added SFDR ADC ut, and updated README
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 28 Aug 2015 02:44:15 +0000 (02:44 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 28 Aug 2015 02:44:15 +0000 (02:44 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2289 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/stm32/Makefile
codec2-dev/stm32/README.txt
codec2-dev/stm32/inc/stm32f4_adc_tuner.h
codec2-dev/stm32/src/adc_sfdr_ut.c [new file with mode: 0644]
codec2-dev/stm32/src/stm32f4_adc_tuner.c

index b70c2a213f00c0cc98a77624cd1bd2c432cdd2b6..185cf41270901cb6aad36e623a646b0bed03015e 100644 (file)
@@ -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:
index 82eda8b010129f86a51c8dedd72e4dfabd41f2f3..1640ea1be9fb3d4368be26f5c988464b28d5a44f 100644 (file)
@@ -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
 ----------------
index 88f16a14f8f80d03d41f0a312c6ced52e5b28c75..6c7c755969b78dce06d953b839db48abb5d63b72 100644 (file)
@@ -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 (file)
index 0000000..c8c8cdf
--- /dev/null
@@ -0,0 +1,82 @@
+/*---------------------------------------------------------------------------*\\r
+\r
+  FILE........: adc_sfdr_ut.c\r
+  AUTHOR......: David Rowe\r
+  DATE CREATED: August 2015\r
+\r
+  Unit test for high speed ADC SFDR testing.  Samples ADC1 from in PA1 at \r
+  Fs=2 MHz and write raw samples to a file, in discontinuus blocks of \r
+  ADC_TUNER_BUF_SZ/2 samples.  The blocks are discontinuous as we \r
+  don'thave the bandwitdh back to the host to support continuous sampling.\r
+\r
+  To process the blocks, fread() ADC_TUNER_BUF_SZ/2 samples at a time,\r
+  abs(fft) and sum results from next block.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+  Copyright (C) 2015 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 <stdlib.h>\r
+#include "gdb_stdio.h"\r
+#include "stm32f4_dac.h"\r
+#include "stm32f4_adc_tuner.h"\r
+#include "iir_tuner.h"\r
+#include "sm1000_leds_switches.h"\r
+#include "../src/codec2_fm.h"\r
+#include "stm32f4xx.h"\r
+\r
+#define REC_TIME_SECS 1\r
+#define FS            2E6\r
+#define N             (ADC_TUNER_BUF_SZ/2)\r
+\r
+extern int adc_overflow1;\r
+\r
+int main(void) {\r
+    short  buf[N];\r
+    int    bufs, i;\r
+    FILE  *fadc;\r
+\r
+    ftuner = fopen("adc.raw", "wb");\r
+    if (ftuner == NULL) {\r
+        printf("Error opening output file: adc.raw\n\nTerminating....\n");\r
+        exit(1);\r
+    }\r
+    bufs = FS*REC_TIME_SECS/N;\r
+    fifo_sz = ADC_TUNER_N;\r
+    printf("Starting! bufs: %d %d\n", bufs, fifo_sz);\r
\r
+    adc_open(fifo_sz);\r
+    adc_set_tuner_en(0); /* dump raw samples, no tuner */\r
+\r
+    sm1000_leds_switches_init();\r
+\r
+    for (i=0; i<bufs; i++) {\r
+        while(adc1_read(buf, N) == -1);\r
+\r
+        /* most of the time will be spent here */\r
+\r
+        GPIOE->ODR |= (1 << 3);\r
+        fwrite(buf, sizeof(short), N, fadc);\r
+        GPIOE->ODR &= ~(1 << 3);\r
+    }\r
+    fclose(fadc);\r
+\r
+    printf("Finsihed!\n");\r
+}\r
+\r
index d083c599e26a2c98b26d63d3e7a542c1cbcfac92..9d74130b21386b4fdcc48bbe68a57333f0d3e43c 100644 (file)
@@ -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);