cc1101.cpp 14 KB

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