From 8b0b441cb3b9d152bfd2c726e08681dfad61d6c7 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 28 Aug 2015 02:44:15 +0000 Subject: [PATCH] added SFDR ADC ut, and updated README git-svn-id: https://svn.code.sf.net/p/freetel/code@2289 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/stm32/Makefile | 24 ++++++- codec2-dev/stm32/README.txt | 31 +++++++-- codec2-dev/stm32/inc/stm32f4_adc_tuner.h | 1 + codec2-dev/stm32/src/adc_sfdr_ut.c | 82 ++++++++++++++++++++++++ codec2-dev/stm32/src/stm32f4_adc_tuner.c | 34 +++++++--- 5 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 codec2-dev/stm32/src/adc_sfdr_ut.c diff --git a/codec2-dev/stm32/Makefile b/codec2-dev/stm32/Makefile index b70c2a21..185cf412 100644 --- a/codec2-dev/stm32/Makefile +++ b/codec2-dev/stm32/Makefile @@ -109,7 +109,7 @@ OBJS = $(SRCS:.c=.o) ################################################### -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 freedv_tx_profile.elf freedv_rx_profile.elf adc_sd.elf usb_vcp_ut.elf tuner_ut.elf fast_dac_ut.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 freedv_tx_profile.elf freedv_rx_profile.elf adc_sd.elf usb_vcp_ut.elf tuner_ut.elf fast_dac_ut.elf adc_sfdr_ut.elf dl/$(PERIPHLIBZIP): mkdir -p dl @@ -390,6 +390,28 @@ tuner_ut.elf: $(TUNER_UT_SRCS) src/stm32f4_adc_tuner.o $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS) $(OBJCOPY) -O binary tuner_ut.elf tuner_ut.bin +# --------------------------------------------------------------------------- + +ADC_SFDR_UT_SRCS=\ +src/adc_sfdr_ut.c \ +gdb_stdio.c \ +../src/fifo.c \ +src/sm1000_leds_switches.c \ +src/debugblinky.c \ +src/system_stm32f4xx.c \ +src/startup_stm32f4xx.s \ +src/init.c \ + +# this needs to be compiled without the optimiser or ugly things happen +# would be nice to work out why as ISRs need to run fast + +src/stm32f4_adc_tuner.o: src/stm32f4_adc_tuner.c + $(CC) $(CFLAGS) $^ -c -o $@ + +adc_sfdr_ut.elf: $(TUNER_UT_SRCS) src/stm32f4_adc_tuner.o + $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS) + $(OBJCOPY) -O binary adc_sfdr_ut.elf adc_sfdr_ut.bin + # --------------------------------------------------------------------------------- clean: diff --git a/codec2-dev/stm32/README.txt b/codec2-dev/stm32/README.txt index 82eda8b0..1640ea1b 100644 --- a/codec2-dev/stm32/README.txt +++ b/codec2-dev/stm32/README.txt @@ -1,14 +1,31 @@ README.txt codec2 support for the stm32f4 -David Rowe May 2013 +David Rowe August 2015 -Introduction ------------- +Quickstart +========== -The Makefile generates several unit tests, stm32f4_codec2.elf is the -most important. It's is equivalent to c2demo.c and runs the encoder -and decoder on raw speech files. It also gathers and prints profiling -information and can dump the codec states to compare changes. +The Makefile generates several programs used in Codec 2 development on +the STM32F4, including sm1000.bin, the firmware for the SM1000. + +1. Find stm32f4_dsp_stdperiph_lib.zip on the InterWebs and place in in + dl. (st.com was down when I last looked for it) + +2. Install the toolchain, on Ubuntu 14 this is: + + $ sudo apt-get install gcc-arm-none-eabi + +3. $ make (and cross your fingers) + +You may need to mess about with the Makefile to get it to work, +e.g. BINPATH, PERIPHLIBURL. A better build system is hopefully on +it's way. Contact me if you can help. + +Not quite so Quickstart +======================= + +Note: This section needs some editing. It deals with the running the +semi-hosting used for development system. gdb_stdio system ---------------- diff --git a/codec2-dev/stm32/inc/stm32f4_adc_tuner.h b/codec2-dev/stm32/inc/stm32f4_adc_tuner.h index 88f16a14..6c7c7559 100644 --- a/codec2-dev/stm32/inc/stm32f4_adc_tuner.h +++ b/codec2-dev/stm32/inc/stm32f4_adc_tuner.h @@ -35,5 +35,6 @@ void adc_open(int fifo_sz); int adc1_read(short buf[], int n); /* ADC1 Pin PA1 */ +void adc_set_tuner_en(short flag); /* disable tuner to get raw ADC samples written to fifo */ #endif diff --git a/codec2-dev/stm32/src/adc_sfdr_ut.c b/codec2-dev/stm32/src/adc_sfdr_ut.c new file mode 100644 index 00000000..c8c8cdf3 --- /dev/null +++ b/codec2-dev/stm32/src/adc_sfdr_ut.c @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: adc_sfdr_ut.c + AUTHOR......: David Rowe + DATE CREATED: August 2015 + + Unit test for high speed ADC SFDR testing. Samples ADC1 from in PA1 at + Fs=2 MHz and write raw samples to a file, in discontinuus blocks of + ADC_TUNER_BUF_SZ/2 samples. The blocks are discontinuous as we + don'thave the bandwitdh back to the host to support continuous sampling. + + To process the blocks, fread() ADC_TUNER_BUF_SZ/2 samples at a time, + abs(fft) and sum results from next block. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2015 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 . +*/ + +#include +#include +#include "gdb_stdio.h" +#include "stm32f4_dac.h" +#include "stm32f4_adc_tuner.h" +#include "iir_tuner.h" +#include "sm1000_leds_switches.h" +#include "../src/codec2_fm.h" +#include "stm32f4xx.h" + +#define REC_TIME_SECS 1 +#define FS 2E6 +#define N (ADC_TUNER_BUF_SZ/2) + +extern int adc_overflow1; + +int main(void) { + short buf[N]; + int bufs, i; + FILE *fadc; + + ftuner = fopen("adc.raw", "wb"); + if (ftuner == NULL) { + printf("Error opening output file: adc.raw\n\nTerminating....\n"); + exit(1); + } + bufs = FS*REC_TIME_SECS/N; + fifo_sz = ADC_TUNER_N; + printf("Starting! bufs: %d %d\n", bufs, fifo_sz); + + adc_open(fifo_sz); + adc_set_tuner_en(0); /* dump raw samples, no tuner */ + + sm1000_leds_switches_init(); + + for (i=0; iODR |= (1 << 3); + fwrite(buf, sizeof(short), N, fadc); + GPIOE->ODR &= ~(1 << 3); + } + fclose(fadc); + + printf("Finsihed!\n"); +} + diff --git a/codec2-dev/stm32/src/stm32f4_adc_tuner.c b/codec2-dev/stm32/src/stm32f4_adc_tuner.c index d083c599..9d74130b 100644 --- a/codec2-dev/stm32/src/stm32f4_adc_tuner.c +++ b/codec2-dev/stm32/src/stm32f4_adc_tuner.c @@ -45,6 +45,7 @@ struct FIFO *adc1_fifo; unsigned short adc_buf[ADC_TUNER_BUF_SZ]; int adc_overflow1; int half,full; +static short tuner_en = 1; #define ADCx_DR_ADDRESS ((uint32_t)0x4001204C) #define DMA_CHANNELx DMA_Channel_0 @@ -73,6 +74,11 @@ int adc1_read(short buf[], int n) { } +void adc_set_tuner_en(short flag) +{ + tuner_en = flag; +} + static void tim2_config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; @@ -232,14 +238,18 @@ void DMA2_Stream0_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0) != RESET) { half++; - iir_tuner(dec_buf, adc_buf); + if (tuner_en) { + iir_tuner(dec_buf, adc_buf); - /* write first half to fifo */ + /* write first half to fifo */ - if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) { - adc_overflow1++; + if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) { + adc_overflow1++; + } } - + else + fifo_write(adc1_fifo, (short*)adc_buf, ADC_TUNER_BUF_SZ/2); + /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0); @@ -250,14 +260,18 @@ void DMA2_Stream0_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET) { full++; - iir_tuner(dec_buf, &adc_buf[ADC_TUNER_BUF_SZ/2]); + if (tuner_en) { + iir_tuner(dec_buf, &adc_buf[ADC_TUNER_BUF_SZ/2]); - /* write second half to fifo */ + /* write second half to fifo */ - if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) { - adc_overflow1++; + if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) { + adc_overflow1++; + } } - + else + fifo_write(adc1_fifo, (short*)&adc_buf[ADC_TUNER_BUF_SZ/2], ADC_TUNER_BUF_SZ/2); + /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); -- 2.25.1