cc1200.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Project: Arrow
  3. * Author: curiousmuch
  4. */
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "freertos/semphr.h"
  10. #include "freertos/portmacro.h"
  11. #include "driver/gpio.h"
  12. #include "sdkconfig.h"
  13. #include "driver/spi_master.h"
  14. #include "esp_err.h"
  15. #include "cc1200.h"
  16. #include "cc1200_protocol.h"
  17. #include "board.h"
  18. #include "esp_task_wdt.h"
  19. #include "freertos/ringbuf.h"
  20. #include "esp_log.h"
  21. #include "driver/timer.h"
  22. /* Debugging Tag for ESP_LOG */
  23. #define CC_TAG "CC1200 Driver"
  24. /* SPI Constants */
  25. #define CC1200_WRITE_BIT 0
  26. #define CC1200_READ_BIT BIT(1)
  27. #define CC1200_BURST_BIT BIT(0)
  28. /* CC1200 SPI Driver Configuration */
  29. spi_bus_config_t bus_config =
  30. {
  31. .miso_io_num = CC1200_MISO,
  32. .mosi_io_num = CC1200_MOSI,
  33. .sclk_io_num = CC1200_SCLK,
  34. .quadwp_io_num = -1,
  35. .quadhd_io_num = -1,
  36. .max_transfer_sz = 150,
  37. .flags = SPICOMMON_BUSFLAG_MASTER,
  38. .intr_flags = ESP_INTR_FLAG_IRAM
  39. };
  40. spi_device_interface_config_t interface_config =
  41. {
  42. .command_bits = 2,
  43. .address_bits = 6,
  44. .dummy_bits = 0,
  45. .mode = 0,
  46. .spics_io_num = CC1200_CS,
  47. .clock_speed_hz = (APB_CLK_FREQ/16),
  48. .flags = 0,
  49. .queue_size = 20
  50. };
  51. spi_device_handle_t spi;
  52. /* Private Functions */
  53. static void cc1200_gpio_init(void)
  54. {
  55. gpio_config_t reset_pin_config =
  56. {
  57. .pin_bit_mask = (uint64_t)(BIT64(CC1200_RESET)),
  58. .mode = GPIO_MODE_OUTPUT,
  59. .pull_up_en = GPIO_PULLUP_DISABLE,
  60. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  61. .intr_type = GPIO_INTR_DISABLE
  62. };
  63. gpio_config_t gpio_pin_config =
  64. {
  65. .pin_bit_mask = (uint64_t) (BIT64(CC1200_GPIO0)|BIT64(CC1200_GPIO2)|BIT64(CC1200_GPIO3)),
  66. .mode = GPIO_MODE_INPUT,
  67. .pull_up_en = GPIO_PULLUP_DISABLE,
  68. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  69. .intr_type = GPIO_INTR_DISABLE
  70. };
  71. gpio_config(&reset_pin_config);
  72. gpio_config(&gpio_pin_config);
  73. gpio_set_level(CC1200_RESET, 1);
  74. }
  75. static void cc1200_spi_init(void)
  76. {
  77. esp_err_t ret;
  78. ret = spi_bus_initialize(VSPI_HOST, &bus_config, 0); // this uses DMA channel 1
  79. ESP_ERROR_CHECK(ret);
  80. ret = spi_bus_add_device(VSPI_HOST, &interface_config, &spi);
  81. ESP_ERROR_CHECK(ret);
  82. }
  83. static void IRAM_ATTR cc1200_spi_write_byte(uint16_t addr, uint8_t data)
  84. {
  85. esp_err_t ret;
  86. spi_transaction_t tx_trans =
  87. {
  88. .flags = SPI_TRANS_USE_TXDATA,
  89. .cmd = CC1200_WRITE_BIT,
  90. .addr = addr,
  91. .length = 8,
  92. .rxlength = 0,
  93. .tx_data[0] = data
  94. };
  95. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  96. {
  97. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  98. spi_transaction_ext_t tx_trans_ext =
  99. {
  100. .base = tx_trans,
  101. .command_bits = 2,
  102. .address_bits = 14
  103. };
  104. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  105. }
  106. else
  107. {
  108. ret = spi_device_polling_transmit(spi, &tx_trans);
  109. }
  110. ESP_ERROR_CHECK(ret);
  111. }
  112. static void IRAM_ATTR cc1200_spi_write_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  113. {
  114. esp_err_t ret;
  115. spi_transaction_t tx_trans =
  116. {
  117. .cmd = (CC1200_WRITE_BIT | CC1200_BURST_BIT),
  118. .addr = addr,
  119. .length = 8*len,
  120. .tx_buffer = data
  121. };
  122. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  123. {
  124. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  125. spi_transaction_ext_t tx_trans_ext =
  126. {
  127. .base = tx_trans,
  128. .command_bits = 2,
  129. .address_bits = 14
  130. };
  131. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  132. }
  133. else
  134. {
  135. ret = spi_device_polling_transmit(spi, &tx_trans);
  136. }
  137. ESP_ERROR_CHECK(ret);
  138. }
  139. static void IRAM_ATTR cc1200_spi_read_byte(uint16_t addr, uint8_t* data)
  140. {
  141. esp_err_t ret;
  142. spi_transaction_t rx_trans =
  143. {
  144. .cmd = CC1200_READ_BIT,
  145. .addr = addr,
  146. .length = 8,
  147. .rxlength = 8,
  148. .rx_buffer = data
  149. };
  150. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  151. {
  152. rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  153. spi_transaction_ext_t rx_trans_ext =
  154. {
  155. .base = rx_trans,
  156. .command_bits = 2,
  157. .address_bits = 14
  158. };
  159. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  160. }
  161. else
  162. {
  163. ret = spi_device_polling_transmit(spi, &rx_trans);
  164. }
  165. ESP_ERROR_CHECK(ret);
  166. }
  167. static void cc1200_spi_read_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  168. {
  169. esp_err_t ret;
  170. spi_transaction_t rx_trans =
  171. {
  172. .cmd = (CC1200_READ_BIT | CC1200_BURST_BIT),
  173. .addr = addr,
  174. .length = 8*len,
  175. .rxlength = 8*len,
  176. .rx_buffer = data
  177. };
  178. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  179. {
  180. rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  181. spi_transaction_ext_t rx_trans_ext =
  182. {
  183. .base = rx_trans,
  184. .command_bits = 2,
  185. .address_bits = 14
  186. };
  187. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  188. }
  189. else
  190. {
  191. ret = spi_device_polling_transmit(spi, &rx_trans);
  192. }
  193. ESP_ERROR_CHECK(ret);
  194. }
  195. rf_status_t IRAM_ATTR cc1200_spi_strobe(uint8_t cmd)
  196. {
  197. esp_err_t ret;
  198. uint8_t temp=0;
  199. spi_transaction_t rx_trans =
  200. {
  201. .flags = (SPI_TRANS_USE_TXDATA | SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR),
  202. .length = 8,
  203. .rxlength = 8,
  204. .rx_buffer = &temp,
  205. .tx_data[0] = cmd
  206. };
  207. spi_transaction_ext_t rx_trans_ext =
  208. {
  209. .base = rx_trans,
  210. .command_bits = 0,
  211. .address_bits = 0
  212. };
  213. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  214. ESP_ERROR_CHECK(ret);
  215. return (temp & 0xF0);
  216. }
  217. // writes array or register value pairs from smart RF studio to CC1200
  218. // w/o reseting
  219. void cc1200_radio_config(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  220. {
  221. uint8_t i;
  222. for (i=0;i<len;i++)
  223. {
  224. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  225. }
  226. }
  227. /* CC1200 Driver Public Functions */
  228. uint8_t IRAM_ATTR cc1200_radio_read_RSSI(void)
  229. {
  230. uint8_t data = 0;
  231. cc1200_spi_read_byte(CC120X_RSSI1, &data);
  232. return data;
  233. }
  234. uint8_t IRAM_ATTR cc1200_radio_read_CFM(void)
  235. {
  236. uint8_t data = 0;
  237. cc1200_spi_read_byte(CC120X_CFM_RX_DATA_OUT, &data);
  238. return data;
  239. }
  240. void IRAM_ATTR cc1200_radio_write_CFM(uint8_t data)
  241. {
  242. cc1200_spi_write_byte(CC120X_CFM_TX_DATA_IN, data);
  243. }
  244. rf_status_t cc1200_radio_reset(void)
  245. {
  246. rf_status_t status;
  247. uint8_t retry_count = 0;
  248. cc1200_spi_strobe(CC120X_SRES); // soft reset the chip
  249. status = cc1200_spi_strobe(CC120X_SNOP); // get chip status
  250. vTaskDelay(20 / portTICK_PERIOD_MS);
  251. while((CC120X_RDYn_BIT & (status & 0x80))) // if chip isn't ready, wait 10ms
  252. {
  253. vTaskDelay(10 / portTICK_PERIOD_MS);
  254. if (retry_count > 3)
  255. {
  256. ESP_LOGE(CC_TAG, "Reset Failure");
  257. // TODO: Reset ESP32
  258. break;
  259. }
  260. status = cc1200_spi_strobe(CC120X_SNOP);
  261. retry_count++;
  262. }
  263. return status;
  264. }
  265. #define CC1200_LO_DIVIDER 24 // 136.7 - 160 MHz Band
  266. #define CC1200_XOSC 40000000 // 40MHz
  267. void cc1200_radio_frequency(uint32_t freq)
  268. {
  269. // f_RF = f_VCO / LO Divider
  270. // f_VCO = FREQ / 2^16 * f_XOSX + FREQOFF / 2^18 * F_XOSC
  271. double temp_freq;
  272. // calculate FREQ0, FREQ, FREQ2 registers
  273. temp_freq = ((double) freq * 65536 * CC1200_LO_DIVIDER) / CC1200_XOSC;
  274. freq = (uint32_t)temp_freq;
  275. cc1200_spi_write_byte(CC120X_FREQ0, ((uint8_t *)&freq)[0]);
  276. cc1200_spi_write_byte(CC120X_FREQ1, ((uint8_t *)&freq)[1]);
  277. cc1200_spi_write_byte(CC120X_FREQ2, ((uint8_t *)&freq)[2]);
  278. return ;
  279. }
  280. void cc1200_radio_sleep(void)
  281. {
  282. // TODO: Write CC1200 sleep function
  283. return;
  284. }
  285. void cc1200_radio_power(uint8_t txPower)
  286. {
  287. // TODO: Write function to set CC1200 power
  288. return;
  289. }
  290. void cc1200_radio_idle(void)
  291. {
  292. // TODO: Create exception for failure condition
  293. while (cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
  294. }
  295. void cc1200_radio_tx(void)
  296. {
  297. // TODO: Create exception for failure condition
  298. while (cc1200_spi_strobe(CC120X_STX) != CC120X_STATE_TX);
  299. }
  300. void cc1200_radio_rx(void)
  301. {
  302. // TODO: Create exception for failure condition
  303. while (cc1200_spi_strobe(CC120X_SRX) != CC120X_STATE_RX);
  304. }
  305. void cc1200_radio_init(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  306. {
  307. cc1200_gpio_init();
  308. cc1200_spi_init();
  309. spi_device_acquire_bus(spi, portMAX_DELAY);
  310. cc1200_radio_reset(); gpio_set_level(CC1200_RESET, 1);
  311. //uint8_t data;
  312. //cc1200_spi_read_byte(CC120X_PARTNUMBER, &data);
  313. //printf("%x", data);
  314. uint8_t i;
  315. for (i=0;i<len;i++)
  316. {
  317. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  318. }
  319. while(cc1200_spi_strobe(CC120X_SIDLE) != CC120X_STATE_IDLE);
  320. }