1 | /**
|
2 | ******************************************************************************
|
3 | * @file main.c
|
4 | * @author Ac6
|
5 | * @version V1.0
|
6 | * @date 01-December-2013
|
7 | * @brief Default main function.
|
8 | ******************************************************************************
|
9 | */
|
10 |
|
11 |
|
12 | #include "stm32f4xx.h"
|
13 | #include "stm32f4_discovery.h"
|
14 |
|
15 | #define VOLTAGE_REF 3.3 //Datasheet
|
16 |
|
17 | void RCC_Configuration(void)
|
18 | {
|
19 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
|
20 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
|
21 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
|
22 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
23 | }
|
24 |
|
25 | /***************************************************************************/
|
26 | void GPIO_Configuration(void)
|
27 | {
|
28 | GPIO_InitTypeDef GPIO_InitStructure;
|
29 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
|
30 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
31 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
32 | GPIO_Init(GPIOC, &GPIO_InitStructure);
|
33 | }
|
34 | /***************************************************************************/
|
35 | void ADC_Configuration(void)
|
36 | {
|
37 | ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
38 | ADC_InitTypeDef ADC_InitStructure;
|
39 | /* ADC Common Init */
|
40 | ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
41 | ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
|
42 | ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
|
43 | // 2 half-words one by one, 1 then 2
|
44 | ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
45 | ADC_CommonInit(&ADC_CommonInitStructure);
|
46 | ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
47 | ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
48 | ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversions Triggered
|
49 | ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
|
50 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
|
51 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
52 | ADC_InitStructure.ADC_NbrOfConversion = 2;
|
53 | ADC_Init(ADC1, &ADC_InitStructure);
|
54 | //ADC_Init(ADC2, &ADC_InitStructure); // Mirror on ADC2
|
55 | /* ADC1 regular channel 10 configuration */
|
56 |
|
57 | ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1,ADC_SampleTime_15Cycles);
|
58 | ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 2,ADC_SampleTime_15Cycles);
|
59 |
|
60 | //ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
|
61 | ADC_DMACmd(ADC1, ENABLE);
|
62 |
|
63 |
|
64 | /* Enable ADC1 */
|
65 | ADC_Cmd(ADC1, ENABLE);
|
66 |
|
67 | }
|
68 |
|
69 | /**************************************************************************/
|
70 | # define BUFFERSIZE 900 // I+Q 200KHz x2 HT/TC at 1KHz
|
71 |
|
72 | __IO uint16_t ADCDualConvertedValues[BUFFERSIZE]; // Filled as pairs ADC1, ADC2
|
73 |
|
74 | static void DMA_Configuration(void)
|
75 | {
|
76 | DMA_InitTypeDef DMA_InitStructure;
|
77 |
|
78 | DMA_InitStructure.DMA_Channel = DMA_Channel_0;
|
79 | DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCDualConvertedValues;
|
80 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40012308;
|
81 | // CDR_ADDRESS; Packed ADC1, ADC2
|
82 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
|
83 | DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
|
84 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
85 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
86 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
87 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
88 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
89 | DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
90 | DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
|
91 | DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
|
92 | DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
93 | DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
94 | DMA_Init(DMA2_Stream0, &DMA_InitStructure);
|
95 | /* Enable DMA Stream Half / Transfer Complete interrupt */
|
96 | DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
|
97 | /* DMA2_Stream0 enable */
|
98 | DMA_Cmd(DMA2_Stream0, ENABLE);
|
99 | }
|
100 | void TIM2_Configuration(void)
|
101 | {
|
102 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
103 | /* Time base configuration */
|
104 | TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
105 | TIM_TimeBaseStructure.TIM_Period =(84000000 / 200000) - 1;
|
106 | // 200 KHz, from 84 MHz TIM2CLK (ie APB1 = HCLK/4, TIM2CLK = HCLK/2)
|
107 | TIM_TimeBaseStructure.TIM_Prescaler = 0;
|
108 | TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
109 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
110 | TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
111 | /* TIM2 TRGO selection */
|
112 | TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
|
113 | // ADC_ExternalTrigConv_T2_TRGO
|
114 | /* TIM2 enable counter */
|
115 | TIM_Cmd(TIM2, ENABLE);
|
116 | }
|
117 |
|
118 | /****************************************************************************/
|
119 | void NVIC_Configuration(void)
|
120 | {
|
121 | NVIC_InitTypeDef NVIC_InitStructure;
|
122 | /* Enable the DMA Stream IRQ Channel */
|
123 | NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
|
124 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
125 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
126 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
127 | NVIC_Init(&NVIC_InitStructure);
|
128 | }
|
129 |
|
130 | /***********************************************************************/
|
131 | void DMA2_Stream0_IRQHandler(void)//Called at 1 KHz for 200 KHz sample rate
|
132 | {
|
133 | /* Test on DMA Stream Half Transfer interrupt */
|
134 | if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0))
|
135 | {
|
136 | /* Clear DMA Stream Half Transfer interrupt pending bit */
|
137 | DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
|
138 |
|
139 | }
|
140 |
|
141 | /* Test on DMA Stream Transfer Complete interrupt */
|
142 | if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
|
143 | {
|
144 | /* Clear DMA Stream Transfer Complete interrupt pending bit */
|
145 | DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
|
146 |
|
147 | // Add code here to process second half of buffer (pong)
|
148 | }
|
149 | }
|
150 |
|
151 | /*****************************************************************************/
|
152 |
|
153 | int main(void)
|
154 | {
|
155 | RCC_Configuration();
|
156 | GPIO_Configuration();
|
157 | NVIC_Configuration();
|
158 | TIM2_Configuration();
|
159 | DMA_Configuration();
|
160 | ADC_Configuration();
|
161 |
|
162 | /* Start ADC1 Software Conversion */
|
163 | ADC_SoftwareStartConv(ADC1);
|
164 |
|
165 | while(1) {// Don't want to exit
|
166 | float x=ADCDualConvertedValues[0];
|
167 | float y=ADCDualConvertedValues[1];
|
168 |
|
169 | }
|
170 | /***************************************************************************/
|
171 | }
|