From: drowe67 Date: Sat, 9 Aug 2014 03:31:02 +0000 (+0000) Subject: single channel driver OK on Discovery X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=fd29e1344f7e704b493c1fe0110c5bde47723c0e;p=freetel-svn-tracking.git single channel driver OK on Discovery git-svn-id: https://svn.code.sf.net/p/freetel/code@1789 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/stm32/src/stm32f4_adc.c b/codec2-dev/stm32/src/stm32f4_adc.c index b5ae4b1a..adad5f89 100644 --- a/codec2-dev/stm32/src/stm32f4_adc.c +++ b/codec2-dev/stm32/src/stm32f4_adc.c @@ -4,19 +4,7 @@ AUTHOR......: David Rowe DATE CREATED: 4 June 2013 - ADC driver module for STM32F4. - - TODO: - [X] just get ADC to run at all, prove its sampling something.... - [X] as above with DMA - [X] half and finished interrupts, ISR - [ ] timer config to drive ADC conversion, measure sample rate and confirm 16kHz - + larger ADC DMA buffer - + fifos - + work out a way to unit test - [ ] ADC working at same time as DAC - [ ] remove (or make optional) the TIM_Config() code that sends PWM output to pins - [ ] check comments still valid + Two channel ADC driver module for STM32F4. \*---------------------------------------------------------------------------*/ @@ -46,12 +34,9 @@ #include "stm32f4xx_rcc.h" #include "codec2_fifo.h" -#include "gdb_stdio.h" +#include "stm32f4_adc.h" -#define ADC_BUF_SZ 320 -#define FIFO_SZ 8000 - -struct FIFO *DMA2_Stream0_fifo; +struct FIFO *adc1_fifo; unsigned short adc_buf[ADC_BUF_SZ]; int adc_overflow; int half,full; @@ -61,89 +46,25 @@ int half,full; #define DMA_STREAMx DMA2_Stream0 #define ADCx ADC1 -#define TIM1_CCR3_ADDRESS 0x4001223C - -TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; -TIM_OCInitTypeDef TIM_OCInitStructure; -uint16_t uhTimerPeriod; -uint16_t aSRC_Buffer[3] = {0, 0, 0}; - -void Timer1Config(); void adc_configure(); -#define REC_TIME_SECS 5 -#define N 2000 -#define FS 16000 - static void tim2_config(void); -int main(void){ - short buf[N]; - FILE *frec; - int i, bufs; +void adc_open(int fifo_sz) { + adc1_fifo = fifo_create(fifo_sz); + assert(adc1_fifo != NULL); - DMA2_Stream0_fifo = fifo_create(FIFO_SZ); - assert(DMA2_Stream0_fifo != NULL); - - //Timer1Config(); tim2_config(); adc_configure(); - ADC_SoftwareStartConv(ADC1); - - frec = fopen("stm_out.raw", "wb"); - if (frec == NULL) { - printf("Error opening input file: stm_out.raw\n\nTerminating....\n"); - exit(1); - } - bufs = FS*REC_TIME_SECS/N; - - printf("Starting!\n"); - for(i=0; i TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock - - TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock - SystemCoreClock is set to 168 MHz for STM32F4xx devices. - - The objective is to configure TIM1 channel 3 to generate complementary PWM - signal with a frequency equal to F KHz: - - TIM1_Period = (SystemCoreClock / F) - 1 - - The number of this repetitive requests is defined by the TIM1 Repetion counter, - each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new - value defined by the aSRC_Buffer. - - Note: - SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. - Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() - function to update SystemCoreClock variable value. Otherwise, any configuration - based on this variable will be incorrect. - -----------------------------------------------------------------------------*/ - - /* Compute the value to be set in ARR regiter to generate signal frequency at 16.00 Khz */ - uhTimerPeriod = (SystemCoreClock / 16000 ) - 1; - /* Compute CCR1 value to generate a duty cycle at 50% */ - aSRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (uhTimerPeriod - 1)) / 10); - /* Compute CCR1 value to generate a duty cycle at 37.5% */ - aSRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (uhTimerPeriod - 1)) / 1000); - /* Compute CCR1 value to generate a duty cycle at 25% */ - aSRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (uhTimerPeriod - 1)) / 100); - - /* TIM1 Peripheral Configuration -------------------------------------------*/ - /* TIM1 clock enable */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); - - /* Time Base configuration */ - - TIM_DeInit(TIM1); - TIM_TimeBaseStructure.TIM_Prescaler = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; - - TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); - - /* Channel 3 Configuration in PWM mode */ - - /* I think we just ned to enable channel 3 somehow, but without - (or optionally with) actual ouput to a GPIO pin. */ - - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; - TIM_OCInitStructure.TIM_Pulse = aSRC_Buffer[0]; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; - TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; - TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; - TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; - - TIM_OC3Init(TIM1, &TIM_OCInitStructure); - - /* Enable preload feature */ - TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); - - /* TIM1 counter enable */ - TIM_Cmd(TIM1, ENABLE); - - /* Main Output Enable */ - TIM_CtrlPWMOutputs(TIM1, ENABLE); -} void adc_configure(){ ADC_InitTypeDef ADC_init_structure; @@ -271,17 +111,14 @@ void adc_configure(){ // Clock configuration RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); - //RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); - // Analog pin configuration + // Analog pin configuration ADC1->PA1, ADC2->PA2 - //GPIO_initStructre.GPIO_Pin = GPIO_Pin_1; // ADC Channel 10 is connected to PC0 - GPIO_initStructre.GPIO_Pin = GPIO_Pin_2; // ADC Channel 10 is connected to PC0 + GPIO_initStructre.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; - //GPIO_Init(GPIOC,&GPIO_initStructre); GPIO_Init(GPIOA,&GPIO_initStructre); // ADC structure configuration @@ -290,7 +127,6 @@ void adc_configure(){ ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Left; ADC_init_structure.ADC_Resolution = ADC_Resolution_12b; ADC_init_structure.ADC_ContinuousConvMode = DISABLE; - //ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_init_structure.ADC_NbrOfConversion = 1; @@ -299,7 +135,6 @@ void adc_configure(){ // Select the channel to be read from - //ADC_RegularChannelConfig(ADCx,ADC_Channel_10,1,ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADCx,ADC_Channel_2,1,ADC_SampleTime_144Cycles); /* DMA configuration **************************************/ @@ -346,9 +181,10 @@ void adc_configure(){ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - // Enable ADC conversion + // Enable and start ADC conversion ADC_Cmd(ADC1,ENABLE); + ADC_SoftwareStartConv(ADC1); } /* @@ -368,13 +204,12 @@ void DMA2_Stream0_IRQHandler(void) { for(i=0; i