cc1200.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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. #define CC_TAG "CC1200_Driver"
  22. #define CC1200_WRITE_BIT 0
  23. #define CC1200_READ_BIT BIT(1)
  24. #define CC1200_BURST_BIT BIT(0)
  25. // Public Configurations for CC1120 SPI Driver
  26. spi_bus_config_t bus_config =
  27. {
  28. .miso_io_num = CC1120_MISO,
  29. .mosi_io_num = CC1120_MOSI,
  30. .sclk_io_num = CC1120_SCLK,
  31. .quadwp_io_num = -1,
  32. .quadhd_io_num = -1,
  33. .max_transfer_sz = 150,
  34. .flags = SPICOMMON_BUSFLAG_MASTER,
  35. .intr_flags = ESP_INTR_FLAG_IRAM
  36. };
  37. spi_device_interface_config_t interface_config =
  38. {
  39. .command_bits = 2,
  40. .address_bits = 6,
  41. .dummy_bits = 0,
  42. .mode = 0,
  43. .spics_io_num = CC1120_CS,
  44. .clock_speed_hz = (APB_CLK_FREQ/8),
  45. .flags = 0,
  46. .queue_size = 20
  47. };
  48. spi_device_handle_t spi;
  49. // Private CC1120 Driver Functions
  50. void cc1200_gpio_init(void)
  51. {
  52. gpio_config_t reset_pin_config =
  53. {
  54. .pin_bit_mask = (uint64_t)(BIT64(CC1120_RESET)),
  55. .mode = GPIO_MODE_OUTPUT,
  56. .pull_up_en = GPIO_PULLUP_DISABLE,
  57. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  58. .intr_type = GPIO_INTR_DISABLE
  59. };
  60. gpio_config_t gpio_pin_config =
  61. {
  62. .pin_bit_mask = (uint64_t) (BIT64(CC1120_GPIO0)|BIT64(CC1120_GPIO2)|BIT64(CC1120_GPIO3)),
  63. .mode = GPIO_MODE_INPUT,
  64. .pull_up_en = GPIO_PULLUP_DISABLE,
  65. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  66. .intr_type = GPIO_INTR_DISABLE
  67. };
  68. gpio_config(&reset_pin_config);
  69. gpio_config(&gpio_pin_config);
  70. gpio_set_level(CC1120_RESET, 1);
  71. }
  72. void cc1200_spi_init(void)
  73. {
  74. esp_err_t ret;
  75. ret = spi_bus_initialize(VSPI_HOST, &bus_config, 0); // this uses DMA channel 1
  76. ESP_ERROR_CHECK(ret);
  77. ret = spi_bus_add_device(VSPI_HOST, &interface_config, &spi);
  78. ESP_ERROR_CHECK(ret);
  79. }
  80. void IRAM_ATTR cc1200_spi_write_byte(uint16_t addr, uint8_t data)
  81. {
  82. esp_err_t ret;
  83. spi_transaction_t tx_trans =
  84. {
  85. .flags = SPI_TRANS_USE_TXDATA,
  86. .cmd = CC1200_WRITE_BIT,
  87. .addr = addr,
  88. .length = 8,
  89. .rxlength = 0,
  90. .tx_data[0] = data
  91. };
  92. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  93. {
  94. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  95. spi_transaction_ext_t tx_trans_ext =
  96. {
  97. .base = tx_trans,
  98. .command_bits = 2,
  99. .address_bits = 14
  100. };
  101. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  102. }
  103. else
  104. {
  105. ret = spi_device_polling_transmit(spi, &tx_trans);
  106. }
  107. ESP_ERROR_CHECK(ret);
  108. }
  109. void IRAM_ATTR cc1200_spi_write_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  110. {
  111. esp_err_t ret;
  112. spi_transaction_t tx_trans =
  113. {
  114. .cmd = (CC1200_WRITE_BIT | CC1200_BURST_BIT),
  115. .addr = addr,
  116. .length = 8*len,
  117. .tx_buffer = data
  118. };
  119. if ((addr & 0xFF00) != 0) // send data with extended address in command field
  120. {
  121. tx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  122. spi_transaction_ext_t tx_trans_ext =
  123. {
  124. .base = tx_trans,
  125. .command_bits = 2,
  126. .address_bits = 14
  127. };
  128. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&tx_trans_ext);
  129. }
  130. else
  131. {
  132. ret = spi_device_polling_transmit(spi, &tx_trans);
  133. }
  134. ESP_ERROR_CHECK(ret);
  135. }
  136. void IRAM_ATTR cc1200_spi_read_byte(uint16_t addr, uint8_t* data)
  137. {
  138. esp_err_t ret;
  139. spi_transaction_t rx_trans =
  140. {
  141. .cmd = CC1200_READ_BIT,
  142. .addr = addr,
  143. .length = 8,
  144. .rxlength = 8,
  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. void cc1200_spi_read_bytes(uint16_t addr, uint8_t* data, uint8_t len)
  165. {
  166. esp_err_t ret;
  167. spi_transaction_t rx_trans =
  168. {
  169. .cmd = (CC1200_READ_BIT | CC1200_BURST_BIT),
  170. .addr = addr,
  171. .length = 8*len,
  172. .rxlength = 8*len,
  173. .rx_buffer = data
  174. };
  175. if ((addr & 0xFF00) != 0) // read data with extended address in command field
  176. {
  177. rx_trans.flags |= (SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR);
  178. spi_transaction_ext_t rx_trans_ext =
  179. {
  180. .base = rx_trans,
  181. .command_bits = 2,
  182. .address_bits = 14
  183. };
  184. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext);
  185. }
  186. else
  187. {
  188. ret = spi_device_polling_transmit(spi, &rx_trans);
  189. }
  190. ESP_ERROR_CHECK(ret);
  191. }
  192. rf_status_t IRAM_ATTR cc1200_spi_strobe(uint8_t cmd)
  193. {
  194. esp_err_t ret;
  195. uint8_t temp=0;
  196. spi_transaction_t rx_trans =
  197. {
  198. .flags = (SPI_TRANS_USE_TXDATA | SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR),
  199. .length = 8,
  200. .rxlength = 8,
  201. .rx_buffer = &temp,
  202. .tx_data[0] = cmd
  203. };
  204. spi_transaction_ext_t rx_trans_ext =
  205. {
  206. .base = rx_trans,
  207. .command_bits = 0,
  208. .address_bits = 0
  209. };
  210. ret = spi_device_polling_transmit(spi, (spi_transaction_t*)&rx_trans_ext); // switched to spi poll as test
  211. ESP_ERROR_CHECK(ret);
  212. return (temp & 0xF0);
  213. }
  214. // Public CC1120 Driver Functions
  215. // These function should have there own error codes as they're dependent upon the radio and
  216. // not the ESP32 :)
  217. rf_status_t cc1200_radio_reset(void)
  218. {
  219. rf_status_t status;
  220. uint8_t retry_count = 0;
  221. cc1200_spi_strobe(CC120X_SRES);
  222. status = cc1200_spi_strobe(CC120X_SNOP);
  223. vTaskDelay(10 / portTICK_PERIOD_MS);
  224. while((CC120X_RDYn_BIT & (status & 0x80)))
  225. {
  226. vTaskDelay(10 / portTICK_PERIOD_MS);
  227. if (retry_count > 3)
  228. {
  229. // place error CC1120 timeout
  230. printf("CC1120 Reset Failure\n");
  231. break;
  232. }
  233. status = cc1200_spi_strobe(CC120X_SNOP);
  234. retry_count++;
  235. }
  236. printf("%x\n", retry_count);
  237. return status;
  238. }
  239. // f_RF = f_VCO / LO Divider
  240. #define CC1200_LO_DIVIDER 24 // 136.7 - 160 MHz Band
  241. #define CC1200_XOSC 40000000 // 40MHz
  242. // f_VCO = FREQ / 2^16 * f_XOSX + FREQOFF / 2^18 * F_XOSC
  243. esp_err_t cc1200_radio_frequency(uint32_t freq)
  244. {
  245. // calculate FREQ0, FREQ, FREQ2 registers
  246. volatile double temp_freq;
  247. temp_freq = ((double) freq * 65536 * CC1200_LO_DIVIDER) / CC1200_XOSC;
  248. freq = (uint32_t)temp_freq;
  249. cc1200_spi_write_byte(CC120X_FREQ0, ((uint8_t *)&freq)[0]);
  250. cc1200_spi_write_byte(CC120X_FREQ1, ((uint8_t *)&freq)[1]);
  251. cc1200_spi_write_byte(CC120X_FREQ2, ((uint8_t *)&freq)[2]);
  252. return ESP_OK;
  253. }
  254. esp_err_t cc1200_radio_sleep(void)
  255. {
  256. return ESP_OK;
  257. }
  258. esp_err_t cc1200_radio_power(uint8_t txPower)
  259. {
  260. return ESP_OK;
  261. }
  262. void cc1200_radio_write(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  263. {
  264. uint8_t i;
  265. for (i=0;i<len;i++)
  266. {
  267. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  268. }
  269. }
  270. #define HDLC_FLAG 0x7E
  271. #define HDLC_FLAG_LEN 10
  272. uint8_t packet_len = 0;
  273. uint8_t test_vector[] = {0x71, 0x01, 023, 0xAE, 0x75};
  274. volatile uint8_t sample_count = 0;
  275. uint8_t toggle;
  276. uint8_t toggle2;
  277. uint8_t prev_sample_count = 0;
  278. uint32_t tx_symbol = 0;
  279. uint8_t prev_tx_symbol = 0;
  280. #define SAMPLE_FREQUENCY 13200
  281. #define DAC_MAX 64
  282. #define LUT_SIZE 128
  283. DRAM_ATTR int8_t LUT[LUT_SIZE];
  284. int32_t phase_i = 0;
  285. volatile uint8_t new_sample = 0;
  286. float phase = 0.0f;
  287. float delta_phi = 0.0f;
  288. float const delta_phi_1 = (float) 1200 / SAMPLE_FREQUENCY * LUT_SIZE;
  289. float const delta_phi_2 = (float) 2200 / SAMPLE_FREQUENCY * LUT_SIZE;
  290. uint8_t data;
  291. // The output needs to be continous phase.
  292. typedef struct {
  293. uint8_t one_count;
  294. uint32_t sample_count;
  295. uint32_t byte;
  296. uint32_t packet_len;
  297. uint8_t prev_bit;
  298. uint8_t cur_bit;
  299. uint8_t tone;
  300. } aprs_flags_t;
  301. aprs_flags_t DRAM_ATTR aprs_flags = {
  302. .one_count = 0,
  303. .sample_count = 0,
  304. .byte = 0,
  305. // .packet_len = sizeof(APRS_TEST_PACKET)/sizeof(uint8_t),
  306. .prev_bit = 0,
  307. .cur_bit = 0,
  308. .tone = 0
  309. };
  310. static void IRAM_ATTR LUT_lookup(void)
  311. {
  312. if (aprs_flags.tone)
  313. delta_phi = delta_phi_1;
  314. else
  315. delta_phi = delta_phi_2;
  316. phase_i = (int32_t)phase; // get integer part of our phase
  317. phase += delta_phi; // increment phase
  318. if (phase >= (float)LUT_SIZE) // handle wraparound
  319. phase -= (float)LUT_SIZE;
  320. }
  321. static void IRAM_ATTR cc1200_aprs_tx_isr(void* arg)
  322. {
  323. cc1200_spi_write_byte(CC120X_CFM_TX_DATA_IN, LUT[phase_i]);
  324. sample_count++;
  325. new_sample = 1;
  326. toggle = toggle ^ 1;
  327. gpio_set_level(DEBUG_1, toggle);
  328. }
  329. void cc1200_lut_init(void)
  330. {
  331. int16_t i=0;
  332. for (i=0; i<LUT_SIZE; ++i)
  333. {
  334. LUT[i] = (int8_t)roundf(DAC_MAX * sinf(2.0f * M_PI * (float)i / LUT_SIZE));
  335. //printf("%d,\n", LUT[i]);
  336. }
  337. }
  338. #define PREAMBLE_LENGTH 20
  339. #define SUFFIX_LENGTH 1
  340. void IRAM_ATTR cc1200_radio_APRSTXPacket(uint8_t *f, uint16_t f_len, uint8_t tx_delay, uint8_t tx_tail)
  341. {
  342. // acquire SPI bus for fastest possible SPI transactions
  343. spi_device_acquire_bus(spi, portMAX_DELAY);
  344. vTaskSuspendAll();
  345. // setup data rate for CFM TX
  346. cc1200_radio_write(APRS_TX_RATE, sizeof(APRS_TX_RATE)/sizeof(cc1200_reg_settings_t));
  347. // start CW transmission
  348. cc1200_spi_write_byte(CC120X_FIFO, 0x12);
  349. cc1200_spi_strobe(CC120X_STX);
  350. // enable interrupt pin for CC1120 for timing packets
  351. gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
  352. gpio_isr_handler_add(CC1120_GPIO3, cc1200_aprs_tx_isr, NULL);
  353. gpio_set_intr_type(CC1120_GPIO3, GPIO_INTR_POSEDGE);
  354. int16_t i,j;
  355. uint16_t p_len = tx_delay * 12;
  356. uint16_t t_len = tx_tail * 12 + 1;
  357. // Start CW transmission
  358. cc1200_spi_write_byte(CC120X_FIFO, 0x12);
  359. cc1200_spi_strobe(CC120X_STX);
  360. sample_count = 0;
  361. new_sample = 0;
  362. // Send HDLC Flag for TX Delay Time
  363. for (i = 0; i<p_len; i++)
  364. {
  365. esp_task_wdt_reset();
  366. aprs_flags.byte = 0x7E;
  367. for(j=0; j<8; j++)
  368. {
  369. aprs_flags.cur_bit = aprs_flags.byte & 0x01;
  370. // NRZ-I Encoding
  371. if (aprs_flags.cur_bit)
  372. {
  373. // do nothing
  374. aprs_flags.one_count++;
  375. }
  376. else
  377. {
  378. aprs_flags.tone = aprs_flags.tone ^ 1; // switch tone
  379. aprs_flags.one_count = 0;
  380. }
  381. aprs_flags.byte = (aprs_flags.byte >> 1);
  382. while(sample_count < 11) // wait for symbol to be sent
  383. {
  384. if ( new_sample )
  385. {
  386. LUT_lookup();
  387. new_sample = 0;
  388. }
  389. }
  390. sample_count = 0;
  391. //printf("Symbol: %x\n", aprs_flags.cur_bit);
  392. }
  393. }
  394. aprs_flags.one_count = 0;
  395. // Send Packet / Frame
  396. //for (i=0;i<aprs_flags.packet_len;i++)
  397. for (i=0;i<f_len;i++)
  398. {
  399. esp_task_wdt_reset();
  400. aprs_flags.byte = f[i];
  401. for(j=0; j<8; j++)
  402. {
  403. aprs_flags.cur_bit = aprs_flags.byte & 0x01; // bool of first bit
  404. // Zero Stuffing
  405. if (aprs_flags.one_count == 5)
  406. {
  407. aprs_flags.tone = aprs_flags.tone ^ 1;
  408. aprs_flags.one_count = 0;
  409. // wait for symbol to be sent
  410. while(sample_count < 11)
  411. {
  412. if ( new_sample )
  413. {
  414. LUT_lookup();
  415. new_sample = 0;
  416. }
  417. }
  418. toggle2 = toggle2 ^ 1;
  419. //gpio_set_level(DEBUG_0, toggle2);
  420. sample_count = 0;
  421. }
  422. // NRZ-I Encoding
  423. if (aprs_flags.cur_bit)
  424. {
  425. // do nothing
  426. aprs_flags.one_count++;
  427. }
  428. else
  429. {
  430. aprs_flags.tone = aprs_flags.tone ^ 1; // switch tone
  431. aprs_flags.one_count = 0;
  432. }
  433. aprs_flags.byte = (aprs_flags.byte >> 1);
  434. while(sample_count < 11) // wait for symbol to be sent
  435. {
  436. if ( new_sample )
  437. {
  438. LUT_lookup();
  439. new_sample = 0;
  440. }
  441. }
  442. toggle2 = toggle2 ^ 1;
  443. //gpio_set_level(DEBUG_0, toggle2);
  444. sample_count = 0;
  445. //printf("Symbol: %x\n", aprs_flags.cur_bit);
  446. }
  447. }
  448. aprs_flags.one_count = 0;
  449. // Send HDLC Flag for TX Tail
  450. for (i = 0; i<t_len; i++)
  451. {
  452. esp_task_wdt_reset();
  453. aprs_flags.byte = 0x7E;
  454. for(j=0; j<8;j++)
  455. {
  456. aprs_flags.cur_bit = aprs_flags.byte & 0x01;
  457. // NRZ-I Encoding
  458. if (aprs_flags.cur_bit)
  459. {
  460. // do nothing
  461. aprs_flags.one_count++;
  462. }
  463. else
  464. {
  465. aprs_flags.tone = aprs_flags.tone ^ 1; // switch tone
  466. aprs_flags.one_count = 0;
  467. }
  468. aprs_flags.byte = (aprs_flags.byte >> 1);
  469. while(sample_count < 11) // wait for symbol to be sent
  470. {
  471. if ( new_sample )
  472. {
  473. LUT_lookup();
  474. new_sample = 0;
  475. }
  476. }
  477. sample_count = 0;
  478. }
  479. }
  480. cc1200_spi_strobe(CC120X_SIDLE);
  481. //cc1200_spi_strobe(CC120X_SFTX);
  482. xTaskResumeAll();
  483. spi_device_release_bus(spi);
  484. gpio_uninstall_isr_service();
  485. }
  486. extern SemaphoreHandle_t xRadioRXSemaphore;
  487. static void IRAM_ATTR cc1200_aprs_rx_isr(void* arg)
  488. {
  489. //uint8_t data = 0;
  490. //cc1200_spi_read_byte(CC120X_CFM_RX_DATA_OUT, &data);
  491. static BaseType_t xHigherPriorityTaskWoken;
  492. gpio_set_intr_type(CC1120_GPIO2, GPIO_INTR_DISABLE);
  493. xSemaphoreGiveFromISR(xRadioRXSemaphore, &xHigherPriorityTaskWoken);
  494. if (xHigherPriorityTaskWoken == pdTRUE)
  495. {
  496. portYIELD_FROM_ISR( );
  497. }
  498. //cc1200_spi_read_byte(CC120X_RSSI1, &data);
  499. //toggle = toggle ^ 1;
  500. // gpio_set_level(DEBUG_0, toggle);
  501. //xRingbufferSendFromISR(cfm_buf_handle, &data, sizeof(data), NULL);
  502. //ets_write_char_uart(data);
  503. //new_sample = 1;
  504. }
  505. void IRAM_ATTR cc1200_radio_start_APRSRX(void)
  506. {
  507. // acquire SPI bus for fastest possible SPI transactions
  508. spi_device_acquire_bus(spi, portMAX_DELAY);
  509. //vTaskSuspendAll();
  510. // start RX transmission
  511. cc1200_radio_write(APRS_RX_RATE, sizeof(APRS_RX_RATE)/sizeof(cc1200_reg_settings_t));
  512. while(cc1200_spi_strobe(CC120X_SRX) != CC120X_STATE_RX);
  513. // enable interrupt pin for CC1120 for timing packets
  514. gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
  515. gpio_isr_handler_add(CC1120_GPIO2, cc1200_aprs_rx_isr, NULL);
  516. gpio_set_intr_type(CC1120_GPIO2, GPIO_INTR_POSEDGE);
  517. }
  518. void cc1200_radio_stop_APRSRX(void)
  519. {
  520. gpio_uninstall_isr_service();
  521. cc1200_spi_strobe(CC120X_SIDLE);
  522. spi_device_release_bus(spi);
  523. }
  524. void cc1200_radio_init(const cc1200_reg_settings_t* rf_settings, uint8_t len)
  525. {
  526. cc1200_gpio_init();
  527. cc1200_spi_init();
  528. cc1200_lut_init();
  529. cc1200_radio_reset(); gpio_set_level(CC1120_RESET, 1);
  530. uint8_t data;
  531. cc1200_spi_read_byte(CC120X_PARTNUMBER, &data);
  532. printf("%x", data);
  533. uint8_t i;
  534. for (i=0;i<len;i++)
  535. {
  536. cc1200_spi_write_byte(rf_settings[i].addr, rf_settings[i].data);
  537. }
  538. }