cc1101.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #include "flipper_v2.h"
  2. #include "cc1101-workaround/cc1101.h"
  3. // ******************************************************************************
  4. #define WRITE_BURST 0x40
  5. #define READ_SINGLE 0x80
  6. #define READ_BURST 0xC0
  7. #define BYTES_IN_FIFO 0x7F //used to detect FIFO underflow or overflow
  8. /*********************ss_pin as global variable****************************** */
  9. /* cc1101 */
  10. /******************************************************************************/
  11. GpioPin ss_pin;
  12. CC1101::CC1101(GpioPin ss_pin) {
  13. /*
  14. pinMode(gdo0_pin, OUTPUT); //GDO0 as asynchronous serial mode input
  15. pinMode(gdo2_pin, INPUT); //GDO2 as asynchronous serial mode output
  16. */
  17. pinMode(ss_pin, OUTPUT);
  18. this->ss_pin = ss_pin;
  19. }
  20. //******************************************************************************
  21. //SpiInit
  22. /******************************************************************************/
  23. void CC1101::SpiInit(void) {
  24. //initialize spi pins
  25. //Enable spi master, MSB, SPI mode 0, FOSC/4
  26. SpiMode(0);
  27. }
  28. void CC1101::SpiEnd(void) {
  29. /*
  30. SPCR = ((0<<SPE) | // SPI Enable
  31. (0<<SPIE)| // SPI Interupt Enable
  32. (0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
  33. (1<<MSTR)| // Master/Slave select
  34. (0<<SPR1)|(0<<SPR0)| // SPI Clock Rate ( 0 0 = osc/4; 0 1 = osc/16; 1 0 = osc/64; 1 1= 0sc/128)
  35. (0<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
  36. (0<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
  37. //SPSR = (0<<SPI2X); // Double Clock Rate
  38. */
  39. }
  40. /******************************************************************************
  41. Function: SpiMode
  42. *INPUT : config mode
  43. (0<<CPOL) | (0 << CPHA) 0
  44. (0<<CPOL) | (1 << CPHA) 1
  45. (1<<CPOL) | (0 << CPHA) 2
  46. (1<<CPOL) | (1 << CPHA) 3
  47. *OUTPUT :none
  48. ******************************************************************************/
  49. void CC1101::SpiMode(byte config) {
  50. /*
  51. byte tmp;
  52. // enable SPI master with configuration byte specified
  53. SPCR = 0;
  54. SPCR = (config & 0x7F) | (1<<SPE) | (1<<MSTR);
  55. tmp = SPSR;
  56. tmp = SPDR;
  57. */
  58. }
  59. /****************************************************************
  60. *FUNCTION NAME:SpiTransfer
  61. *FUNCTION :spi transfer
  62. *INPUT :value: data to send
  63. *OUTPUT :data to receive
  64. ****************************************************************/
  65. extern SPI_HandleTypeDef hspi3;
  66. byte CC1101::SpiTransfer(byte value) {
  67. uint8_t buf[1] = {value};
  68. uint8_t rxbuf[1] = {0};
  69. HAL_SPI_TransmitReceive(&hspi3, buf, rxbuf, 1, HAL_MAX_DELAY);
  70. return rxbuf[0];
  71. }
  72. /****************************************************************
  73. *FUNCTION NAME:SpiWriteReg
  74. *FUNCTION :CC1101 write data to register
  75. *INPUT :addr: register address; value: register value
  76. *OUTPUT :none
  77. ****************************************************************/
  78. void CC1101::SpiWriteReg(byte addr, byte value) {
  79. digitalWrite(ss_pin, LOW);
  80. while(digitalRead(MISO_PIN))
  81. ;
  82. SpiTransfer(addr);
  83. SpiTransfer(value);
  84. digitalWrite(ss_pin, HIGH);
  85. }
  86. /****************************************************************
  87. *FUNCTION NAME:SpiWriteBurstReg
  88. *FUNCTION :CC1101 write burst data to register
  89. *INPUT :addr: register address; buffer:register value array; num:number to write
  90. *OUTPUT :none
  91. ****************************************************************/
  92. void CC1101::SpiWriteBurstReg(byte addr, byte* buffer, byte num) {
  93. byte i, temp;
  94. temp = addr | WRITE_BURST;
  95. digitalWrite(ss_pin, LOW);
  96. while(digitalRead(MISO_PIN))
  97. ;
  98. SpiTransfer(temp);
  99. for(i = 0; i < num; i++) {
  100. SpiTransfer(buffer[i]);
  101. }
  102. digitalWrite(ss_pin, HIGH);
  103. }
  104. /****************************************************************
  105. *FUNCTION NAME:SpiStrobe
  106. *FUNCTION :CC1101 Strobe
  107. *INPUT :strobe: command; //refer define in CC1101.h//
  108. *OUTPUT :none
  109. ****************************************************************/
  110. void CC1101::SpiStrobe(byte strobe) {
  111. digitalWrite(ss_pin, LOW);
  112. while(digitalRead(MISO_PIN))
  113. ;
  114. SpiTransfer(strobe);
  115. digitalWrite(ss_pin, HIGH);
  116. }
  117. /****************************************************************
  118. *FUNCTION NAME:SpiReadReg
  119. *FUNCTION :CC1101 read data from register
  120. *INPUT :addr: register address
  121. *OUTPUT :register value
  122. ****************************************************************/
  123. byte CC1101::SpiReadReg(byte addr) {
  124. byte temp, value;
  125. temp = addr | READ_SINGLE;
  126. digitalWrite(ss_pin, LOW);
  127. while(digitalRead(MISO_PIN))
  128. ;
  129. SpiTransfer(temp);
  130. value = SpiTransfer(0);
  131. digitalWrite(ss_pin, HIGH);
  132. return value;
  133. }
  134. /****************************************************************
  135. *FUNCTION NAME:SpiReadBurstReg
  136. *FUNCTION :CC1101 read burst data from register
  137. *INPUT :addr: register address; buffer:array to store register value; num: number to read
  138. *OUTPUT :none
  139. ****************************************************************/
  140. void CC1101::SpiReadBurstReg(byte addr, byte* buffer, byte num) {
  141. byte i, temp;
  142. temp = addr | READ_BURST;
  143. digitalWrite(ss_pin, LOW);
  144. while(digitalRead(MISO_PIN))
  145. ;
  146. SpiTransfer(temp);
  147. for(i = 0; i < num; i++) {
  148. buffer[i] = SpiTransfer(0);
  149. }
  150. digitalWrite(ss_pin, HIGH);
  151. }
  152. /****************************************************************
  153. *FUNCTION NAME:SpiReadStatus
  154. *FUNCTION :CC1101 read status register
  155. *INPUT :addr: register address
  156. *OUTPUT :status value
  157. ****************************************************************/
  158. byte CC1101::SpiReadStatus(byte addr) {
  159. byte value, temp;
  160. temp = addr | READ_BURST;
  161. digitalWrite(ss_pin, LOW);
  162. while(digitalRead(MISO_PIN))
  163. ;
  164. SpiTransfer(temp);
  165. value = SpiTransfer(0);
  166. digitalWrite(ss_pin, HIGH);
  167. return value;
  168. }
  169. /****************************************************************
  170. *FUNCTION NAME:Reset
  171. *FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100//
  172. *INPUT :none
  173. *OUTPUT :none
  174. ****************************************************************/
  175. void CC1101::Reset(void) {
  176. digitalWrite(ss_pin, LOW);
  177. delay(1);
  178. digitalWrite(ss_pin, HIGH);
  179. delay(1);
  180. digitalWrite(ss_pin, LOW);
  181. while(digitalRead(MISO_PIN))
  182. ;
  183. SpiTransfer(CC1101_SRES);
  184. while(digitalRead(MISO_PIN))
  185. ;
  186. digitalWrite(ss_pin, HIGH);
  187. }
  188. /****************************************************************
  189. *FUNCTION NAME:Init
  190. *FUNCTION :CC1101 initialization
  191. *INPUT :none
  192. *OUTPUT :none
  193. ****************************************************************/
  194. byte CC1101::Init(void) {
  195. #ifdef CC1101_DEBUG
  196. printf("Init SPI...\n");
  197. #endif
  198. SpiInit(); //spi initialization
  199. digitalWrite(ss_pin, HIGH);
  200. // digitalWrite(SCK_PIN, HIGH);
  201. // digitalWrite(MOSI_PIN, LOW);
  202. #ifdef CC1101_DEBUG
  203. printf("Reset CC1101...\n");
  204. #endif
  205. Reset(); //CC1101 reset
  206. byte partnum, version;
  207. partnum = SpiReadStatus(CC1101_PARTNUM);
  208. version = SpiReadStatus(CC1101_VERSION);
  209. #ifdef CC1101_DEBUG
  210. printf("Partnum:0x%02X, Version:0x%02X\n", partnum, version);
  211. #endif
  212. #ifdef CC1101_DEBUG
  213. printf("Init CC1101...");
  214. #endif
  215. RegConfigSettings(); //CC1101 register config
  216. #ifdef CC1101_DEBUG
  217. printf("Done!\n");
  218. #endif
  219. return version;
  220. }
  221. /****************************************************************
  222. *FUNCTION NAME:SetMod
  223. *FUNCTION :CC1101 modulation type
  224. *INPUT :byte mode
  225. *OUTPUT :none
  226. ****************************************************************/
  227. void CC1101::SetMod(byte mode) {
  228. SpiWriteReg(CC1101_MDMCFG2, mode); //no sync/preamble; ASK/OOK only support up to -1dbm
  229. if((mode | 0x30) == ASK) {
  230. SpiWriteReg(CC1101_FREND0, 0x11); //use first up to PATABLE(0)
  231. byte PaTabel[8] = {0x00, POWER, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  232. SpiWriteBurstReg(CC1101_PATABLE, PaTabel, 8); //CC1101 PATABLE config
  233. } else {
  234. SpiWriteReg(CC1101_FREND0, 0x10); //use first up to PATABLE(0)
  235. byte PaTabel[8] = {POWER, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  236. SpiWriteBurstReg(CC1101_PATABLE, PaTabel, 8); //CC1101 PATABLE config
  237. }
  238. #ifdef CC1101_DEBUG
  239. switch(mode | 0x30) {
  240. case GFSK: {
  241. printf("CC1101 Modulation: GFSK");
  242. break;
  243. }
  244. case MSK: {
  245. printf("CC1101 Modulation: MSK");
  246. break;
  247. }
  248. case ASK: {
  249. printf("CC1101 Modulation: ASK/OOK");
  250. break;
  251. }
  252. case FSK2: {
  253. printf("CC1101 Modulation: 2-FSK");
  254. break;
  255. }
  256. case FSK4: {
  257. printf("CC1101 Modulation: 4-FSK");
  258. break;
  259. }
  260. default: //default to GFSK
  261. {
  262. printf("Modulation mode not supported");
  263. break;
  264. }
  265. }
  266. printf("\n");
  267. #endif
  268. }
  269. /****************************************************************
  270. *FUNCTION NAME:RegConfigSettings
  271. *FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100//
  272. *INPUT :none
  273. *OUTPUT :none
  274. ****************************************************************/
  275. void CC1101::RegConfigSettings(void) {
  276. SpiWriteReg(CC1101_FSCTRL1, 0x06); //IF frequency
  277. SpiWriteReg(CC1101_FSCTRL0, 0x00); //frequency offset before synthesizer
  278. SpiWriteReg(CC1101_MDMCFG4, 0xCC); // RX filter bandwidth 100k(0xcc)
  279. SpiWriteReg(
  280. CC1101_MDMCFG3, 0x43); //datarate config 512kBaud for the purpose of fast rssi measurement
  281. SpiWriteReg(CC1101_MDMCFG1, 0x21); //FEC preamble etc. last 2 bits for channel spacing
  282. SpiWriteReg(CC1101_MDMCFG0, 0xF8); //100khz channel spacing
  283. //CC1101_CHANNR moved to SetChannel func
  284. //SpiWriteReg(CC1101_DEVIATN, 0x47);
  285. SpiWriteReg(
  286. CC1101_MCSM0, 0x18); // calibrate when going from IDLE to RX or TX ; 149 - 155 μs timeout
  287. SpiWriteReg(CC1101_FOCCFG, 0x16); //frequency compensation
  288. //SpiWriteReg(CC1101_BSCFG, 0x1C); //bit synchronization config
  289. SpiWriteReg(CC1101_AGCCTRL2, 0x43);
  290. SpiWriteReg(CC1101_AGCCTRL1, 0x49);
  291. SpiWriteReg(CC1101_AGCCTRL0, 0x91);
  292. //freq synthesizer calibration
  293. SpiWriteReg(CC1101_FSCAL3, 0xEA);
  294. SpiWriteReg(CC1101_FSCAL2, 0x2A);
  295. SpiWriteReg(CC1101_FSCAL1, 0x00);
  296. SpiWriteReg(CC1101_FSCAL0, 0x1F);
  297. SpiWriteReg(CC1101_TEST2, 0x81);
  298. SpiWriteReg(CC1101_TEST1, 0x35);
  299. SpiWriteReg(CC1101_TEST0, 0x0B); //should be 0x0B for lower than 430.6MHz and 0x09 for higher
  300. //SpiWriteReg(CC1101_FREND1, 0x56);
  301. //SpiWriteReg(CC1101_IOCFG2, 0x0B); //serial clock.synchronous to the data in synchronous serial mode
  302. //SpiWriteReg(CC1101_IOCFG0, 0x06); //asserts when sync word has been sent/received, and de-asserts at the end of the packet
  303. SpiWriteReg(CC1101_IOCFG2, 0x0D); //data output pin for asynchronous mode
  304. SpiWriteReg(
  305. CC1101_IOCFG0,
  306. 0x2E); //High impedance (3-state), GDO0 configed as data input for asynchronous mode
  307. //SpiWriteReg(CC1101_PKTCTRL0, 0x05); //whitening off;CRC Enable;variable length packets, packet length configured by the first byte after sync word
  308. SpiWriteReg(
  309. CC1101_PKTCTRL0, 0x33); //whitening off; asynchronous serial mode; CRC diable;reserved
  310. //SpiWriteReg(CC1101_PKTLEN, 0x3D); //61 bytes max length
  311. SpiWriteReg(
  312. CC1101_FIFOTHR,
  313. 0x47); //Adc_retention enabled for RX filter bandwidth less than 325KHz; defalut fifo threthold.
  314. }
  315. /****************************************************************
  316. *FUNCTION NAME:SetFreq
  317. *FUNCTION :SetFreq
  318. *INPUT :Freq2, Freq1, Freq0
  319. *OUTPUT :none
  320. ****************************************************************/
  321. void CC1101::SetFreq(byte freq2, byte freq1, byte freq0) {
  322. SpiWriteReg(CC1101_FREQ2, freq2);
  323. SpiWriteReg(CC1101_FREQ1, freq1);
  324. SpiWriteReg(CC1101_FREQ0, freq0);
  325. }
  326. /****************************************************************
  327. *FUNCTION NAME:SetChannel
  328. *FUNCTION :SetChannel
  329. *INPUT :int channel
  330. *OUTPUT :none
  331. ****************************************************************/
  332. void CC1101::SetChannel(int channel) {
  333. #ifdef CC1101_DEBUG
  334. printf("Set CC1101 channel to: %d \n", channel);
  335. #endif
  336. SpiWriteReg(CC1101_CHANNR, (byte)channel); //related to channel numbers
  337. }
  338. /****************************************************************
  339. *FUNCTION NAME:SetReceive
  340. *FUNCTION :SetReceive
  341. *INPUT :none
  342. *OUTPUT :none
  343. ****************************************************************/
  344. void CC1101::SetReceive(void) {
  345. SpiStrobe(CC1101_SRX);
  346. while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_RX) {
  347. // delay(1);
  348. // printf("wait status\n");
  349. }
  350. }
  351. /****************************************************************
  352. *FUNCTION NAME:SetTransmit
  353. *FUNCTION :
  354. *INPUT :none
  355. *OUTPUT :none
  356. ****************************************************************/
  357. void CC1101::SetTransmit(void) {
  358. SpiStrobe(CC1101_STX);
  359. while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_TX)
  360. ;
  361. }
  362. //cc1101 cc1101;