From 7a38e2994963635ea7b5ec6811710d98cb4efdc4 Mon Sep 17 00:00:00 2001 From: sjlongland Date: Tue, 6 Oct 2015 10:03:57 +0000 Subject: [PATCH] sm1000_main: First stab at a time-out timer. This needs calibration, but basically it cuts transmission after a fixed period, giving warning beeps in the time just prior to timeout. For now it is disabled by default, and the timing for now is way off. git-svn-id: https://svn.code.sf.net/p/freetel/code@2425 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/stm32/Makefile | 1 + codec2-dev/stm32/src/sm1000_main.c | 195 ++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/codec2-dev/stm32/Makefile b/codec2-dev/stm32/Makefile index 94cd335a..a2a0248d 100644 --- a/codec2-dev/stm32/Makefile +++ b/codec2-dev/stm32/Makefile @@ -669,6 +669,7 @@ src/sfx.c \ src/sounds.c \ src/morse.c \ src/menu.c \ +src/tot.c \ src/sm1000_leds_switches.c \ ../src/fifo.c \ src/debugblinky.c \ diff --git a/codec2-dev/stm32/src/sm1000_main.c b/codec2-dev/stm32/src/sm1000_main.c index 0ed856a8..3f3c13a2 100644 --- a/codec2-dev/stm32/src/sm1000_main.c +++ b/codec2-dev/stm32/src/sm1000_main.c @@ -43,6 +43,7 @@ #include "sounds.h" #include "morse.h" #include "menu.h" +#include "tot.h" #define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES) @@ -60,6 +61,8 @@ struct switch_t sw_select; /*!< Switch driver for SELECT button */ struct switch_t sw_back; /*!< Switch driver for BACK button */ struct switch_t sw_ptt; /*!< Switch driver for PTT buttons */ +struct tot_t tot; /*!< Time-out timer */ + unsigned int announceTicker = 0; unsigned int menuLEDTicker = 0; unsigned int menuTicker = 0; @@ -71,6 +74,10 @@ unsigned int menuExit = 0; static struct prefs_t { /*! Serial number */ uint64_t serial; + /*! Time-out timer period, in seconds increment */ + uint16_t tot_period; + /*! Time-out timer warning period, in seconds increment */ + uint16_t tot_warn_period; /*! Menu frequency */ uint16_t menu_freq; /*! Menu speed */ @@ -254,6 +261,7 @@ int main(void) { } led_rt(LED_OFF); tone_reset(&tone_gen, 0, 0); + tot_reset(&tot); /* Try to load preferences from flash */ if (load_prefs() < 0) { @@ -263,8 +271,13 @@ int main(void) { prefs.menu_vol = 2; prefs.menu_speed = 60; /* 20 WPM */ prefs.menu_freq = 800; + prefs.tot_period = 0; /* Disable time-out timer */ + prefs.tot_warn_period = 15; } + /* Set up time-out timer */ + tot.tick_period = 600000; /* TODO: calibrate */ + /* Clear out switch states */ memset(&sw_select, 0, sizeof(sw_select)); memset(&sw_back, 0, sizeof(sw_back)); @@ -288,6 +301,9 @@ int main(void) { switch_update(&sw_ptt, (switch_ptt() || (!ext_ptt())) ? 1 : 0); + /* Update time-out timer state */ + tot_update(&tot); + /* Process menu */ if (!menuTicker) { if (menu.stack_depth > 0) { @@ -404,7 +420,8 @@ int main(void) { menuLEDTicker = MENU_LED_PERIOD; } } - else if (switch_ptt() || (ext_ptt() == 0)) { + else if ((switch_ptt() || (ext_ptt() == 0)) && + (!(tot.event & TOT_EVT_TIMEOUT))) { /* Transmit -------------------------------------------------------------------------*/ @@ -414,6 +431,19 @@ int main(void) { morse_play(&morse_player, NULL); } + /* Handle the time-out timer events */ + if (!tot.event) { + /* Time-out timer has not yet started */ + if (prefs.tot_period) + tot_start(&tot, prefs.tot_period, + prefs.tot_warn_period); + } else if (tot.event & TOT_EVT_WARN_NEXT) { + /* Re-set warning flag */ + tot.event &= ~TOT_EVT_WARN_NEXT; + /* Schedule a click tone */ + sfx_play(&sfx_player, sound_click); + } + /* ADC2 is the SM1000 microphone, DAC1 is the modulator signal we send to radio tx */ if (adc2_read(&adc16k[FDMDV_OS_TAPS_16K], n_samples_16k) == 0) { @@ -467,6 +497,23 @@ int main(void) { /* Receive --------------------------------------------------------------------------*/ + /* Did we just come out of transmit? */ + if (tot.event) { + if (tot.event & TOT_EVT_TIMEOUT) { + /* + * Time-out reached, play time-out tune then reset + * the timeout flag to acknowledge. + */ + sfx_play(&sfx_player, sound_death_march); + tot.event &= ~TOT_EVT_TIMEOUT; + } + + /* Reset the timeout timer */ + if (switch_ptt() || !ext_ptt()) { + tot_reset(&tot); + } + } + not_cptt(1); led_ptt(0); /* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */ @@ -576,6 +623,7 @@ void SysTick_Handler(void) if (announceTicker > 0) { announceTicker--; } + tot_tick(&tot); } /* ---------------------------- Menu data --------------------------- */ @@ -640,9 +688,11 @@ static const struct menu_item_t menu_root = { /* Child declarations */ static const struct menu_item_t menu_op_mode; +static const struct menu_item_t menu_tot; static const struct menu_item_t menu_ui; static const struct menu_item_t const* menu_root_children[] = { &menu_op_mode, + &menu_tot, &menu_ui, }; @@ -760,6 +810,149 @@ static void menu_op_mode_cb(struct menu_t* const menu, uint32_t event) } +/* Time-out timer menu forward declarations */ +static struct menu_item_t const* menu_tot_children[]; +/* Operation mode menu */ +static const struct menu_item_t menu_tot = { + .label = "TOT", + .event_cb = menu_default_cb, + .children = menu_tot_children, + .num_children = 2, +}; +/* Children */ +static const struct menu_item_t menu_tot_time; +static const struct menu_item_t menu_tot_warn; +static struct menu_item_t const* menu_tot_children[] = { + &menu_tot_time, + &menu_tot_warn, +}; + +/* TOT time menu forward declarations */ +static void menu_tot_time_cb(struct menu_t* const menu, uint32_t event); +/* TOT time menu */ +static const struct menu_item_t menu_tot_time = { + .label = "TIME", + .event_cb = menu_tot_time_cb, + .children = NULL, + .num_children = 0, +}; + +/* Callback function */ +static void menu_tot_time_cb(struct menu_t* const menu, uint32_t event) +{ + uint8_t announce = 0; + + switch(event) { + case MENU_EVT_ENTERED: + sfx_play(&sfx_player, sound_startup); + /* Get the current period */ + menu->current = prefs.tot_period; + case MENU_EVT_RETURNED: + /* Shouldn't happen, but we handle it anyway */ + announce = 1; + break; + case MENU_EVT_NEXT: + sfx_play(&sfx_player, sound_click); + /* Adjust the frequency up by 50 Hz */ + if (prefs.tot_period < 600) + prefs.tot_period += 5; + announce = 1; + break; + case MENU_EVT_PREV: + sfx_play(&sfx_player, sound_click); + if (prefs.tot_period > 0) + prefs.tot_period -= 5; + announce = 1; + break; + case MENU_EVT_SELECT: + /* Play the "selected" tune and return. */ + sfx_play(&sfx_player, sound_startup); + prefs_changed = 1; + menu_leave(menu); + break; + case MENU_EVT_BACK: + /* Restore the mode and exit the menu */ + sfx_play(&sfx_player, sound_returned); + case MENU_EVT_EXIT: + prefs.tot_period = menu->current; + menu_leave(menu); + break; + default: + break; + } + + if (announce) { + /* Render the text, thankfully we don't need re-entrancy */ + static char period[5]; + snprintf(period, 4, "%d", prefs.tot_period); + /* Announce the period */ + morse_play(&morse_player, period); + } +}; + +/* TOT warning time menu forward declarations */ +static void menu_tot_warn_cb(struct menu_t* const menu, uint32_t event); +/* TOT warning time menu */ +static const struct menu_item_t menu_tot_warn = { + .label = "WARN", + .event_cb = menu_tot_warn_cb, + .children = NULL, + .num_children = 0, +}; + +/* Callback function */ +static void menu_tot_warn_cb(struct menu_t* const menu, uint32_t event) +{ + uint8_t announce = 0; + + switch(event) { + case MENU_EVT_ENTERED: + sfx_play(&sfx_player, sound_startup); + /* Get the current period */ + menu->current = prefs.tot_warn_period; + case MENU_EVT_RETURNED: + /* Shouldn't happen, but we handle it anyway */ + announce = 1; + break; + case MENU_EVT_NEXT: + sfx_play(&sfx_player, sound_click); + /* Adjust the frequency up by 50 Hz */ + if (prefs.tot_warn_period < 600) + prefs.tot_warn_period += 5; + announce = 1; + break; + case MENU_EVT_PREV: + sfx_play(&sfx_player, sound_click); + if (prefs.tot_warn_period > 0) + prefs.tot_warn_period -= 5; + announce = 1; + break; + case MENU_EVT_SELECT: + /* Play the "selected" tune and return. */ + sfx_play(&sfx_player, sound_startup); + prefs_changed = 1; + menu_leave(menu); + break; + case MENU_EVT_BACK: + /* Restore the mode and exit the menu */ + sfx_play(&sfx_player, sound_returned); + case MENU_EVT_EXIT: + prefs.tot_warn_period = menu->current; + menu_leave(menu); + break; + default: + break; + } + + if (announce) { + /* Render the text, thankfully we don't need re-entrancy */ + static char period[5]; + snprintf(period, 4, "%d", prefs.tot_period); + /* Announce the period */ + morse_play(&morse_player, period); + } +}; + /* UI menu forward declarations */ static struct menu_item_t const* menu_ui_children[]; /* Operation mode menu */ -- 2.25.1