main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. * Project: Arrow
  3. * Author: curiousmuch
  4. * Description: This project is an APRS transceiver based on the ESP32 and CC1200.
  5. * TODO: Refactor Code to isolate into seperate components
  6. * TODO: Isolate BT_SPP.C functionality
  7. * TODO: Isolate KISS.C functionality
  8. * TODO: Remove any dependancies on Direwolf.
  9. * TODO: Transfer DSP functions to APRS folder
  10. * TODO: Abstract includes to be nicer (#include aprs.h) for example
  11. * TODO: Isolate CC1200 functions from other parts / maybe integrate most of TX scheme into task.
  12. */
  13. #include <stdio.h>
  14. #include "freertos/FreeRTOS.h"
  15. #include "freertos/task.h"
  16. #include "freertos/semphr.h"
  17. #include "freertos/ringbuf.h"
  18. #include "driver/gpio.h"
  19. #include "sdkconfig.h"
  20. #include "esp_task_wdt.h"
  21. #include "cc1200.h"
  22. #include "cc1200_protocol.h"
  23. #include "board.h"
  24. #include "nvs.h"
  25. #include "nvs_flash.h"
  26. #include "esp_log.h"
  27. #include "esp_bt.h"
  28. #include "esp_bt_main.h"
  29. #include "esp_gap_bt_api.h"
  30. #include "esp_bt_device.h"
  31. #include "esp_spp_api.h"
  32. #include "bt_spp.h"
  33. #include "ax25_pad2.h"
  34. #include "ax25_pad.h"
  35. #include "fcs_calc.h"
  36. #include "math.h"
  37. #include "driver/timer.h"
  38. #include "aprs_decoder.h"
  39. #include "kiss.h"
  40. #include "afsk_demodulator.h"
  41. //#include "esp_dsp.h"
  42. RingbufHandle_t radio_tx_buf;
  43. RingbufHandle_t radio_rx_buf;
  44. SemaphoreHandle_t xRadioRXISRSemaphore;
  45. SemaphoreHandle_t xRadioRXSemaphore;
  46. SemaphoreHandle_t xRadioTXSemaphore;
  47. SemaphoreHandle_t xRadioMutex;
  48. //RingbufHandle_t radio_rx_buf;
  49. extern int8_t EXTERNAL_DATA;
  50. extern decoder_varibles_t v;
  51. // Timer Functions
  52. void IRAM_ATTR rx_timer_isr(void *para)
  53. {
  54. //GPIO.out_w1ts = (1 << DEBUG_0);
  55. int timer_idx = (int) para;
  56. /* Clear the interrupt
  57. and update the alarm time for the timer with without reload */
  58. TIMERG0.int_clr_timers.t0 = 1;
  59. // after the alarm has been triggered
  60. // we need enable it again, so it is triggered the next time
  61. TIMERG0.hw_timer[0].config.alarm_en = TIMER_ALARM_EN;
  62. static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  63. xSemaphoreGiveFromISR(xRadioRXISRSemaphore, &xHigherPriorityTaskWoken);
  64. if (xHigherPriorityTaskWoken == pdTRUE)
  65. {
  66. portYIELD_FROM_ISR( );
  67. }
  68. //GPIO.out_w1tc = (1 << DEBUG_0);
  69. }
  70. void Radio_Task(void *pvParameters)
  71. {
  72. size_t p_size;
  73. // Setup Timer for TX Task
  74. timer_config_t config;
  75. config.divider = 2;
  76. config.counter_dir = TIMER_COUNT_UP;
  77. config.counter_en = TIMER_PAUSE;
  78. config.alarm_en = TIMER_ALARM_EN;
  79. config.intr_type = TIMER_INTR_LEVEL;
  80. config.auto_reload = TIMER_AUTORELOAD_EN;
  81. timer_init(TIMER_GROUP_0, TIMER_1, &config);
  82. timer_set_counter_value(TIMER_GROUP_0, TIMER_1, 0x00000000ULL);
  83. timer_set_alarm_value(TIMER_GROUP_0, TIMER_1, 3030);
  84. timer_isr_register(TIMER_GROUP_0, TIMER_1, cc1200_aprs_tx_isr,
  85. (void *) TIMER_1, ESP_INTR_FLAG_IRAM, NULL);
  86. // Setup Sampling Timer for RX Task
  87. timer_config_t rx_config;
  88. rx_config.divider = 2;
  89. rx_config.counter_dir = TIMER_COUNT_UP;
  90. rx_config.counter_en = TIMER_PAUSE;
  91. rx_config.alarm_en = TIMER_ALARM_EN;
  92. rx_config.intr_type = TIMER_INTR_LEVEL;
  93. rx_config.auto_reload = TIMER_AUTORELOAD_EN;
  94. timer_init(TIMER_GROUP_0, TIMER_0, &rx_config);
  95. timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
  96. timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 3030);
  97. timer_isr_register(TIMER_GROUP_0, TIMER_0, rx_timer_isr,
  98. (void *) TIMER_0, ESP_INTR_FLAG_IRAM, NULL);
  99. // Initialize Radio
  100. cc1200_radio_init(APRS_RX2_SETTINGS, sizeof(APRS_RX2_SETTINGS)/sizeof(cc1200_reg_settings_t));
  101. cc1200_radio_frequency(144390000);
  102. while(1)
  103. {
  104. // setup LEDs for RX mode
  105. disable_red_led();
  106. enable_green_led();
  107. cc1200_radio_start_APRSRX();
  108. timer_enable_intr(TIMER_GROUP_0, TIMER_0);
  109. timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
  110. timer_start(TIMER_GROUP_0, TIMER_0);
  111. // block until packet is in queue
  112. uint8_t *p = (uint8_t *)xRingbufferReceive(radio_tx_buf, &p_size, portMAX_DELAY);
  113. // send packet
  114. if (p != NULL)
  115. {
  116. // disable RX mode
  117. timer_disable_intr(TIMER_GROUP_0, TIMER_0);
  118. timer_pause(TIMER_GROUP_0, TIMER_0);
  119. cc1200_radio_stop_APRSRX();
  120. // setup LEDs for TX mode
  121. enable_red_led();
  122. disable_green_led();
  123. cc1200_radio_APRSTXPacket(p, p_size, 4, 1);
  124. vRingbufferReturnItem(radio_tx_buf, (void *)p);
  125. }
  126. }
  127. }
  128. // Phase Locked Loop (PLL) Parameters
  129. #define BAUD_RATE (1200)
  130. #define SAMPLES_BIT (SAMPLEFREQUENCY / BAUD_RATE)
  131. #define D_PLL_INC (SAMPLES_BIT * 1)
  132. #define D_PLL_MAX (D_PLL_INC * SAMPLES_BIT *1)
  133. #define D_PLL_MARGIN (dpll_margin)
  134. uint8_t aprs_buf[256];
  135. void dsps_biquad_gen_lpf_f32(float *coeffs, float f, float qFactor)
  136. {
  137. if (qFactor <= 0.0001) {
  138. qFactor = 0.0001;
  139. }
  140. float Fs = 1;
  141. float w0 = 2 * M_PI * f / Fs;
  142. float c = cosf(w0);
  143. float s = sinf(w0);
  144. float alpha = s / (2 * qFactor);
  145. float b0 = (1 - c) / 2;
  146. float b1 = 1 - c;
  147. float b2 = b0;
  148. float a0 = 1 + alpha;
  149. float a1 = -2 * c;
  150. float a2 = 1 - alpha;
  151. coeffs[0] = b0 / a0;
  152. coeffs[1] = b1 / a0;
  153. coeffs[2] = b2 / a0;
  154. coeffs[3] = a1 / a0;
  155. coeffs[4] = a2 / a0;
  156. return;
  157. }
  158. void dsps_biquad_f32_ansi(const float *input, float *output, int len, float *coef, float *w)
  159. {
  160. for (int i = 0 ; i < len ; i++) {
  161. float d0 = input[i] - coef[3] * w[0] - coef[4] * w[1];
  162. output[i] = coef[0] * d0 + coef[1] * w[0] + coef[2] * w[1];
  163. w[1] = w[0];
  164. w[0] = d0;
  165. }
  166. return;
  167. }
  168. float lpf_coef0[5];
  169. float lpf_coef1[5];
  170. float lpf_delay0[2];
  171. float lpf_delay1[2];
  172. void lpf_init(void)
  173. {
  174. // generate filter coef
  175. dsps_biquad_gen_lpf_f32(lpf_coef0, 0.10, 0.54119610);
  176. dsps_biquad_gen_lpf_f32(lpf_coef1, 0.10, 1.3065630);
  177. // setup delay line and lpf_input window
  178. int i;
  179. for(i=0;i<2;i++)
  180. {
  181. lpf_delay0[i] = 0;
  182. lpf_delay1[i] = 0;
  183. }
  184. }
  185. float lpf_baseband(float input)
  186. {
  187. float output, temp;
  188. dsps_biquad_f32_ansi(&input, &temp, 1, lpf_coef0, lpf_delay0);
  189. dsps_biquad_f32_ansi(&temp, &output, 1, lpf_coef1, lpf_delay1);
  190. return output;
  191. }
  192. void RX_DSP_Task(void *pvParameters)
  193. {
  194. // algorithm variables
  195. volatile float E_s1=0, E_s2=0, lpf_output;
  196. volatile uint8_t raw_bit=0, previous_raw_bit=1;
  197. volatile int32_t d_pll=0, dpll_error=0, err_div=0, dpll_margin = 1;
  198. uint32_t success = 0;
  199. float coeff0, coeff1;
  200. volatile uint32_t count_start, count_stop; // needed for debuging
  201. aprs_decoder_init();
  202. frame_buffer_init(aprs_buf, 256);
  203. goertzel_init(1200, 2200, &coeff0, &coeff1);
  204. lpf_init();
  205. // Sampling Semaphore
  206. xRadioRXISRSemaphore = xSemaphoreCreateBinary();
  207. while(1)
  208. {
  209. count_start = xthal_get_ccount();
  210. if( xSemaphoreTake(xRadioRXISRSemaphore, portMAX_DELAY) == pdTRUE)
  211. {
  212. //enable_debug_IO(DEBUG_0);
  213. if (xSemaphoreTake(xRadioMutex, 0) == pdTRUE)
  214. {
  215. //disable_debug_IO(DEBUG_0);
  216. //enable_debug_IO(DEBUG_0);
  217. EXTERNAL_DATA = (int)cc1200_radio_read_CFM();
  218. //EXTERNAL_DATA = gpio_get_level(CC1120_GPIO2);
  219. xSemaphoreGive(xRadioMutex);
  220. //disable_debug_IO(DEBUG_0);
  221. }
  222. else
  223. {
  224. ESP_LOGE("Radio", "Sampling Failure");
  225. }
  226. //disable_debug_IO(DEBUG_0);
  227. //enable_debug_IO(DEBUG_0);
  228. window_add(EXTERNAL_DATA);
  229. int8_t *window = window_get();
  230. E_s1 = goertzel_filter(window, coeff0, WINDOW_SIZE);
  231. E_s2 = goertzel_filter(window, coeff1, WINDOW_SIZE);
  232. //E_s1 = goertzelFilter(window, 1200, WINDOW_SIZE);
  233. //E_s1 = goertzelFilter(window, 2200, WINDOW_SIZE);
  234. lpf_output = lpf_baseband((E_s1 - E_s2));
  235. if (lpf_output > 0)
  236. {
  237. raw_bit = 1;
  238. enable_debug_IO(DEBUG_2);
  239. }
  240. else
  241. {
  242. raw_bit = 0;
  243. disable_debug_IO(DEBUG_2);
  244. }
  245. //disable_debug_IO(DEBUG_0);
  246. //enable_debug_IO(DEBUG_0);
  247. // DPLL for sampling
  248. if (raw_bit != previous_raw_bit)
  249. {
  250. dpll_error = d_pll - (D_PLL_MAX / 2);
  251. if (dpll_error > (D_PLL_MARGIN))
  252. {
  253. d_pll -= get_rx_status() ? D_PLL_MARGIN:
  254. (err_div + dpll_error);//(dpll_error + err_div / 2) / err_div;
  255. }
  256. else if (dpll_error < (-D_PLL_MARGIN))
  257. {
  258. d_pll += get_rx_status() ? D_PLL_MARGIN:
  259. -(err_div + dpll_error); //(dpll_error + err_div / 2) / err_div;
  260. }
  261. }
  262. d_pll += D_PLL_INC;
  263. if (d_pll >= D_PLL_MAX)
  264. {
  265. // set clock debug I/O high
  266. enable_debug_IO(DEBUG_3);
  267. // feed bit to aprs decoder algorithm
  268. switch(aprs_decoder_feed_bit(raw_bit))
  269. {
  270. case NORMAL:
  271. break;
  272. case FRAME_DECODED:
  273. ESP_LOGI("APRS RX", "AX.25 Frame Received [%d]", success++);
  274. // send via KISS TNC to over BLE SPP
  275. //ESP_LOG_BUFFER_HEXDUMP("APRS RX", aprs_buf, 100, ESP_LOG_INFO);
  276. kiss_transmit(KISS_DATAFRAME, v.frame_buffer, v.frame_len);
  277. break;
  278. case ERROR_FCS_MISMATCH:
  279. ESP_LOGV("APRS RX", "AX.25 FCS Error\n");
  280. break;
  281. default:
  282. //printf("Weird Error\n");
  283. break;
  284. }
  285. d_pll -= D_PLL_MAX;
  286. }
  287. else
  288. {
  289. // set clock debug I/O low
  290. disable_debug_IO(DEBUG_3);
  291. }
  292. count_stop = xthal_get_ccount();
  293. previous_raw_bit = raw_bit;
  294. }
  295. }
  296. }
  297. void radio_init()
  298. {
  299. // Setup Task Communications
  300. radio_tx_buf = xRingbufferCreate(1028, RINGBUF_TYPE_NOSPLIT);
  301. radio_rx_buf = xRingbufferCreate(1028, RINGBUF_TYPE_NOSPLIT);
  302. xRadioRXSemaphore = xSemaphoreCreateBinary();
  303. xRadioTXSemaphore = xSemaphoreCreateBinary();
  304. xRadioMutex = xSemaphoreCreateMutex();
  305. xTaskCreatePinnedToCore(Radio_Task, "Radio Controller", 1024*4, 0, 2, NULL, 1);
  306. xTaskCreatePinnedToCore(RX_DSP_Task, "Radio DSP", 1024*4, 0, 1, NULL, 1);
  307. }
  308. void IRAM_ATTR app_main()
  309. {
  310. // Initialize Flash
  311. esp_err_t ret = nvs_flash_init();
  312. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  313. ESP_ERROR_CHECK(nvs_flash_erase());
  314. ret = nvs_flash_init();
  315. }
  316. ESP_ERROR_CHECK( ret );
  317. // Board IO Initialize
  318. board_init();
  319. // Radio Task Initialize
  320. radio_init();
  321. // AFSK Decoder and Encoder
  322. // Kiss Decoder and Encoder
  323. kiss_init();
  324. // BLE and SPP
  325. bt_spp_init();
  326. }