c1120.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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 "driver/gpio.h"
  10. #include "sdkconfig.h"
  11. #include "driver/spi_master.h"
  12. #include "esp_err.h"
  13. #include "cc1120.h"
  14. #include "cc1120_protocol.h"
  15. #include "board.h"
  16. #define CC1120_WRITE_BIT 0
  17. #define CC1120_READ_BIT BIT(1)
  18. #define CC1120_BURST_BIT BIT(0)
  19. // Public Configurations for CC1120 SPI Driver
  20. spi_bus_config_t bus_config =
  21. {
  22. .miso_io_num = CC1120_MISO,
  23. .mosi_io_num = CC1120_MOSI,
  24. .sclk_io_num = CC1120_SCLK,
  25. .quadwp_io_num = -1,
  26. .quadhd_io_num = -1,
  27. .max_transfer_sz = 150,
  28. .flags = ESP_INTR_FLAG_IRAM
  29. };
  30. spi_device_interface_config_t interface_config =
  31. {
  32. .command_bits = 2,
  33. .address_bits = 6,
  34. .dummy_bits = 0,
  35. .mode = 0,
  36. .spics_io_num = CC1120_CS,
  37. .clock_speed_hz = (APB_CLK_FREQ/20),
  38. .flags = 0,
  39. .queue_size = 20
  40. };
  41. spi_device_handle_t spi;
  42. // Private CC1120 Driver Functions
  43. void cc1120_gpio_init(void)
  44. {
  45. gpio_config_t reset_pin_config =
  46. {
  47. .pin_bit_mask = (uint64_t)BIT64(CC1120_RESET),
  48. .mode = GPIO_MODE_OUTPUT,
  49. .pull_up_en = GPIO_PULLUP_DISABLE,
  50. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  51. .intr_type = GPIO_INTR_DISABLE
  52. };
  53. gpio_config_t gpio_pin_config =
  54. {
  55. .pin_bit_mask = (uint64_t) (BIT64(CC1120_GPIO0)|BIT64(CC1120_GPIO2)|BIT64(CC1120_GPIO3)),
  56. .mode = GPIO_MODE_INPUT,
  57. .pull_up_en = GPIO_PULLUP_DISABLE,
  58. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  59. .intr_type = GPIO_INTR_DISABLE
  60. };
  61. gpio_config(&reset_pin_config);
  62. gpio_config(&gpio_pin_config);
  63. gpio_set_level(CC1120_RESET, 1);
  64. }
  65. void cc1120_spi_init(void)
  66. {
  67. esp_err_t ret;
  68. ret = spi_bus_initialize(VSPI_HOST, &bus_config, 0); // this uses DMA channel 1
  69. ESP_ERROR_CHECK(ret);
  70. ret = spi_bus_add_device(VSPI_HOST, &interface_config, &spi);
  71. ESP_ERROR_CHECK(ret);
  72. }
  73. void IRAM_ATTR cc1120_spi_write_byte(uint16_t addr, uint8_t data)
  74. {
  75. esp_err_t ret;
  76. spi_transaction_t tx_trans =
  77. {
  78. .flags = SPI_TRANS_USE_TXDATA,
  79. .cmd = CC1120_WRITE_BIT,
  80. .addr = addr,
  81. .length = 8,
  82. .rxlength = 0,
  83. .tx_data[0] = data
  84. };
  85. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  86. {
  87. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  88. spi_transaction_ext_t tx_trans_ext =
  89. {
  90. .base = tx_trans,
  91. .command_bits = 2,
  92. .address_bits = 14
  93. };
  94. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  95. }
  96. else
  97. {
  98. ret = spi_device_polling_transmit(spi, &tx_trans);
  99. }
  100. ESP_ERROR_CHECK(ret);
  101. }
  102. void IRAM_ATTR cc1120_spi_write_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  103. {
  104. esp_err_t ret;
  105. spi_transaction_t tx_trans =
  106. {
  107. .cmd = (CC1120_WRITE_BIT | CC1120_BURST_BIT),
  108. .addr = addr,
  109. .length = 8*len,
  110. .tx_buffer = data
  111. };
  112. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  113. {
  114. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  115. spi_transaction_ext_t tx_trans_ext =
  116. {
  117. .base = tx_trans,
  118. .command_bits = 2,
  119. .address_bits = 14
  120. };
  121. ret = spi_device_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  122. }
  123. else
  124. {
  125. ret = spi_device_transmit(spi, &tx_trans);
  126. }
  127. ESP_ERROR_CHECK(ret);
  128. }
  129. void cc1120_spi_read_byte(uint16_t addr, uint8_t* data)
  130. {
  131. esp_err_t ret;
  132. spi_transaction_t rx_trans =
  133. {
  134. .cmd = CC1120_READ_BIT,
  135. .addr = addr,
  136. .length = 8,
  137. .rxlength = 8,
  138. .rx_buffer = data
  139. };
  140. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  141. {
  142. rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  143. spi_transaction_ext_t rx_trans_ext =
  144. {
  145. .base = rx_trans,
  146. .command_bits = 2,
  147. .address_bits = 14
  148. };
  149. ret = spi_device_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  150. }
  151. else
  152. {
  153. ret = spi_device_transmit(spi, &rx_trans);
  154. }
  155. ESP_ERROR_CHECK(ret);
  156. }
  157. void cc1120_spi_read_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  158. {
  159. esp_err_t ret;
  160. spi_transaction_t rx_trans =
  161. {
  162. .cmd = (CC1120_READ_BIT | CC1120_BURST_BIT),
  163. .addr = addr,
  164. .length = 8*len,
  165. .rxlength = 8*len,
  166. .rx_buffer = data
  167. };
  168. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  169. {
  170. rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  171. spi_transaction_ext_t rx_trans_ext =
  172. {
  173. .base = rx_trans,
  174. .command_bits = 2,
  175. .address_bits = 14
  176. };
  177. ret = spi_device_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  178. }
  179. else
  180. {
  181. ret = spi_device_transmit(spi, &rx_trans);
  182. }
  183. ESP_ERROR_CHECK(ret);
  184. }
  185. rf_status_t IRAM_ATTR cc1120_spi_strobe(uint8_t cmd)
  186. {
  187. esp_err_t ret;
  188. uint8_t temp=0;
  189. spi_transaction_t rx_trans =
  190. {
  191. .flags = (SPI_TRANS_USE_TXDATA | SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR),
  192. .length = 8,
  193. .rxlength = 8,
  194. .rx_buffer = &temp,
  195. .tx_data[0] = cmd
  196. };
  197. spi_transaction_ext_t rx_trans_ext =
  198. {
  199. .base = rx_trans,
  200. .command_bits = 0,
  201. .address_bits = 0
  202. };
  203. ret = spi_device_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  204. ESP_ERROR_CHECK(ret);
  205. return (temp & 0xF0);
  206. }
  207. // Public CC1120 Driver Functions
  208. // These function should have there own error codes as they're dependent upon the radio and
  209. // not the ESP32 :)
  210. rf_status_t cc1120_radio_reset(void)
  211. {
  212. rf_status_t status;
  213. uint8_t retry_count = 0;
  214. cc1120_spi_strobe(CC112X_SRES);
  215. status = cc1120_spi_strobe(CC112X_SNOP);
  216. vTaskDelay(10 / portTICK_PERIOD_MS);
  217. while((CC112X_RDYn_BIT & (status & 0x80)))
  218. {
  219. vTaskDelay(10 / portTICK_PERIOD_MS);
  220. if (retry_count > 3)
  221. {
  222. // place error CC1120 timeout
  223. printf("CC1120 Reset Failure\n");
  224. break;
  225. }
  226. status = cc1120_spi_strobe(CC112X_SNOP);
  227. retry_count++;
  228. }
  229. printf("%x\n", retry_count);
  230. return status;
  231. }
  232. esp_err_t cc1120_radio_frequency(uint32_t freq)
  233. {
  234. return ESP_OK;
  235. }
  236. esp_err_t cc1120_radio_sleep(void)
  237. {
  238. return ESP_OK;
  239. }
  240. esp_err_t cc1120_radio_power(uint8_t txPower)
  241. {
  242. return ESP_OK;
  243. }
  244. #define HDLC_FLAG 0x7E
  245. #define HDLC_FLAG_LEN 10
  246. uint8_t packet_len = 0;
  247. uint8_t test_vector[] = {0x71, 0x01, 023, 0xAE, 0x75};
  248. uint8_t sample_count = 0;
  249. uint32_t tx_symbol = 0;
  250. uint8_t prev_tx_symbol = 0;
  251. #define SAMPLE_FREQUENCY 13200
  252. #define DAC_MAX 64
  253. #define LUT_SIZE DAC_MAX*2
  254. DRAM_ATTR int8_t LUT[LUT_SIZE];
  255. int8_t phase_i = 0;
  256. float phase, delta_phi;
  257. float const delta_phi_1 = (float) 1200 / SAMPLE_FREQUENCY * LUT_SIZE;
  258. float const delta_phi_2 = (float) 2200 / SAMPLE_FREQUENCY * LUT_SIZE;
  259. // The output needs to be continous phase.
  260. static void IRAM_ATTR cc1120_aprs_tx_isr(void* arg)
  261. {
  262. if (tx_symbol)
  263. delta_phi = delta_phi_1;
  264. else
  265. delta_phi = delta_phi_2;
  266. phase_i = (int8_t)phase; // get integer part of our phase
  267. cc1120_spi_write_byte(CC112X_CFM_TX_DATA_IN, LUT[phase_i]);
  268. phase += delta_phi; // increment phase
  269. if (phase >= (float)LUT_SIZE) // handle wraparound
  270. phase -= (float)LUT_SIZE;
  271. sample_count++;
  272. }
  273. void cc1120_lut_init(void)
  274. {
  275. int16_t i=0;
  276. for (i=0; i<LUT_SIZE; i++)
  277. {
  278. LUT[i] = (int8_t)roundf(DAC_MAX * sinf(2.0f * M_PI * (float)i / LUT_SIZE));
  279. }
  280. }
  281. // test function to generate APRS s1 or s2
  282. void cc1120_radio_APRSTXPacket(void)
  283. {
  284. // start CW transmission
  285. cc1120_spi_write_byte(CC112X_FIFO, 0x12);
  286. cc1120_spi_strobe(CC112X_STX);
  287. // enable interrupt pin for CC1120 for timing packets
  288. gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
  289. gpio_isr_handler_add(CC1120_GPIO3, cc1120_aprs_tx_isr, NULL);
  290. gpio_set_intr_type(CC1120_GPIO3, GPIO_INTR_POSEDGE);
  291. // acquire SPI bus for fastest possible SPI transactions
  292. spi_device_acquire_bus(spi, portMAX_DELAY);
  293. // send Flag
  294. // send Loaded Packet
  295. // send Flag
  296. }
  297. void cc1120_radio_init(const cc1120_reg_settings_t* rf_settings, uint8_t len)
  298. {
  299. cc1120_gpio_init();
  300. cc1120_spi_init();
  301. cc1120_lut_init();
  302. cc1120_radio_reset();
  303. uint8_t i;
  304. for (i=0;i<len;i++)
  305. {
  306. cc1120_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  307. }
  308. }