123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #include <stdio.h>
- #include <stddef.h>
- #include "sdkconfig.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/semphr.h"
- #include "freertos/ringbuf.h"
- #include "nvs.h"
- #include "nvs_flash.h"
- #include "esp_log.h"
- #include "bt_spp.h"
- #include "board.h"
- #include "radio.h"
- #include "kiss.h"
- #include "fcs_calc.h"
- typedef enum {
- TNC_TX=0,
- TNC_RX,
- TNC_IDLE
- } tnc_status_t;
- typedef struct {
- uint8_t tnc_number;
- uint8_t tx_delay;
- uint8_t P;
- uint8_t slot_time;
- uint8_t full_duplex;
- uint8_t tx_tail;
- uint8_t frequency_index;
- uint8_t mode_index;
- uint32_t freq;
- radio_config_t mode;
- tnc_status_t status;
- TaskHandle_t tnc_task;
- } tnc_settings_t;
- static tnc_settings_t tnc_settings;
- static SemaphoreHandle_t xRadioTXSemaphore;
- uint8_t ax25_rx_buf[1024];
- RingbufHandle_t ax25_tx_buf;
- uint32_t ax_freq_table[16] = { 144390000,
- 145512500,
- 145537500,
- 145562500,
- 145587500,
- 145612500,
- 145637500,
- 145662500,
- 145687500,
- 145712500,
- 145737500,
- 145762500,
- 145787500,
- 145812500,
- 145837500,
- 145862500 };
- void radio_rx_ax25_cb(uint8_t *frame, uint32_t len)
- {
-
- kiss_transmit(KISS_DATAFRAME, frame, len);
- }
- void radio_tx_ax25_cb(void)
- {
-
- xSemaphoreGive(xRadioTXSemaphore);
- }
- void tnc_print_settings(void)
- {
- ESP_LOGI("tnc", "TX Delay: %d", tnc_settings.tx_delay*10);
- ESP_LOGI("tnc", "TX Tail: %d", tnc_settings.tx_tail*10);
- ESP_LOGI("tnc", "Slot Time: %d", tnc_settings.slot_time*10);
- ESP_LOGI("tnc", "P: %d", tnc_settings.P);
- ESP_LOGI("tnc", "Frequency: %d", tnc_settings.freq);
- }
- void kiss_tx_cb(uint8_t *frame, uint32_t len)
- {
-
-
-
- bt_spp_tx(frame, len);
- ESP_LOGI("tnc", "kiss packet sent");
- }
- void kiss_rx_cb(uint8_t *frame, uint32_t len)
- {
- uint8_t data_byte;
- data_byte = frame[0] & 0x0F;
-
- if (data_byte == KISS_DATAFRAME)
- {
- ESP_LOGI("tnc", "kiss packet received");
-
- uint32_t fcs = fcs_calc(&frame[1], len-1);
- frame[len] = fcs & 0xFF;
- frame[len+1] = fcs>>8 & 0xFF;
- if (xRingbufferSend(ax25_tx_buf, &frame[1], ((len+1)*sizeof(uint8_t)),10/portTICK_PERIOD_MS) == pdFALSE)
- {
- ESP_LOGE("tnc", "packet buffer overflow");
- }
- }
- else
- {
- ESP_LOGI("tnc", "received tnc command");
- switch(data_byte)
- {
- case KISS_CMD_TXDELAY:
- tnc_settings.tx_delay = frame[1];
- break;
- case KISS_CMD_P:
- tnc_settings.P = frame[1];
- break;
- case KISS_CMD_SLOTTIME:
- tnc_settings.slot_time = frame[1];
- break;
- case KISS_CMD_TXTAIL:
- tnc_settings.tx_tail = frame[1];
- break;
- case KISS_CMD_FULLDUPLEX:
- tnc_settings.full_duplex = frame[1];
- break;
- case KISS_CMD_SETHARDWARE:
- {
- uint8_t freq_index = frame[1] & 0x0F;
- tnc_settings.freq = ax_freq_table[freq_index];
- break;
- }
- default:
- ESP_LOGE("tnc", "unknown data byte for KISS protocol");
- }
-
- ESP_LOGW("tnc", "waiting to disable tnc...");
- while(tnc_settings.status != TNC_RX)
- {
- vTaskDelay(100 / portTICK_PERIOD_MS);
- }
-
- tnc_print_settings();
-
- vTaskSuspend(tnc_settings.tnc_task);
- ESP_LOGW("tnc", "disabled tnc");
-
- ax25_param_t ax25_param;
- ax25_param.tx_tail = tnc_settings.tx_tail;
- ax25_param.tx_delay = tnc_settings.tx_delay;
- ax25_param.sample_rate = 13200;
- ax25_param.symbol0_freq = 1200;
- ax25_param.symbol1_freq = 2200;
- ax25_param.rx_cb = radio_rx_ax25_cb;
- ax25_param.tx_cb = radio_tx_ax25_cb;
- ax25_param.rx_buf = ax25_rx_buf;
- ax25_param.rx_buf_len = sizeof(ax25_rx_buf) / sizeof(ax25_rx_buf[0]);
- ax25_param.cpu_core = 1;
- radio_reinit(AX25, &ax25_param);
- radio_set_frequency(tnc_settings.freq);
-
- radio_packet_rx(NULL);
-
- vTaskResume(tnc_settings.tnc_task);
- ESP_LOGI("tnc", "re-enabled tnc");
- }
- }
- void tnc_task(void *para)
- {
- uint8_t *packet;
- size_t packet_size;
- uint8_t P;
- radio_packet_rx(NULL);
- tnc_settings.status = TNC_RX;
- while(1)
- {
-
- enable_green_led();
- disable_red_led();
-
- packet = xRingbufferReceive(ax25_tx_buf, &packet_size, portMAX_DELAY);
- ESP_LOGI("tnc", "scheduling transmission");
- if (packet != NULL)
- {
-
- while (1)
- {
-
-
- if (radio_get_cs() == 0)
- {
- ESP_LOGV("radio", "carrier not detected");
- P = (uint8_t) esp_random();
- if (P <= tnc_settings.P)
- {
- ESP_LOGI("radio", "transmission scheduled");
- break;
- }
- else
- {
- ESP_LOGV("radio", "transmission postponed");
- vTaskDelay((tnc_settings.slot_time * 10) / portTICK_PERIOD_MS);
- }
- }
- else
- {
- ESP_LOGV("radio", "carrier detected");
- vTaskDelay(10 / portTICK_PERIOD_MS);
- }
- }
-
- enable_red_led();
- disable_green_led();
-
-
- while(packet != NULL)
- {
-
- tnc_settings.status = TNC_TX;
- radio_packet_tx(packet, packet_size, NULL);
-
- xSemaphoreTake(xRadioTXSemaphore, portMAX_DELAY);
- tnc_settings.status = TNC_IDLE;
-
- vRingbufferReturnItem(ax25_tx_buf, (void *)packet);
- packet = xRingbufferReceive(ax25_tx_buf, &packet_size, 0);
- }
- }
- else
- {
- ESP_LOGE("tnc", "buffer error");
- }
-
- radio_packet_rx(NULL);
- tnc_settings.status = TNC_RX;
- }
- }
- void app_main()
- {
-
- ax25_tx_buf = xRingbufferCreate(1028, RINGBUF_TYPE_NOSPLIT);
- xRadioTXSemaphore = xSemaphoreCreateBinary();
-
- esp_err_t ret = nvs_flash_init();
- if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
- ESP_ERROR_CHECK(nvs_flash_erase());
- ret = nvs_flash_init();
- }
- ESP_ERROR_CHECK( ret );
-
- board_init();
-
- tnc_settings.P = 63;
- tnc_settings.tx_tail = 0;
- tnc_settings.tx_delay = 10;
- tnc_settings.P = 63;
- tnc_settings.slot_time = 10;
- tnc_settings.tnc_number = 0;
- tnc_settings.status = TNC_IDLE;
- tnc_settings.freq = 144390000;
- tnc_settings.mode = AX25;
-
- ax25_param_t ax25_param;
- ax25_param.tx_tail = tnc_settings.tx_tail;
- ax25_param.tx_delay = tnc_settings.tx_delay;
- ax25_param.sample_rate = 13200;
- ax25_param.symbol0_freq = 1200;
- ax25_param.symbol1_freq = 2200;
- ax25_param.rx_cb = radio_rx_ax25_cb;
- ax25_param.tx_cb = radio_tx_ax25_cb;
- ax25_param.rx_buf = ax25_rx_buf;
- ax25_param.rx_buf_len = sizeof(ax25_rx_buf) / sizeof(ax25_rx_buf[0]);
- ax25_param.cpu_core = 1;
-
- tnc_print_settings();
- radio_init(AX25, &ax25_param);
- radio_set_frequency(tnc_settings.freq);
-
- kiss_init(tnc_settings.tnc_number, kiss_tx_cb, kiss_rx_cb);
-
- bt_spp_init();
-
- xTaskCreatePinnedToCore(tnc_task, "tnc task", 1024*4, 0, 2, &tnc_settings.tnc_task, 1);
- }
|