cc1200.c 13 KB

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