#include <assert.h>
#include <stdlib.h>
#include <string.h>
-#include "stm32f4xx.h"
#include "codec2_fifo.h"
-#include "stm32f4_adc.h"
+#include "gdb_stdio.h"
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+
+//#define TRY3
+#ifdef TRY3
+
+#define ADCx ADC1
+#define ADCx_CLK RCC_APB2Periph_ADC1
+#define DMA_CHANNELx DMA_Channel_0
+#define DMA_STREAMx DMA2_Stream0
+#define ADCx_DR_ADDRESS ((uint32_t)0x4001204C)
+
+static void ADC_Config(void);
+
+volatile unsigned short uhADCConvertedValue[10];
+
+int adc_convert(){
+ while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion
+ return ADC_GetConversionValue(ADC1); //Return the converted data
+}
+
+int main(void)
+{
+
+ /* ADC1 Channel Vbat configuration */
+ ADC_Config();
+
+ /* Start ADC1 Software Conversion */
+ ADC_SoftwareStartConv(ADC1);
+
+ while (1) {
+ //uhADCConvertedValue = adc_convert();
+ int i;
+ for(i=0; i<10; i++)
+ printf("ADC: %d \n", uhADCConvertedValue[i]);
+ }
+}
+
+static void ADC_Config(void);
+
+/**
+ * @brief ADC1 Channel Vbat configuration
+ * @note This function Configure the ADC peripheral
+ 1) Enable peripheral clocks
+ 2) DMA2_Stream0 channel 0 configuration
+ 3) Configure ADC1 Channel18 (VBAT)
+ * @param None
+ * @retval None
+ */
+static void ADC_Config(void)
+{
+ ADC_InitTypeDef ADC_InitStructure;
+ ADC_CommonInitTypeDef ADC_CommonInitStructure;
+ DMA_InitTypeDef DMA_InitStructure;
+
+ /* Enable peripheral clocks *************************************************/
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+ RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
-#define ADCx ADC3
+ /* DMA2_Stream0 channel0 configuration **************************************/
+ DMA_DeInit(DMA2_Stream0);
+ DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
+ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
+ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADCConvertedValue;
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
+ DMA_InitStructure.DMA_BufferSize = 10;
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+ DMA_Init(DMA_STREAMx, &DMA_InitStructure);
+
+ /* DMA2_Stream0 enable */
+ DMA_Cmd(DMA_STREAMx, ENABLE);
+
+ /* ADC Common Init **********************************************************/
+ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
+ ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
+ ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
+ ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
+ ADC_CommonInit(&ADC_CommonInitStructure);
+
+ /* ADC1 Init ****************************************************************/
+ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
+ ADC_InitStructure.ADC_ScanConvMode = DISABLE;
+ ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
+ ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
+ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
+ ADC_InitStructure.ADC_NbrOfConversion = 1;
+ ADC_Init(ADCx, &ADC_InitStructure);
+
+ /* Enable ADC1 DMA */
+ ADC_DMACmd(ADCx, ENABLE);
+
+#define VBAT
+#ifdef VBAT
+ /* ADC1 regular channel18 (VBAT) configuration ******************************/
+ ADC_RegularChannelConfig(ADCx, ADC_Channel_Vbat, 1, ADC_SampleTime_15Cycles);
+
+ /* Enable VBAT channel */
+ ADC_VBATCmd(ENABLE);
+#else
+ ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_15Cycles);
+ ADC_TempSensorVrefintCmd(ENABLE);
+#endif
+
+ /* Enable DMA request after last transfer (Single-ADC mode) */
+ ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
+
+ /* Enable ADC1 **************************************************************/
+ ADC_Cmd(ADCx, ENABLE);
+}
+#endif
+
+#define TRY2
+#ifdef TRY2
+
+int ConvertedValue = 0; //Converted value readed from ADC
+#define ADCx_DR_ADDRESS ((uint32_t)0x4001204C)
+volatile unsigned short uhADCxConvertedValue[10];
+
+#define DMA_CHANNELx DMA_Channel_0
+#define DMA_STREAMx DMA2_Stream0
+
+ ADC_InitTypeDef ADC_init_structure; //Structure for adc confguration
+ GPIO_InitTypeDef GPIO_initStructre; //Structure for analog input pin
+ DMA_InitTypeDef DMA_InitStructure;
+
+void adc_configure(){
+
+
+ //Clock configuration
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//The ADC1 is connected the APB2 peripheral bus thus we will use its clock source
+ RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);//Clock for the ADC port!! Do not forget about this one ;)
+
+ /* DMA2 configuration **************************************/
+ DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
+ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
+ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADCxConvertedValue;
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
+ DMA_InitStructure.DMA_BufferSize = 10;
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+ DMA_Init(DMA_STREAMx, &DMA_InitStructure);
+ DMA_Cmd(DMA_STREAMx, ENABLE);
+
+ //Analog pin configuration
+ GPIO_initStructre.GPIO_Pin = GPIO_Pin_0;//The channel 10 is connected to PC0
+ GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //The PC0 pin is configured in analog mode
+ GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //We don't need any pull up or pull down
+ GPIO_Init(GPIOC,&GPIO_initStructre);//Affecting the port with the initialization structure configuration
+
+ //ADC structure configuration
+ ADC_DeInit();
+ ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
+ ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
+ ADC_init_structure.ADC_ContinuousConvMode = ENABLE; //the conversion is continuous, the input data is converted more than once
+ ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;// conversion is synchronous with TIM1 and CC1 (actually I'm not sure about this one :/)
+ ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//no trigger for conversion
+ ADC_init_structure.ADC_NbrOfConversion = 1;//I think this one is clear :p
+ ADC_init_structure.ADC_ScanConvMode = DISABLE;//The scan is configured in one channel
+ ADC_Init(ADC1,&ADC_init_structure);//Initialize ADC with the previous configuration
+
+ /* Enable DMA request after last transfer (Single-ADC mode) */
+ ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
+
+ /* Enable ADC1 DMA */
+ ADC_DMACmd(ADC1, ENABLE);
+
+ //Enable ADC conversion
+ ADC_Cmd(ADC1,ENABLE);
+
+ //Select the channel to be read from
+ ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_144Cycles);
+}
+
+int adc_convert(){
+ while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion
+ return ADC_GetConversionValue(ADC1); //Return the converted data
+}
+
+int main(void){
+ adc_configure();//Start configuration
+ ADC_SoftwareStartConv(ADC1);//Start the conversion
+ while(1){//loop while the board is working
+ //ConvertedValue = adc_convert();//Read the ADC converted value
+ //printf("ConvertedValue = %d\n", ConvertedValue);
+ int i;
+ for(i=0; i<10; i++)
+ printf("ADC: %d \n", uhADCxConvertedValue[i]);
+ }
+}
+#endif
+
+#ifdef TRY1
+
+#define ADCx ADC1
#define ADC_CHANNEL ADC_Channel_7
-#define ADCx_CLK RCC_APB2Periph_ADC3
-#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOF
-#define GPIO_PIN GPIO_Pin_9
-#define GPIO_PORT GPIOF
-#define DMA_CHANNELx DMA_Channel_2
+#define ADCx_CLK RCC_APB2Periph_ADC1
+#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOA
+#define GPIO_PIN GPIO_Pin_7
+#define GPIO_PORT GPIOA
+#define DMA_CHANNELx DMA_Channel_0
#define DMA_STREAMx DMA2_Stream0
-#define ADCx_DR_ADDRESS ((uint32_t)0x4001224C)
+#define ADCx_DR_ADDRESS ((uint32_t)0x4001204C)
-#define TIM1_CCR3_ADDRESS 0x4001003C
+#define TIM1_CCR3_ADDRESS 0x4001223C
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
+uint16_t uhTimerPeriod;
+uint16_t aSRC_Buffer[3] = {0, 0, 0};
+
unsigned short uhADCxConvertedValue;
static void ADC_Config(void);
/* look for 17kHz (ish) on timer pins */
ADC_Config();
+ ADC_SoftwareStartConv(ADCx);
Timer1Config();
/* todo: that start up cmd here */
while(1) {
- printf("ADC; %d\n", uhADCxConvertedValue);
+ printf("ADC: %d\n", uhADCxConvertedValue);
}
}
void Timer1Config() {
- /* TIM Configuration */
+ /* TIM Configuration */
- TIM_Config();
+ TIM_Config();
- /* TIM1 DMA Transfer example -------------------------------------------------
+ /* TIM1 DMA Transfer example -------------------------------------------------
- TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2
- prescaler is different from 1.
- TIM1CLK = 2 * PCLK2
- PCLK2 = HCLK / 2
- => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock
+ TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2
+ prescaler is different from 1.
+ TIM1CLK = 2 * PCLK2
+ PCLK2 = HCLK / 2
+ => 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 17.57 KHz:
- - TIM1_Period = (SystemCoreClock / 17570) - 1
- and a variable duty cycle that is changed by the DMA after a specific number of
- Update DMA request.
-
- 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.
+ 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 17.57 KHz:
+ - TIM1_Period = (SystemCoreClock / 17570) - 1
+ and a variable duty cycle that is changed by the DMA after a specific number of
+ Update DMA request.
+
+ 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.
- -----------------------------------------------------------------------------*/
+ 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 17.57 Khz */
- uhTimerPeriod = (SystemCoreClock / 17570 ) - 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_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 = 3;
-
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
-
- /* Channel 3 Configuration in PWM mode */
- 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);
+ /* Compute the value to be set in ARR regiter to generate signal frequency at 17.57 Khz */
+ uhTimerPeriod = (SystemCoreClock / 17570 ) - 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_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 = 3;
+
+ TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
+
+ /* Channel 3 Configuration in PWM mode */
+ 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);
+ /* TIM1 counter enable */
+ TIM_Cmd(TIM1, ENABLE);
- /* DMA enable*/
- DMA_Cmd(DMA2_Stream6, ENABLE);
+ /* DMA enable*/
+ DMA_Cmd(DMA2_Stream6, ENABLE);
- /* TIM1 Update DMA Request enable */
- TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);
+ /* TIM1 Update DMA Request enable */
+ TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);
- /* Main Output Enable */
- TIM_CtrlPWMOutputs(TIM1, ENABLE);
+ /* Main Output Enable */
+ TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
/* DR: note I dont think any of this is needed, except perhaps to check
DMA_Init(DMA2_Stream6, &DMA_InitStructure);
}
+#endif