cc1200.c 14 KB

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