###################################################
-CFLAGS = -std=gnu99 -O3 --param max-unroll-times=200 -g -Wall -Tstm32_flash.ld -DSTM32F4XX -DCORTEX_M4
+CFLAGS = -std=gnu99 -g -Wall -Tstm32_flash.ld -DSTM32F4XX -DCORTEX_M4
CFLAGS += -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4
ifeq ($(FLOAT_TYPE), hard)
###################################################
-all: libstm32f4.a codec2_profile.elf fft_test.elf dac_ut.elf dac_play.elf adc_rec.elf pwm_ut.elf power_ut.elf fdmdv_profile.elf sm1000_leds_switches_ut.elf sm1000.elf
+all: libstm32f4.a codec2_profile.elf fft_test.elf dac_ut.elf dac_play.elf adc_rec.elf pwm_ut.elf fdmdv_profile.elf sm1000_leds_switches_ut.elf sm1000.elf adcdac_ut.elf
dl/$(PERIPHLIBZIP):
mkdir -p dl
src/dac_ut.c \
../src/fifo.c \
src/stm32f4_dac.c \
+src/debugblinky.c \
src/system_stm32f4xx.c \
src/startup_stm32f4xx.s \
src/init.c
dac_ut.elf: $(DAC_UT_SRCS)
$(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS)
+ADCDAC_UT_SRCS=\
+src/adcdac_ut.c \
+../src/fifo.c \
+src/stm32f4_dac.c \
+src/stm32f4_adc.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+adcdac_ut.elf: $(ADCDAC_UT_SRCS)
+ $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS)
+
DAC_PLAY_SRCS=\
src/dac_play.c \
../src/fifo.c \
gdb_stdio.c \
src/stm32f4_dac.c \
+src/debugblinky.c \
src/system_stm32f4xx.c \
src/startup_stm32f4xx.s \
src/init.c
../src/fifo.c \
gdb_stdio.c \
src/stm32f4_adc.c \
+src/debugblinky.c \
src/system_stm32f4xx.c \
src/startup_stm32f4xx.s \
src/init.c
../src/fifo.c \
src/stm32f4_adc.c \
src/stm32f4_dac.c \
+src/debugblinky.c \
src/system_stm32f4xx.c \
src/startup_stm32f4xx.s \
src/init.c \
src/sm1000_main.c \
src/sm1000_leds_switches.c \
../src/fifo.c \
-src/stm32f4_adc.c \
-src/stm32f4_dac.c \
+src/debugblinky.c \
src/system_stm32f4xx.c \
src/startup_stm32f4xx.s \
src/init.c
SM1000_SRCS += $(CODEC2_SRCS)
-sm1000.elf: $(SM1000_SRCS)
- $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+src/stm32f4_dac.o: src/stm32f4_dac.c
+ $(CC) $(CFLAGS) $^ -c -o $@
+
+src/stm32f4_adc.o: src/stm32f4_adc.c
+ $(CC) $(CFLAGS) $^ -c -o $@
+
+sm1000.elf: $(SM1000_SRCS) src/stm32f4_dac.o src/stm32f4_adc.o
+ $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
clean:
rm -f *.o
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ FILE........: debugblinky.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 12 August 2014
+
+ Configures GPIO pins used for debug blinkies
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2014 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DEBUGBLINKY__
+#define __DEBUGBLINKY__
+
+void init_debug_blinky(void);
+
+#endif
#ifndef __STM32F4_ADC__
#define __STM32F4_ADC__
-void adc_open(void);
+#define ADC_BUF_SZ 320
+
+void adc_open(int fifo_sz);
int adc1_read(short buf[], int n); /* ADC1 Pin PA1 */
int adc2_read(short buf[], int n); /* ADC2 Pin PA2 */
#include "gdb_stdio.h"\r
\r
#define REC_TIME_SECS 10\r
-#define N 2000\r
+#define N (ADC_BUF_SZ*6)\r
#define FS 16000\r
\r
int main(void){\r
FILE *frec;\r
int i, bufs;\r
\r
- adc_open();\r
+ adc_open(2*N);\r
\r
frec = fopen("stm_out.raw", "wb");\r
if (frec == NULL) {\r
for(i=0; i<bufs; i++) {\r
while(adc1_read(buf, N) == -1);\r
fwrite(buf, sizeof(short), N, frec); \r
- printf(".");\r
+ printf(".\n");\r
}\r
fclose(frec);\r
printf("Finished!\n");\r
--- /dev/null
+/*---------------------------------------------------------------------------*\\r
+\r
+ FILE........: adcdac_ut.c\r
+ AUTHOR......: David Rowe\r
+ DATE CREATED: May 31 201310 Aug 2014\r
+\r
+ Echoes ADC2 input (mic) to DAC2 output (speaker) on SM1000.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+ Copyright (C) 2013 David Rowe\r
+\r
+ All rights reserved.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License version 2.1, as\r
+ published by the Free Software Foundation. This program is\r
+ distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\r
+ License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include <assert.h>\r
+#include "stm32f4_dac.h"\r
+#include "stm32f4_adc.h"\r
+\r
+#define SINE_SAMPLES 32\r
+\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
+ short buf[SINE_SAMPLES];\r
+\r
+ dac_open(4*DAC_BUF_SZ);\r
+ adc_open(4*ADC_BUF_SZ);\r
+\r
+ while (1) {\r
+\r
+ /* keep DAC FIFOs topped up */\r
+\r
+ while(adc1_read(buf, SINE_SAMPLES) == -1);\r
+ dac2_write(buf, SINE_SAMPLES);\r
+ }\r
+ \r
+}\r
+\r
AUTHOR......: David Rowe\r
DATE CREATED: 1 June 2013\r
\r
- Plays a 16 kHz sample rate raw file to the STM32F4 pin PA5.\r
+ Plays a 16 kHz sample rate raw file to the STM32F4 DACs.\r
\r
\*---------------------------------------------------------------------------*/\r
\r
printf("Starting!\n");\r
\r
while(fread(buf, sizeof(short), N, fplay) == N) {\r
+ while(dac1_write(buf, N) == -1);\r
while(dac2_write(buf, N) == -1);\r
} \r
\r
};\r
\r
int main(void) {\r
+\r
dac_open(4*DAC_BUF_SZ);\r
\r
while (1) {\r
--- /dev/null
+/*---------------------------------------------------------------------------*\\r
+\r
+ FILE........: debugblinky.c\r
+ AUTHOR......: David Rowe\r
+ DATE CREATED: 12 August 2014\r
+\r
+ Configures GPIO pins used for debug blinkies\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+ Copyright (C) 2014 David Rowe\r
+\r
+ All rights reserved.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU Lesser General Public License version 2.1, as\r
+ published by the Free Software Foundation. This program is\r
+ distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\r
+ License for more details.\r
+\r
+ You should have received a copy of the GNU Lesser General Public License\r
+ along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include "stm32f4xx.h"\r
+\r
+void init_debug_blinky(void) {\r
+ GPIO_InitTypeDef GPIO_InitStruct;\r
+\r
+ /* PE0-3 used to indicate activity */\r
+\r
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);\r
+\r
+ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;\r
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; \r
+ GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; \r
+ GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; \r
+ GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; \r
+ GPIO_Init(GPIOE, &GPIO_InitStruct); \r
+\r
+}\r
+\r
SystemInit();\r
gpio_init();\r
machdep_timer_init ();\r
- adc_open();\r
+ adc_open(4*DAC_BUF_SZ);\r
dac_open(4*DAC_BUF_SZ);\r
\r
printf("Starting power_ut\n");\r
#include "stm32f4_adc.h"\r
#include "stm32f4_dac.h"\r
#include "freedv_api.h"\r
+#include "codec2_fdmdv.h"\r
#include "sm1000_leds_switches.h"\r
+#include <stm32f4xx_gpio.h>\r
+\r
+#define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES)\r
\r
int main(void) {\r
struct freedv *f;\r
- short buf[FREEDV_NSAMPLES];\r
- int nin, nout;\r
+ float adc16k[FDMDV_OS_TAPS_16K+FREEDV_NSAMPLES_16K];\r
+ float adc8k[FREEDV_NSAMPLES];\r
+ float dac8k[FDMDV_OS_TAPS_8K+FREEDV_NSAMPLES];\r
+ float dac16k[FREEDV_NSAMPLES_16K];\r
+ short buf[FREEDV_NSAMPLES_16K];\r
+\r
+ int nin, nout, i;\r
\r
/* init all the drivers for various peripherals */\r
\r
- sm1000_leds_switches_init();\r
+ //sm1000_leds_switches_init();\r
dac_open(4*DAC_BUF_SZ);\r
- adc_open();\r
- f = freedv_open(FREEDV_MODE_1600);\r
+ adc_open(4*ADC_BUF_SZ);\r
+ //f = freedv_open(FREEDV_MODE_1600);\r
\r
/* LEDs into a known state */\r
\r
- led_pwr(1); led_ptt(0); led_rt(0); led_err(0);\r
+ //led_pwr(1); led_ptt(0); led_rt(0); led_err(0);\r
\r
/* \r
TODO:\r
[ ] UT analog interfaces from file IO\r
[ ] UTs for simultaneous tx & rx on analog interfaces\r
[ ] measure CPU load of various parts with a blinky\r
+ [ ] ADC and DAC drivers\r
+ [ ] rate conversion\r
[ ] detect program assert type errors with a blinky\r
[ ] timer tick function to measure 10ms-ish type times\r
[ ] switch debouncing?\r
[ ] light led with bit errors\r
+ [ ] 16 to 8 kHz rate conversion\r
*/\r
\r
- while(1) {\r
+ /* clear filter memories */\r
\r
- if(switch_ptt()) {\r
+ for(i=0; i<FDMDV_OS_TAPS_16K; i++)\r
+ adc16k[i] = 0.0;\r
+ for(i=0; i<FDMDV_OS_TAPS_8K; i++)\r
+ dac8k[i] = 0.0;\r
+ \r
+ while(1) {\r
+ if(1) {\r
\r
/* Transmit -------------------------------------------------------------------------*/\r
\r
/* ADC2 is the SM1000 microphone, DAC1 is the modulator signal we send to radio tx */\r
\r
- if (adc2_read(buf, FREEDV_NSAMPLES) == FREEDV_NSAMPLES) {\r
- freedv_tx(f, buf, buf);\r
- dac1_write(buf, FREEDV_NSAMPLES);\r
- led_ptt(1); led_rt(0); led_err(0);\r
+ if (adc1_read(buf, FREEDV_NSAMPLES_16K) == 0) {\r
+\r
+ GPIOE->ODR = (1 << 3);\r
+ for(i=0; i<FREEDV_NSAMPLES_16K; i++)\r
+ adc16k[FDMDV_OS_TAPS_16K+i] = buf[i];\r
+\r
+ fdmdv_16_to_8(adc8k, &adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES);\r
+\r
+ for(i=0; i<FREEDV_NSAMPLES; i++)\r
+ buf[i] = adc8k[i];\r
+ //freedv_tx(f, buf, buf);\r
+ for(i=0; i<FREEDV_NSAMPLES; i++)\r
+ dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];\r
+\r
+ fdmdv_8_to_16(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES); \r
+\r
+ for(i=0; i<FREEDV_NSAMPLES_16K; i++)\r
+ buf[i] = dac16k[i]; \r
+ dac2_write(buf, FREEDV_NSAMPLES_16K);\r
+ GPIOE->ODR &= ~(1 << 3);\r
+\r
+ //led_ptt(1); led_rt(0); led_err(0);\r
}\r
+\r
}\r
else {\r
\r
nin = freedv_nin(f);\r
f->total_bit_errors = 0;\r
\r
- if (adc1_read(buf, nin) == nin) {\r
+ if (adc1_read(buf, nin) == 0) {\r
nout = freedv_rx(f, buf, buf);\r
dac2_write(buf, nout);\r
led_ptt(0); led_rt(f->fdmdv_stats.sync); led_err(f->total_bit_errors);\r
#include "codec2_fifo.h"
#include "stm32f4_adc.h"
+#include "debugblinky.h"
struct FIFO *adc1_fifo;
unsigned short adc_buf[ADC_BUF_SZ];
tim2_config();
adc_configure();
+ init_debug_blinky();
}
/* n signed 16 bit samples in buf[] if return != -1 */
// Select the channel to be read from
- ADC_RegularChannelConfig(ADCx,ADC_Channel_3,1,ADC_SampleTime_144Cycles);
+ ADC_RegularChannelConfig(ADCx,ADC_Channel_2,1,ADC_SampleTime_144Cycles);
+ //ADC_VBATCmd(ENABLE);
/* DMA configuration **************************************/
int i, sam;
short signed_buf[ADC_BUF_SZ/2];
+ GPIOE->ODR = (1 << 0);
+
/* Half transfer interrupt */
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0) != RESET) {
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
}
+
+ GPIOE->ODR &= ~(1 << 0);
}
#include "stm32f4xx.h"\r
#include "codec2_fifo.h"\r
#include "stm32f4_dac.h"\r
+#include "debugblinky.h"\r
\r
/* write to these registers for 12 bit left aligned data, as per data sheet \r
make sure 4 least sig bits set to 0 */\r
tim6_config(); \r
dac1_config();\r
dac2_config();\r
+\r
+ init_debug_blinky();\r
}\r
\r
/* Call these puppies to send samples to the DACs. For your\r
\r
/* --------------------------------------------------------\r
\r
- TIM3 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since\r
+ TIM6 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since\r
APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig\r
13 clock tree figure in DM0031020.pdf).\r
\r
int i, j, sam;\r
short signed_buf[DAC_BUF_SZ/2];\r
\r
+ GPIOE->ODR = (1 << 1);\r
+\r
/* Transfer half empty interrupt - refill first half */\r
\r
if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5) != RESET) {\r
\r
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5); \r
}\r
+\r
+ GPIOE->ODR &= ~(1 << 1);\r
}\r
\r
/*\r
int i, j, sam;\r
short signed_buf[DAC_BUF_SZ/2];\r
\r
+ GPIOE->ODR = (1 << 2);\r
+\r
/* Transfer half empty interrupt - refill first half */\r
\r
if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET) {\r
\r
DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6); \r
}\r
+\r
+ GPIOE->ODR &= ~(1 << 2);\r
}\r
\r