cc1200.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * cc1200.c
  3. *
  4. * Created on: Feb 5, 2022
  5. * Author: curiousmuch
  6. */
  7. /*
  8. * Project: Arrow
  9. * Author: curiousmuch
  10. */
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "main.h"
  14. #include "cc1200.h"
  15. #include "cc1200_protocol.h"
  16. #define BIT(n) (0x1U << (n))
  17. /* SPI Constants */
  18. #define CC1200_WRITE_BIT 0b00000000
  19. #define CC1200_READ_BIT 0b10000000
  20. #define CC1200_BURST_BIT 0b01000000
  21. void SPI1_TransmitBytes(uint8_t *p_buf, uint8_t len)
  22. {
  23. LL_SPI_SetTransferSize(SPI1, len);
  24. LL_SPI_Enable(SPI1);
  25. LL_SPI_StartMasterTransfer(SPI1);
  26. switch(len)
  27. {
  28. case 1:
  29. LL_SPI_TransmitData8(SPI1, *p_buf);
  30. break;
  31. case 2:
  32. LL_SPI_TransmitData16(SPI1, *(uint16_t *)p_buf);
  33. break;
  34. case 3:
  35. LL_SPI_TransmitData32(SPI1, *(uint32_t *)p_buf);
  36. break;
  37. default:
  38. assert(0);
  39. }
  40. // Wait until the transmission is complete
  41. while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
  42. SPI1->IFCR = UINT32_MAX;
  43. LL_SPI_Disable(SPI1);
  44. }
  45. uint8_t SPI1_ReceiveByte(void)
  46. {
  47. uint8_t rxByte;
  48. LL_SPI_SetTransferSize(SPI1, 1);
  49. LL_SPI_Enable(SPI1);
  50. LL_SPI_StartMasterTransfer(SPI1);
  51. LL_SPI_TransmitData8(SPI1, 0);
  52. while (LL_SPI_IsActiveFlag_RXP(SPI1) == 0);
  53. rxByte = LL_SPI_ReceiveData8(SPI1);
  54. // Wait until the transmission is complete
  55. while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
  56. SPI1->IFCR = UINT32_MAX;
  57. LL_SPI_Disable(SPI1);
  58. return rxByte;
  59. }
  60. uint8_t SPI1_TransmitReceive(uint8_t *p_buf, uint8_t len)
  61. {
  62. SPI1_TransmitBytes(p_buf, len);
  63. return SPI1_ReceiveByte();
  64. }
  65. // TODO: Fix to use HAL.
  66. static void cc1200_spi_write_byte(uint16_t addr, uint8_t data)
  67. {
  68. uint8_t txBuf[3];
  69. // set the data field
  70. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
  71. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  72. {
  73. txBuf[0] = ((uint8_t *)&addr)[1];
  74. txBuf[1] = ((uint8_t *)&addr)[0];
  75. txBuf[0] |= CC1200_WRITE_BIT;
  76. txBuf[2] = data;
  77. SPI1_TransmitBytes(txBuf, 3);
  78. }
  79. else
  80. {
  81. // correctly configure the addr field.
  82. txBuf[0] = (uint8_t)addr | CC1200_WRITE_BIT;
  83. txBuf[1] = data;
  84. SPI1_TransmitBytes(txBuf, 2);
  85. }
  86. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
  87. }
  88. //static void cc1200_spi_write_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  89. //{
  90. // esp_err_t ret;
  91. // spi_transaction_t tx_trans =
  92. // {
  93. // .cmd = (CC1200_WRITE_BIT | CC1200_BURST_BIT),
  94. // .addr = addr,
  95. // .length = 8*len,
  96. // .tx_buffer = data
  97. // };
  98. // if ((addr & 0xFF00) != 0) // send data with extended address in command field
  99. // {
  100. // tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  101. // spi_transaction_ext_t tx_trans_ext =
  102. // {
  103. // .base = tx_trans,
  104. // .command_bits = 2,
  105. // .address_bits = 14
  106. // };
  107. // ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  108. // }
  109. // else
  110. // {
  111. // ret = spi_device_polling_transmit(spi, &tx_trans);
  112. // }
  113. // ESP_ERROR_CHECK(ret);
  114. //}
  115. // TODO: Fix to use HAL.
  116. static void cc1200_spi_read_byte(uint16_t addr, uint8_t* data)
  117. {
  118. uint8_t rxBuf[3];
  119. uint8_t txBuf[3];
  120. // correctly configure the addr field.
  121. txBuf[0] = (uint8_t)addr | CC1200_READ_BIT;
  122. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
  123. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  124. {
  125. txBuf[0] = ((uint8_t *)&addr)[1];
  126. txBuf[1] = ((uint8_t *)&addr)[0];
  127. txBuf[0] |= CC1200_READ_BIT;
  128. *data = SPI1_TransmitReceive(txBuf, 2);
  129. }
  130. else
  131. {
  132. *data = SPI1_TransmitReceive(txBuf, 1);
  133. }
  134. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
  135. }
  136. //static void cc1200_spi_read_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  137. //{
  138. // esp_err_t ret;
  139. // spi_transaction_t rx_trans =
  140. // {
  141. // .cmd = (CC1200_READ_BIT | CC1200_BURST_BIT),
  142. // .addr = addr,
  143. // .length = 8*len,
  144. // .rxlength = 8*len,
  145. // .rx_buffer = data
  146. // };
  147. // if ((addr & 0xFF00) != 0) // read data with extended address in command field
  148. // {
  149. // rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  150. // spi_transaction_ext_t rx_trans_ext =
  151. // {
  152. // .base = rx_trans,
  153. // .command_bits = 2,
  154. // .address_bits = 14
  155. // };
  156. // ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  157. // }
  158. // else
  159. // {
  160. // ret = spi_device_polling_transmit(spi, &rx_trans);
  161. // }
  162. // ESP_ERROR_CHECK(ret);
  163. //}
  164. // TODO: Fix to use HAL.
  165. rf_status_t cc1200_spi_strobe(uint8_t cmd)
  166. {
  167. uint8_t txBuf[2];
  168. txBuf[0] = cmd;
  169. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 0);
  170. uint8_t rxByte;
  171. LL_SPI_SetTransferSize(SPI1, 1);
  172. LL_SPI_Enable(SPI1);
  173. LL_SPI_StartMasterTransfer(SPI1);
  174. LL_SPI_TransmitData8(SPI1, cmd);
  175. while (LL_SPI_IsActiveFlag_RXP(SPI1) == 0);
  176. rxByte = LL_SPI_ReceiveData8(SPI1);
  177. // Wait until the transmission is complete
  178. while( LL_SPI_IsActiveFlag_EOT(SPI1) == 0);
  179. SPI1->IFCR = UINT32_MAX;
  180. LL_SPI_Disable(SPI1);
  181. HAL_GPIO_WritePin(CC1200_CS_GPIO_Port, CC1200_CS_Pin, 1);
  182. return rxByte & 0xF0;
  183. }
  184. // writes array or register value pairs from smart RF studio to CC1200
  185. // w/o reseting
  186. void cc1200_radio_config(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  187. {
  188. uint8_t i;
  189. for (i=0;i<len;i++)
  190. {
  191. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  192. }
  193. }
  194. /* CC1200 Driver Public Functions */
  195. uint8_t cc1200_radio_read_RSSI(void)
  196. {
  197. uint8_t data = 0;
  198. cc1200_spi_read_byte(CC120X_RSSI1, &data);
  199. return data;
  200. }
  201. uint8_t cc1200_radio_read_CFM(void)
  202. {
  203. uint8_t data = 0;
  204. cc1200_spi_read_byte(CC120X_CFM_RX_DATA_OUT, &data);
  205. return data;
  206. }
  207. void cc1200_radio_write_CFM(int8_t data)
  208. {
  209. cc1200_spi_write_byte(CC120X_CFM_TX_DATA_IN, data);
  210. }
  211. rf_status_t cc1200_radio_reset(void)
  212. {
  213. rf_status_t status;
  214. uint8_t retry_count = 0;
  215. cc1200_spi_strobe(CC120X_SRES); // soft reset the chip
  216. status = cc1200_spi_strobe(CC120X_SNOP); // get chip status
  217. HAL_Delay(20);
  218. while((CC120X_RDYn_BIT & (status & 0x80))) // if chip isn't ready, wait 10ms
  219. {
  220. HAL_Delay(10);
  221. if (retry_count > 3)
  222. {
  223. break;
  224. }
  225. status = cc1200_spi_strobe(CC120X_SNOP);
  226. retry_count++;
  227. }
  228. return status;
  229. }
  230. #define CC1200_LO_DIVIDER 24 // 136.7 - 160 MHz Band
  231. #define CC1200_XOSC 40000000 // 40MHz
  232. void cc1200_radio_frequency(uint32_t freq)
  233. {
  234. // f_RF = f_VCO / LO Divider
  235. // f_VCO = FREQ / 2^16 * f_XOSX + FREQOFF / 2^18 * F_XOSC
  236. double temp_freq;
  237. // calculate FREQ0, FREQ, FREQ2 registers
  238. temp_freq = ((double) freq * 65536 * CC1200_LO_DIVIDER) / CC1200_XOSC;
  239. freq = (uint32_t)temp_freq;
  240. cc1200_spi_write_byte(CC120X_FREQ0, ((uint8_t *)&freq)[0]);
  241. cc1200_spi_write_byte(CC120X_FREQ1, ((uint8_t *)&freq)[1]);
  242. cc1200_spi_write_byte(CC120X_FREQ2, ((uint8_t *)&freq)[2]);
  243. return ;
  244. }
  245. void cc1200_radio_sleep(void)
  246. {
  247. // TODO: Write CC1200 sleep function
  248. return;
  249. }
  250. void cc1200_radio_power(uint8_t txPower)
  251. {
  252. // TODO: Write function to set CC1200 power
  253. return;
  254. }
  255. void cc1200_radio_idle(void)
  256. {
  257. // TODO: Create exception for failure condition
  258. while (cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
  259. }
  260. void cc1200_radio_tx(void)
  261. {
  262. // TODO: Create exception for failure condition
  263. while (cc1200_spi_strobe(CC120X_STX) != CC120X_STATE_TX);
  264. }
  265. void cc1200_radio_rx(void)
  266. {
  267. // TODO: Create exception for failure condition
  268. while (cc1200_spi_strobe(CC120X_SRX) != CC120X_STATE_RX);
  269. }
  270. // TODO: Fix to use HAL.
  271. void cc1200_radio_init(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  272. {
  273. //cc1200_gpio_init();
  274. //cc1200_spi_init();
  275. cc1200_radio_reset(); //gpio_set_level(CC1200_RESET, 1);
  276. uint8_t i;
  277. for (i=0;i<len;i++)
  278. {
  279. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  280. }
  281. while(cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
  282. }