cc1101.cpp 13 KB

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