\r
#define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES)\r
\r
+#define FIFTY_MS 50\r
+#define MAX_MODES 3\r
+#define ANALOG 0\r
+#define DV 1\r
+#define TONE 2\r
+\r
+#define SS_IDLE 0\r
+#define SS_DEBOUNCE_DOWN 1\r
+#define SS_WAIT_BUTTON_UP 2\r
+#define SS_DEBOUNCE_UP 3\r
+\r
+typedef struct {\r
+ int state;\r
+ int mode;\r
+} SWITCH_STATE;\r
+\r
+unsigned int downTicker;\r
+\r
+void SysTick_Handler(void);\r
+void iterate_select_state_machine(SWITCH_STATE *ss);\r
+\r
+#define SINE_SAMPLES 32\r
+\r
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz. Note samples\r
+ are 16 bit 2's complement, the DAC driver convertsto 12 bit\r
+ unsigned. */\r
+\r
+short aSine[] = {\r
+ -16, 6384, 12528, 18192, 23200, 27232, 30256, 32128,\r
+ 32752, 32128, 30256, 27232, 23152, 18192, 12528, 6384,\r
+ -16, -6416, -12560, -18224, -23184, -27264, -30288, -32160,\r
+ -32768, -32160, -30288, -27264, -23184, -18224, -12560, -6416\r
+};\r
+\r
int main(void) {\r
struct freedv *f;\r
short adc16k[FDMDV_OS_TAPS_16K+FREEDV_NSAMPLES_16K];\r
short dac16k[FREEDV_NSAMPLES_16K];\r
short adc8k[FREEDV_NSAMPLES];\r
short dac8k[FDMDV_OS_TAPS_8K+FREEDV_NSAMPLES];\r
- \r
- int nin, nout, i, analog_mode;\r
+ SWITCH_STATE ss;\r
+ int nin, nout, i;\r
\r
/* init all the drivers for various peripherals */\r
\r
+ SysTick_Config(SystemCoreClock/168000); /* 1 kHz SysTick */\r
sm1000_leds_switches_init();\r
dac_open(4*DAC_BUF_SZ);\r
adc_open(4*ADC_BUF_SZ);\r
for(i=0; i<FDMDV_OS_TAPS_8K; i++)\r
dac8k[i] = 0.0;\r
\r
- analog_mode = 1;\r
+ ss.state = SS_IDLE;\r
+ ss.mode = ANALOG;\r
\r
while(1) {\r
-\r
- if (switch_select()) {\r
- if (analog_mode)\r
- analog_mode = 0;\r
- else\r
- analog_mode = 1;\r
- }\r
+ \r
+ iterate_select_state_machine(&ss);\r
\r
if (switch_ptt()) {\r
\r
\r
fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES);\r
\r
- freedv_tx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);\r
- \r
- /* force analog bypass when select down */\r
- \r
- if (analog_mode) {\r
+ if (ss.mode == ANALOG) {\r
for(i=0; i<FREEDV_NSAMPLES; i++)\r
dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];\r
+ fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES); \r
+ dac1_write(dac16k, FREEDV_NSAMPLES_16K);\r
+ }\r
+ if (ss.mode == DV) {\r
+ freedv_tx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);\r
+ fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES); \r
+ dac1_write(dac16k, FREEDV_NSAMPLES_16K);\r
}\r
\r
- fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES); \r
-\r
- dac1_write(dac16k, FREEDV_NSAMPLES_16K);\r
+ if (ss.mode == TONE) {\r
+ while(dac1_write((short*)aSine, SINE_SAMPLES) == 0);\r
+ }\r
\r
led_ptt(1); led_rt(0); led_err(0); not_cptt(0);\r
GPIOE->ODR &= ~(1 << 3);\r
\r
/* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */\r
\r
- if (analog_mode) {\r
+ if (ss.mode == ANALOG) {\r
\r
/* force analog bypass when select down */\r
\r
nout = nin;\r
f->total_bit_errors = 0;\r
\r
-\r
if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], 2*nin) == 0) {\r
GPIOE->ODR = (1 << 3);\r
fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);\r
} /* while(1) ... */\r
}\r
\r
+/*\r
+ * SysTick Interrupt Handler\r
+ */\r
+\r
+void SysTick_Handler(void)\r
+{\r
+ if (downTicker > 0) {\r
+ downTicker--;\r
+ }\r
+}\r
+\r
+/* Select button state machine. Debounces switches and enables cycling\r
+ through ANALOG-DV-TONE modes */\r
+\r
+void iterate_select_state_machine(SWITCH_STATE *ss) {\r
+ int next_state;\r
+\r
+ next_state = ss->state;\r
+ switch(ss->state) {\r
+ case SS_IDLE:\r
+ if (switch_select()) {\r
+ downTicker = FIFTY_MS;\r
+ next_state = SS_DEBOUNCE_DOWN;\r
+ }\r
+ break;\r
+ case SS_DEBOUNCE_DOWN:\r
+ if (downTicker == 0) {\r
+ ss->mode++;\r
+ if (ss->mode >= MAX_MODES)\r
+ ss->mode = 0;\r
+ next_state = SS_WAIT_BUTTON_UP;\r
+ }\r
+ break;\r
+ case SS_WAIT_BUTTON_UP:\r
+ if (switch_select() == 0) {\r
+ downTicker = FIFTY_MS;\r
+ next_state = SS_DEBOUNCE_UP;\r
+ }\r
+ break;\r
+ case SS_DEBOUNCE_UP:\r
+ if (downTicker == 0) {\r
+ next_state = SS_IDLE;\r
+ }\r
+ break;\r
+ }\r
+ ss->state = next_state;\r
+}\r
+ \r