main.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. /* Standard Includes */
  14. #include <stdio.h>
  15. /* ESP-IDF */
  16. #include "sdkconfig.h"
  17. #include "freertos/FreeRTOS.h"
  18. #include "freertos/task.h"
  19. #include "freertos/semphr.h"
  20. #include "freertos/ringbuf.h"
  21. #include "nvs.h"
  22. #include "nvs_flash.h"
  23. #include "esp_log.h"
  24. /* Application Specific */
  25. #include "bt_spp.h"
  26. #include "board.h"
  27. #include "radio.h"
  28. #include "kiss.h"
  29. #include "fcs_calc.h"
  30. /* Data Structures */
  31. typedef struct {
  32. uint8_t tnc_number;
  33. uint8_t tx_delay;
  34. uint8_t P;
  35. uint8_t slot_time;
  36. uint8_t full_duplex;
  37. uint8_t tx_tail;
  38. } tnc_settings_t;
  39. /* Public Variables */
  40. tnc_settings_t tnc_settings;
  41. uint8_t ax25_rx_buf[1024];
  42. RingbufHandle_t ax25_tx_buf;
  43. /* Functions and Main */
  44. /* Radio Callback Functions */
  45. // callback function for when radio rx'd AX25 packet
  46. // unblocks task on other core and packet to another buffer
  47. // so we can continue processing
  48. void radio_rx_ax25_cb(uint8_t *frame, uint32_t len)
  49. {
  50. ESP_LOGV("AX25 CB", "We Here");
  51. // unblock receive task on CPU0
  52. }
  53. /* KISS callback Functions */
  54. void kiss_tx_cb(uint8_t *frame, uint32_t len)
  55. {
  56. // send data to UART / via bluetooth
  57. bt_spp_tx(frame, len);
  58. }
  59. void kiss_rx_cb(uint8_t *frame, uint32_t len)
  60. {
  61. uint8_t data_byte;
  62. data_byte = frame[0] & 0x0F; // tnc_number information
  63. // process dataframe
  64. if (data_byte == KISS_DATAFRAME)
  65. {
  66. // feed packet to ring buffer
  67. uint32_t fcs = fcs_calc(&frame[1], len-1);
  68. frame[len] = fcs & 0xFF;
  69. frame[len+1] = fcs>>8 & 0xFF;
  70. xRingbufferSend(ax25_tx_buf, &frame[1], ((len+1)*sizeof(uint8_t)),10/portTICK_PERIOD_MS);
  71. }
  72. else // assume command
  73. {
  74. switch(data_byte)
  75. {
  76. case KISS_CMD_TXDELAY:
  77. ESP_LOGI("TNC", "updated tx delay");
  78. tnc_settings.tx_delay = frame[1];
  79. break;
  80. case KISS_CMD_P:
  81. ESP_LOGI("TNC", "updated persistance");
  82. tnc_settings.P = frame[1];
  83. break;
  84. case KISS_CMD_SLOTTIME:
  85. ESP_LOGI("TNC", "updated slot time");
  86. tnc_settings.slot_time = frame[1];
  87. break;
  88. case KISS_CMD_TXTAIL:
  89. ESP_LOGI("TNC", "updated tx tail");
  90. tnc_settings.tx_tail = frame[1];
  91. break;
  92. case KISS_CMD_FULLDUPLEX:
  93. ESP_LOGI("TNC", "updated duplex setting");
  94. tnc_settings.full_duplex = frame[1];
  95. break;
  96. case KISS_CMD_SETHARDWARE:
  97. ESP_LOGI("TNC", "updated hardware settings");
  98. break;
  99. case KISS_CMD_RETURN:
  100. ESP_LOGI("TNC", "wtf is return");
  101. break;
  102. default:
  103. ESP_LOGE("KISS", "unknown data byte");
  104. }
  105. // reload for parameter changes to take effect
  106. }
  107. }
  108. /* TNC Tasks */
  109. // schedules transmissions based on p-persistance
  110. // settings and carrier sense from radio a
  111. // TODO: Latch CS during slot time?
  112. void tnc_task(void *para)
  113. {
  114. radio_packet_rx(NULL);
  115. uint8_t *packet;
  116. size_t packet_size;
  117. while(1)
  118. {
  119. // indicate RX
  120. enable_green_led();
  121. disable_red_led();
  122. // check ring buffer for packet
  123. packet = xRingbufferReceive(ax25_tx_buf, &packet_size, portMAX_DELAY);
  124. if (packet != NULL)
  125. {
  126. uint8_t P;
  127. // wait based on persistance algorithm
  128. while (1)
  129. {
  130. if (!radio_get_cs())
  131. {
  132. P = (uint8_t) esp_random();
  133. if (P <= tnc_settings.P)
  134. {
  135. break;
  136. }
  137. else
  138. {
  139. vTaskDelay(tnc_settings.slot_time * 10 / portTICK_PERIOD_MS);
  140. }
  141. }
  142. taskYIELD(); // make sure to yield for RX'ing task
  143. }
  144. // indicate TX
  145. enable_red_led();
  146. disable_green_led();
  147. // dump all the packets in the buffer
  148. while(packet != NULL)
  149. {
  150. radio_packet_tx(packet, packet_size, NULL);
  151. vRingbufferReturnItem(ax25_tx_buf, (void *)packet);
  152. packet = xRingbufferReceive(ax25_tx_buf, &packet_size, 0);
  153. }
  154. }
  155. else
  156. {
  157. printf("Why we here \n");
  158. }
  159. // setup again for reception
  160. radio_packet_rx(NULL);
  161. }
  162. }
  163. void IRAM_ATTR app_main()
  164. {
  165. // Initialize Flash
  166. esp_err_t ret = nvs_flash_init();
  167. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  168. ESP_ERROR_CHECK(nvs_flash_erase());
  169. ret = nvs_flash_init();
  170. }
  171. ESP_ERROR_CHECK( ret );
  172. // Board IO Initialize
  173. board_init();
  174. // Load Settings from Flash
  175. // Radio Task Initialize
  176. ax25_param_t ax25_param;
  177. ax25_param.tx_tail = 10;
  178. ax25_param.tx_delay = 10;
  179. ax25_param.sample_rate = 13200;
  180. ax25_param.symbol0_freq = 1200;
  181. ax25_param.symbol1_freq = 2200;
  182. ax25_param.rx_cb = radio_rx_ax25_cb;
  183. ax25_param.rx_buf = ax25_rx_buf;
  184. ax25_param.rx_buf_len = sizeof(ax25_rx_buf) / sizeof(ax25_rx_buf[0]);
  185. ax25_param.cpu_core = 1;
  186. radio_init(AX25, &ax25_param);
  187. // Kiss Decoder and Encoder
  188. kiss_init(0, kiss_tx_cb, kiss_rx_cb);
  189. // BLE and SPP
  190. bt_spp_init();
  191. // Inter-Task Communication
  192. ax25_tx_buf = xRingbufferCreate(1028, RINGBUF_TYPE_NOSPLIT);
  193. // Tasks
  194. xTaskCreatePinnedToCore(tnc_task, "tnc task", 1024*4, 0, 2, NULL, 1);
  195. }