diff --git a/docs/aprs-debugging.adoc b/docs/aprs-debugging.adoc index dbdf345..6aa6bbe 100644 --- a/docs/aprs-debugging.adoc +++ b/docs/aprs-debugging.adoc @@ -3,11 +3,11 @@ ## Direwolf ```bash -rx_fm -f 434250000 -M fm -s 250000 -r 32000 -g 22 -d driver=rtlsdr - | direwolf -n 1 -D 1 -r 32000 -b 16 - +rx_fm -f 434250000 -M fm -s 250000 -r 48000 -g 22 -d driver=rtlsdr - | direwolf -n 1 -D 1 -r 48000 -b 16 - ``` ```bash -rtl_fm -f 434250000 -M fm -s 250k -r 32000 -g 22 - | direwolf -n 1 -D 1 -r 32000 -b 16 - +rtl_fm -f 434250000 -M fm -s 250k -r 48000 -g 22 - | direwolf -n 1 -D 1 -r 48000 -b 16 - ``` ## SigPlay @@ -19,5 +19,5 @@ rx_fm -f 434250000 -M fm -s 250000 -r 48000 -g 22 -d driver=rtlsdr - | ./aprs - ``` ```bash -rtl_fm -f 434250000 -M fm -s 250k -r 32000 -g 22 - | ./aprs - +rtl_fm -f 434250000 -M fm -s 250k -r 48000 -g 22 - | ./aprs - ``` diff --git a/src/codecs/aprs/aprs.c b/src/codecs/aprs/aprs.c index 1f881bd..09e093b 100644 --- a/src/codecs/aprs/aprs.c +++ b/src/codecs/aprs/aprs.c @@ -32,9 +32,8 @@ static void convert_degrees_to_dmh(long x, int8_t *degrees, uint8_t *minutes, ui } } -#include - -size_t aprs_generate_position_without_timestamp(uint8_t *payload, size_t length, telemetry_data *data, char symbol, char *comment) +size_t aprs_generate_position_without_timestamp(uint8_t *payload, size_t length, telemetry_data *data, + char symbol_table, char symbol, char *comment) { int8_t la_degrees, lo_degrees; uint8_t la_minutes, la_h_minutes, lo_minutes, lo_h_minutes; @@ -48,9 +47,10 @@ size_t aprs_generate_position_without_timestamp(uint8_t *payload, size_t length, return snprintf((char *) payload, length, - ("!%02d%02d.%02u%c/%03d%02u.%02u%c%c/A=%06ld/P%dS%dT%dV%d%s"), + ("!%02d%02d.%02u%c%c%03d%02u.%02u%c%c/A=%06ld/P%dS%dT%dV%d%s"), abs(la_degrees), la_minutes, la_h_minutes, la_degrees > 0 ? 'N' : 'S', + symbol_table, abs(lo_degrees), lo_minutes, lo_h_minutes, lo_degrees > 0 ? 'E' : 'W', symbol, diff --git a/src/codecs/aprs/aprs.h b/src/codecs/aprs/aprs.h index 824bfdb..8def542 100644 --- a/src/codecs/aprs/aprs.h +++ b/src/codecs/aprs/aprs.h @@ -7,6 +7,7 @@ #include "gps.h" #include "telemetry.h" -size_t aprs_generate_position_without_timestamp(uint8_t *payload, size_t length, telemetry_data *data, char symbol, char *comment); +size_t aprs_generate_position_without_timestamp(uint8_t *payload, size_t length, telemetry_data *data, + char symbol_table, char symbol, char *comment); #endif diff --git a/src/codecs/ax25/ax25.c b/src/codecs/ax25/ax25.c index baab862..bc6f3de 100644 --- a/src/codecs/ax25/ax25.c +++ b/src/codecs/ax25/ax25.c @@ -14,7 +14,6 @@ static inline uint16_t ax25_calculate_crc_for_bit(uint16_t crc, bool bit) // If XOR result from above has lsb set if (temp & 0x0001U) { - // Shift 16-bit CRC one bit to the right result ^= 0x8408U; } @@ -24,7 +23,7 @@ static inline uint16_t ax25_calculate_crc_for_bit(uint16_t crc, bool bit) static inline uint16_t ax25_calculate_crc_for_byte(uint16_t crc, uint8_t byte) { uint8_t temp = byte; - for (int i = 0; i < 8; i++, byte >>= 1U) { + for (int i = 0; i < 8; i++, temp >>= 1U) { bool bit = ((temp & 1U) == 1U) ? true : false; crc = ax25_calculate_crc_for_bit(crc, bit); } @@ -109,7 +108,8 @@ size_t ax25_encode_packet_aprs(char *source, uint8_t source_ssid, char *destinat size_t info_length = strlen(information_field); strcpy(header_end->information_field, information_field); - uint16_t crc = ax25_calculate_crc(14 + digipeater_addresses_length + 2 + info_length, actual_data_start); + size_t crc_length = 14 + digipeater_addresses_length + 2 + info_length; + uint16_t crc = ax25_calculate_crc(crc_length, actual_data_start); ax25_packet_footer *footer = (ax25_packet_footer *) (((uint8_t *) header_end->information_field) + info_length); diff --git a/src/codecs/bell/bell.c b/src/codecs/bell/bell.c index f0f82c5..83161ed 100644 --- a/src/codecs/bell/bell.c +++ b/src/codecs/bell/bell.c @@ -131,25 +131,20 @@ int8_t bell_encoder_next_tone(fsk_encoder *encoder) } bool bit = (bell->current_byte >> bell->current_bit_index) & 1U; - bool stuff_bit = false; if (bit) { + bell->bit_stuffing_counter++; if (bell->bit_stuffing_counter == 5) { + int8_t previous_tone_index = bell->current_tone_index; bell_encoder_toggle_tone(encoder); bell->bit_stuffing_counter = 0; - stuff_bit = true; - } else { - bell->bit_stuffing_counter++; + return previous_tone_index; } } else { bell_encoder_toggle_tone(encoder); bell->bit_stuffing_counter = 0; } - if (stuff_bit) { - return bell->current_tone_index; - } - bell->current_bit_index = (bell->current_bit_index + 1) % 8; if (bell->current_bit_index == 0) { diff --git a/src/config.h b/src/config.h index 3b834b0..3196a25 100644 --- a/src/config.h +++ b/src/config.h @@ -36,13 +36,36 @@ #define FSQ_CALLSIGN_TO "N0CALL" #define FSQ_COMMAND ' ' +/** + * APRS SSID: + * + * 0 Your primary station usually fixed and message capable + * 1 generic additional station, digi, mobile, wx, etc + * 2 generic additional station, digi, mobile, wx, etc + * 3 generic additional station, digi, mobile, wx, etc + * 4 generic additional station, digi, mobile, wx, etc + * 5 Other networks (Dstar, Iphones, Androids, Blackberry's etc) + * 6 Special activity, Satellite ops, camping or 6 meters, etc + * 7 walkie talkies, HT's or other human portable + * 8 boats, sailboats, RV's or second main mobile + * 9 Primary Mobile (usually message capable) + * A internet, Igates, echolink, winlink, AVRS, APRN, etc + * B balloons, aircraft, spacecraft, etc + * C APRStt, DTMF, RFID, devices, one-way trackers*, etc + * D Weather stations + * E Truckers or generally full time drivers + * F generic additional station, digi, mobile, wx, etc + */ + #define APRS_CALLSIGN "OH3BHX" -#define APRS_SSID 13 -#define APRS_SYMBOL 'O' -#define APRS_COMMENT "Testing 123" +#define APRS_SSID 'B' +// See APRS symbol table documentation in: http://www.aprs.org/symbols/symbolsX.txt +#define APRS_SYMBOL_TABLE '/' // '/' denotes primary and '\\' denotes alternate APRS symbol table +#define APRS_SYMBOL '[' +#define APRS_COMMENT " RS41ng custom radiosonde firmware testing" #define APRS_RELAYS "WIDE1-1,WIDE2-1" #define APRS_DESTINATION "APZ41N" -#define APRS_DESTINATION_SSID 0 +#define APRS_DESTINATION_SSID '0' #define PAIR_COUNT 4 // max. 6 (12 characters WWL) #define RTTY_7BIT 1 // if 0 --> 5 bits diff --git a/src/hal/delay.c b/src/hal/delay.c index 706cbf4..ad96d51 100644 --- a/src/hal/delay.c +++ b/src/hal/delay.c @@ -18,7 +18,7 @@ void delay_init() RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); - tim_init.TIM_Prescaler = 192 - 1; + tim_init.TIM_Prescaler = 24 - 1; tim_init.TIM_CounterMode = TIM_CounterMode_Up; tim_init.TIM_Period = 0; tim_init.TIM_ClockDivision = TIM_CKD_DIV1; @@ -30,8 +30,8 @@ void delay_init() NVIC_InitTypeDef nvic_init; nvic_init.NVIC_IRQChannel = TIM3_IRQn; - nvic_init.NVIC_IRQChannelPreemptionPriority = 2; - nvic_init.NVIC_IRQChannelSubPriority = 2; + nvic_init.NVIC_IRQChannelPreemptionPriority = 0; + nvic_init.NVIC_IRQChannelSubPriority = 1; nvic_init.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init); @@ -41,7 +41,7 @@ void delay_init() void delay_us(uint16_t us) { TIM_Cmd(TIM3, DISABLE); - TIM_SetAutoreload(TIM3, us / 8); + TIM_SetAutoreload(TIM3, us); TIM_SetCounter(TIM3, 0); TIM_Cmd(TIM3, ENABLE); done = false; diff --git a/src/hal/pwm.c b/src/hal/pwm.c index fc2271a..49b0678 100644 --- a/src/hal/pwm.c +++ b/src/hal/pwm.c @@ -5,6 +5,7 @@ #include #include "pwm.h" +#include "log.h" uint16_t pwm_timer_dma_buffer[PWM_TIMER_DMA_BUFFER_SIZE]; @@ -28,7 +29,7 @@ void pwm_data_timer_init() tim_init.TIM_Prescaler = 2 - 1; // tick every 1/12000000 s tim_init.TIM_CounterMode = TIM_CounterMode_Up; - tim_init.TIM_Period = 10000 - 1 - 55; // update every 1/1200 s + tim_init.TIM_Period = 10000 - 1; // update every 1/1200 s tim_init.TIM_ClockDivision = TIM_CKD_DIV1; tim_init.TIM_RepetitionCounter = 0; @@ -91,7 +92,7 @@ void pwm_timer_init(uint32_t frequency_hz_100) // TIM_SelectOCxM(TIM15, TIM_Channel_2, TIM_OCMode_PWM1); // TIM_CCxCmd(TIM15, TIM_Channel_2, TIM_CCx_Enable); - // The following make transitions smooth + // The following settings make transitions between generated frequencies smooth TIM_ARRPreloadConfig(TIM15, ENABLE); TIM_OC2PreloadConfig(TIM15, TIM_OCPreload_Enable); @@ -146,8 +147,6 @@ void pwm_dma_init() NVIC_Init(&nvic_init); } -#include "log.h" - void pwm_dma_start() { //pwm_dma_init_channel(); @@ -177,14 +176,10 @@ void DMA1_Channel2_IRQHandler(void) if (DMA_GetITStatus(DMA1_IT_HT2)) { DMA_ClearITPendingBit(DMA1_IT_HT2); pwm_handle_dma_transfer_half(PWM_TIMER_DMA_BUFFER_SIZE, pwm_timer_dma_buffer); - //if (length < PWM_TIMER_DMA_BUFFER_SIZE / 2) { - //} } if (DMA_GetITStatus(DMA1_IT_TC2)) { DMA_ClearITPendingBit(DMA1_IT_TC2); pwm_handle_dma_transfer_full(PWM_TIMER_DMA_BUFFER_SIZE, pwm_timer_dma_buffer); - //if (length < PWM_TIMER_DMA_BUFFER_SIZE / 2) { - //} } } @@ -215,15 +210,13 @@ inline uint16_t pwm_calculate_period(uint32_t frequency_hz_100) return (uint16_t) (((100.0f * 1000000.0f) / (frequency_hz_100 * 2.0f))) - 1; } -inline void pwm_timer_set_frequency(uint32_t frequency_hz_100) +inline void pwm_timer_set_frequency(uint32_t pwm_period) { - uint16_t period = pwm_calculate_period(frequency_hz_100); - // TIM_CtrlPWMOutputs(TIM15, DISABLE); // TIM_Cmd(TIM15, DISABLE); - TIM_SetAutoreload(TIM15, period); - // TIM_SetCompare2(TIM15, period / 2); + TIM_SetAutoreload(TIM15, pwm_period); + // TIM_SetCompare2(TIM15, pwm_period / 2); // TIM_Cmd(TIM15, ENABLE); // TIM_CtrlPWMOutputs(TIM15, ENABLE); diff --git a/src/hal/system.c b/src/hal/system.c index 83910a9..5a043c4 100644 --- a/src/hal/system.c +++ b/src/hal/system.c @@ -50,6 +50,8 @@ static void rcc_init() FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_0); + // TODO: Check what the delay timer TIM3 settings really should be and WTF the clock tick really is!?!?!? + RCC_HCLKConfig(RCC_SYSCLK_Div1); // Was: RCC_SYSCLK_Div4 RCC_PCLK2Config(RCC_HCLK_Div1); // Was: 4 RCC_PCLK1Config(RCC_HCLK_Div1); // Was: 2 @@ -221,6 +223,22 @@ void system_scheduler_timer_init() TIM_Cmd(TIM4, ENABLE); } +void system_disable_tick() +{ + TIM_Cmd(TIM4, DISABLE); + NVIC_DisableIRQ(TIM4_IRQn); + TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE); + TIM_ClearITPendingBit(TIM4, TIM_IT_Update); +} + +void system_enable_tick() +{ + TIM_ClearITPendingBit(TIM4, TIM_IT_Update); + TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); + NVIC_EnableIRQ(TIM4_IRQn); + TIM_Cmd(TIM4, ENABLE); +} + void system_set_green_led(bool enabled) { if (enabled) { diff --git a/src/hal/system.h b/src/hal/system.h index 4ade68a..b7fb681 100644 --- a/src/hal/system.h +++ b/src/hal/system.h @@ -10,6 +10,8 @@ void system_init(); uint32_t system_get_tick(); +void system_disable_tick(); +void system_enable_tick(); void system_disable_irq(); void system_enable_irq(); void system_set_green_led(bool enabled); diff --git a/src/radio.c b/src/radio.c index a1effab..34da41d 100644 --- a/src/radio.c +++ b/src/radio.c @@ -5,6 +5,7 @@ #include "telemetry.h" #include "log.h" #include "hal/system.h" +#include "hal/delay.h" #include "hal/spi.h" #include "hal/pwm.h" #include "hal/usart_gps.h" @@ -47,11 +48,13 @@ typedef struct _radio_transmit_entry { payload_encoder *payload_encoder; fsk_encoder_api *fsk_encoder_api; - jtencode_mode_type jtencode_mode_type; + jtencode_mode_type jtencode_mode_type; fsk_encoder fsk_encoder; } radio_transmit_entry; +static bool si4032_use_dma = false; + static volatile bool radio_transmission_active = false; static volatile bool radio_transmission_finished = false; static volatile radio_transmit_entry *radio_current_transmit_entry = NULL; @@ -75,6 +78,8 @@ static volatile uint32_t radio_symbol_count_loop = 0; static volatile bool radio_dma_transfer_active = false; static volatile int8_t radio_dma_transfer_stop_after_counter = -1; +static volatile bool radio_manual_transmit_active = false; + uint8_t radio_current_payload[RADIO_PAYLOAD_MAX_LENGTH]; size_t radio_current_payload_length = 0; @@ -90,14 +95,13 @@ telemetry_data current_telemetry_data; uint8_t aprs_packet[RADIO_PAYLOAD_MAX_LENGTH]; static volatile uint32_t start_tick = 0, end_tick = 0; -static volatile bool freq_state = false; static size_t radio_fill_pwm_buffer(size_t offset, size_t length, uint16_t *buffer); size_t radio_aprs_encode(uint8_t *payload, size_t length, telemetry_data *telemetry_data) { aprs_generate_position_without_timestamp( - aprs_packet, sizeof(aprs_packet), telemetry_data, APRS_SYMBOL, APRS_COMMENT); + aprs_packet, sizeof(aprs_packet), telemetry_data, APRS_SYMBOL_TABLE, APRS_SYMBOL, APRS_COMMENT); log_debug("aprs: %s\n", aprs_packet); @@ -111,6 +115,7 @@ payload_encoder radio_aprs_payload_encoder = { size_t radio_ft8_encode(uint8_t *payload, size_t length, telemetry_data *telemetry_data) { + // TODO: Encode locator for FT8 return snprintf((char *) payload, length, "%s %s", FT8_CALLSIGN, FT8_LOCATOR); } @@ -120,6 +125,7 @@ payload_encoder radio_ft8_payload_encoder = { size_t radio_wspr_encode(uint8_t *payload, size_t length, telemetry_data *telemetry_data) { + // TODO: Encode locator for WSPR return snprintf((char *) payload, length, ""); } @@ -127,7 +133,7 @@ payload_encoder radio_wspr_payload_encoder = { .encode = radio_wspr_encode, }; -#define RADIO_TRANSMIT_ENTRY_COUNT 3 +#define RADIO_TRANSMIT_ENTRY_COUNT 1 static radio_transmit_entry radio_transmit_schedule[] = { { @@ -139,7 +145,7 @@ static radio_transmit_entry radio_transmit_schedule[] = { .payload_encoder = &radio_aprs_payload_encoder, .fsk_encoder_api = &bell_fsk_encoder_api, }, - { +/* { .radio_type = RADIO_TYPE_SI5351, .data_mode = RADIO_DATA_MODE_FT8, .frequency = RADIO_SI5351_TX_FREQUENCY_FT8, @@ -156,7 +162,7 @@ static radio_transmit_entry radio_transmit_schedule[] = { .payload_encoder = &radio_wspr_payload_encoder, .fsk_encoder_api = &jtencode_fsk_encoder_api, .jtencode_mode_type = JTENCODE_MODE_WSPR, - }, + },*/ }; static bool radio_start_transmit_si4032(radio_transmit_entry *entry) @@ -180,7 +186,9 @@ static bool radio_start_transmit_si4032(radio_transmit_entry *entry) frequency_offset = 0; modulation_type = SI4032_MODULATION_TYPE_FSK; use_direct_mode = true; - radio_fill_pwm_buffer(0, PWM_TIMER_DMA_BUFFER_SIZE, pwm_timer_dma_buffer); + if (si4032_use_dma) { + radio_fill_pwm_buffer(0, PWM_TIMER_DMA_BUFFER_SIZE, pwm_timer_dma_buffer); + } break; default: return false; @@ -203,10 +211,17 @@ static bool radio_start_transmit_si4032(radio_transmit_entry *entry) switch (entry->data_mode) { case RADIO_DATA_MODE_APRS: - // TODO: Set up DMA for APRS - radio_dma_transfer_active = true; - radio_dma_transfer_stop_after_counter = -1; - pwm_dma_start(); + if (si4032_use_dma) { + radio_dma_transfer_active = true; + radio_dma_transfer_stop_after_counter = -1; + system_disable_tick(); + pwm_dma_start(); + } else { + log_info("Si4032 manual TX\n"); + radio_manual_transmit_active = true; + } + break; + default: break; } @@ -269,7 +284,7 @@ static bool radio_start_transmit(radio_transmit_entry *entry) break; case RADIO_DATA_MODE_APRS: // TODO: make bell tones and flag field count configurable - bell_encoder_new(&entry->fsk_encoder, entry->symbol_rate, 20, bell202_tones); + bell_encoder_new(&entry->fsk_encoder, entry->symbol_rate, BELL_FLAG_FIELD_COUNT_1200, bell202_tones); radio_current_symbol_rate = entry->fsk_encoder_api->get_symbol_rate(&entry->fsk_encoder); entry->fsk_encoder_api->get_tones(&entry->fsk_encoder, &radio_current_fsk_tone_count, &radio_current_fsk_tones); @@ -284,6 +299,7 @@ static bool radio_start_transmit(radio_transmit_entry *entry) case RADIO_DATA_MODE_FSQ_3: case RADIO_DATA_MODE_FSQ_4_5: case RADIO_DATA_MODE_FSQ_6: + // TODO: Encode WSPR locator jtencode_encoder_new(&entry->fsk_encoder, entry->jtencode_mode_type, WSPR_CALLSIGN, WSPR_LOCATOR, WSPR_DBM, FSQ_CALLSIGN_FROM, FSQ_CALLSIGN_TO, FSQ_COMMAND); radio_current_symbol_delay_ms_100 = entry->fsk_encoder_api->get_symbol_delay(&entry->fsk_encoder); @@ -294,27 +310,27 @@ static bool radio_start_transmit(radio_transmit_entry *entry) return false; } + // USART interrupts may interfere with transmission timing + usart_gps_enable(false); + switch (entry->radio_type) { case RADIO_TYPE_SI4032: success = radio_start_transmit_si4032(entry); - if (!success) { - return false; - } break; case RADIO_TYPE_SI5351: success = radio_start_transmit_si5351(entry); - if (!success) { - return false; - } break; default: return false; } - log_info("TX enabled\n"); + if (!success) { + usart_gps_enable(true); + // TODO: stop transmit here + return false; + } - // USART interrupts may interfere with transmission timing - usart_gps_enable(false); + log_info("TX enabled\n"); system_set_red_led(true); @@ -336,9 +352,12 @@ static bool radio_stop_transmit_si4032(radio_transmit_entry *entry) break; case RADIO_DATA_MODE_APRS: use_direct_mode = true; + if (si4032_use_dma) { + system_enable_tick(); + } break; default: - return false; + break; } if (use_direct_mode) { @@ -353,6 +372,16 @@ static bool radio_stop_transmit_si4032(radio_transmit_entry *entry) si4032_inhibit_tx(); + switch (entry->data_mode) { + case RADIO_DATA_MODE_APRS: + if (si4032_use_dma) { + system_enable_tick(); + } + break; + default: + break; + } + return true; } @@ -384,20 +413,17 @@ static bool radio_stop_transmit(radio_transmit_entry *entry) switch (entry->radio_type) { case RADIO_TYPE_SI4032: success = radio_stop_transmit_si4032(entry); - if (!success) { - return false; - } break; case RADIO_TYPE_SI5351: success = radio_stop_transmit_si5351(entry); - if (!success) { - return false; - } break; default: return false; } + radio_reset_transmit_state(); + + radio_manual_transmit_active = false; radio_dma_transfer_active = false; switch (entry->data_mode) { @@ -423,12 +449,10 @@ static bool radio_stop_transmit(radio_transmit_entry *entry) return false; } - radio_reset_transmit_state(); - usart_gps_enable(true); system_set_red_led(false); - return true; + return success; } static uint32_t radio_next_symbol_si4032(radio_transmit_entry *entry) @@ -444,8 +468,7 @@ static uint32_t radio_next_symbol_si4032(radio_transmit_entry *entry) return 0; } - fsk_tone *tone = &radio_current_fsk_tones[next_tone_index]; - return tone->frequency_hz_100; + return radio_current_fsk_tones[next_tone_index].frequency_hz_100; } default: return 0; @@ -479,7 +502,8 @@ static bool radio_transmit_symbol_si5351(radio_transmit_entry *entry) log_trace("Tone: %d\n", next_tone_index); - uint64_t frequency = ((uint64_t) entry->frequency) * 100UL + (next_tone_index * radio_current_tone_spacing_hz_100); + uint64_t frequency = + ((uint64_t) entry->frequency) * 100UL + (next_tone_index * radio_current_tone_spacing_hz_100); radio_si5351_freq = frequency; radio_si5351_state_change = true; break; @@ -520,7 +544,7 @@ static void radio_next_transmit_entry() void radio_handle_timer_tick() { - if (radio_dma_transfer_active) { + if (radio_dma_transfer_active || radio_manual_transmit_active) { return; } @@ -541,6 +565,8 @@ void radio_handle_timer_tick() // TODO: implement time sync } +uint16_t symbol_delay = 823; // -> good around ~823 for a tight loop + void radio_handle_main_loop() { if (radio_post_transmit_delay_counter == 0) { @@ -548,21 +574,54 @@ void radio_handle_main_loop() log_info("Battery: %d mV\n", current_telemetry_data.battery_voltage_millivolts); log_info("Internal temperature: %ld C*100\n", current_telemetry_data.internal_temperature_celsius_100); log_info("Time: %02d:%02d:%02d\n", - current_telemetry_data.gps.hours, current_telemetry_data.gps.minutes, current_telemetry_data.gps.seconds); + current_telemetry_data.gps.hours, current_telemetry_data.gps.minutes, + current_telemetry_data.gps.seconds); log_info("Fix: %d, Sats: %d, OK packets: %d, Bad packets: %d\n", - current_telemetry_data.gps.fix, current_telemetry_data.gps.sats_raw, current_telemetry_data.gps.ok_packets, current_telemetry_data.gps.bad_packets); + current_telemetry_data.gps.fix, current_telemetry_data.gps.sats_raw, + current_telemetry_data.gps.ok_packets, current_telemetry_data.gps.bad_packets); log_info("Lat: %ld *1M, Lon: %ld *1M, Alt: %ld m\n", - current_telemetry_data.gps.lat_raw / 10, current_telemetry_data.gps.lon_raw / 10, (current_telemetry_data.gps.alt_raw / 1000) * 3280 / 1000); + current_telemetry_data.gps.lat_raw / 10, current_telemetry_data.gps.lon_raw / 10, + (current_telemetry_data.gps.alt_raw / 1000) * 3280 / 1000); radio_post_transmit_delay_counter = RADIO_POST_TRANSMIT_DELAY * SYSTEM_SCHEDULER_TIMER_TICKS_PER_SECOND / 1000; radio_start_transmit_entry = radio_current_transmit_entry; } if (radio_si4032_state_change) { - radio_si4032_state_change = false; - pwm_timer_set_frequency(radio_si4032_freq); - radio_symbol_count_loop++; - freq_state = !freq_state; + if (radio_manual_transmit_active) { + // TODO: Refactor this code for proper handling of APRS + fsk_encoder_api *fsk_encoder_api = radio_current_transmit_entry->fsk_encoder_api; + fsk_encoder *fsk_enc = &radio_current_transmit_entry->fsk_encoder; + log_info("Si4032 manual TX start: %d\n", symbol_delay); + system_disable_tick(); + int8_t tone_index = 0; + uint32_t pwm_periods[2]; + pwm_periods[0] = pwm_calculate_period(radio_current_fsk_tones[0].frequency_hz_100); + pwm_periods[1] = pwm_calculate_period(radio_current_fsk_tones[1].frequency_hz_100); + switch (radio_current_transmit_entry->data_mode) { + case RADIO_DATA_MODE_APRS: + do { + // radio_si4032_state_change = false; + pwm_timer_set_frequency(pwm_periods[tone_index]); + // radio_symbol_count_loop++; + delay_us(symbol_delay); + tone_index = fsk_encoder_api->next_tone(fsk_enc); + } while (tone_index >= 0); + //} while (radio_transmit_symbol(radio_current_transmit_entry)); + + radio_si4032_state_change = false; + radio_transmission_finished = true; + break; + default: + break; + } + system_enable_tick(); + //symbol_delay += 1; + } else { + radio_si4032_state_change = false; + pwm_timer_set_frequency(radio_si4032_freq); + radio_symbol_count_loop++; + } return; } @@ -696,7 +755,10 @@ void radio_init() radio_current_transmit_entry = &radio_transmit_schedule[radio_current_transmit_entry_index]; - pwm_data_timer_init(); pwm_timer_init(100 * 100); - pwm_dma_init(); + + if (si4032_use_dma) { + pwm_data_timer_init(); + pwm_dma_init(); + } } diff --git a/tests/bell_test.c b/tests/bell_test.c index b5a17f7..d8fd388 100644 --- a/tests/bell_test.c +++ b/tests/bell_test.c @@ -2,6 +2,10 @@ #include #include "codecs/bell/bell.h" +#include "codecs/aprs/aprs.h" +#include "codecs/ax25/ax25.h" +#include "telemetry.h" +#include "config.h" int main(void) { @@ -9,10 +13,29 @@ int main(void) bell_encoder_new(&fsk_encoder, 1200, 0, bell202_tones); - // aprs_generate_position_without_timestamp( - // aprs_packet, sizeof(aprs_packet), telemetry_data, APRS_SYMBOL, APRS_COMMENT); - // ax25_encode_packet_aprs(APRS_CALLSIGN, APRS_SSID, "APZ41N", 0, "", - // (char *) aprs_packet, length, payload); + telemetry_data telemetry; + memset(&telemetry, 0, sizeof(telemetry_data)); + + uint8_t aprs_packet[256]; + size_t aprs_length = aprs_generate_position_without_timestamp( + aprs_packet, sizeof(aprs_packet), &telemetry, APRS_SYMBOL_TABLE, APRS_SYMBOL, APRS_COMMENT); + + uint8_t payload[256]; + size_t payload_length = ax25_encode_packet_aprs(APRS_CALLSIGN, APRS_SSID, APRS_DESTINATION, APRS_DESTINATION_SSID, APRS_RELAYS, + (char *) aprs_packet, aprs_length, payload); + + printf("Full payload length: %d\n", payload_length); + + for (int i = 0; i < payload_length; i++) { + uint8_t c = payload[i]; + if (c >= 0x20 && c <= 0x7e) { + printf("%c", c); + } else { + printf(" [%02X] ", c); + } + } + + printf("\n"); //uint8_t payload[] = { 0x7e, 0x82, 0xa0, 0xb4, 'h', 'b', 0x9c, 0x00, 0x7e}; // 0x7e: 0 1 1 1 1 1 1 0 @@ -20,7 +43,7 @@ int main(void) // 0xa0: 0 0 0 0 0 1 0 1 // 0xb4: 0 0 1 0 1 1 0 1 - uint8_t payload[] = { 0x7e, 0x3f, 0x7f }; + //uint8_t payload[] = { 0x7e, 0x3f, 0x7f }; // 1 1 1 1 1 1 0 0 // N N N N N S N C C