1 | typedef struct ADCValues
|
2 | {
|
3 | uint16_t channel0;
|
4 | uint16_t channel1;
|
5 | uint16_t channel2;
|
6 | uint16_t channel3;
|
7 | uint16_t spare;
|
8 | } ADCValues_t;
|
9 |
|
10 | // DMA Target for ADC
|
11 | volatile ADCValues_t ADCRead;
|
12 |
|
13 | /* temporary use the internal 12-bit ADC for audio input, but it sounds bad */
|
14 | void ADCInit(void) {
|
15 | ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
16 | ADC_InitTypeDef ADC_InitStructure;
|
17 | DMA_InitTypeDef DMA_InitStructure;
|
18 |
|
19 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
|
20 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
|
21 | /* ADC1 configuration
|
22 | * 4 channel continuous
|
23 | */
|
24 | //ADC_DeInit(ADC1);
|
25 | ADC_CommonStructInit(&ADC_CommonInitStructure);
|
26 | ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
27 | ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
|
28 | ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
29 | ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
30 | ADC_CommonInit(&ADC_CommonInitStructure);
|
31 |
|
32 | ADC_StructInit(&ADC_InitStructure);
|
33 | ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
34 | ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
35 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
36 | ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
37 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
|
38 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
|
39 | ADC_InitStructure.ADC_NbrOfConversion = 4;
|
40 | /* Now do the setup */
|
41 | ADC_Init(ADC1, &ADC_InitStructure);
|
42 | /* Enable ADC1 and configure channels*/
|
43 | ADC_RegularChannelConfig(ADC1,INPUT0_CHANNEL,1,ADC_SampleTime_15Cycles);
|
44 | ADC_RegularChannelConfig(ADC1,INPUT1_CHANNEL,2,ADC_SampleTime_15Cycles);
|
45 | ADC_RegularChannelConfig(ADC1,INPUT2_CHANNEL,3,ADC_SampleTime_15Cycles);
|
46 | ADC_RegularChannelConfig(ADC1,INPUT3_CHANNEL,4,ADC_SampleTime_15Cycles);
|
47 |
|
48 | /* DMA1 channel1 configuration ----------------------------------------------*/
|
49 | DMA_DeInit(DMA2_Stream0); // Clear everything we had
|
50 | DMA_StructInit(&DMA_InitStructure);
|
51 | DMA_InitStructure.DMA_Channel = DMA_Channel_0;
|
52 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR); // source address
|
53 | DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ADCRead.channel0; // result memory location
|
54 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // from Peripheral to RAM
|
55 | DMA_InitStructure.DMA_BufferSize = 2; /// Note that we have 4 Channels
|
56 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Source stays same address
|
57 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Destination will be incremented
|
58 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16 bit results
|
59 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // yeah same size -> 16 bit
|
60 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Wrap around the destination address
|
61 | DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //
|
62 | DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
63 | DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
64 | DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
65 | DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
|
66 | DMA_Init(DMA2_Stream0, &DMA_InitStructure); // Init the stuff finally
|
67 | DMA_Cmd(DMA2_Stream0,ENABLE);
|
68 | // wait for the DMA Stream to be ready
|
69 | while(DMA_GetCmdStatus(DMA2_Stream0)==DISABLE){};
|
70 | // now run the ADC
|
71 | ADC_DMACmd(ADC1, ENABLE);
|
72 | ADC_Cmd(ADC1, ENABLE);
|
73 | ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
|
74 | ADC_ContinuousModeCmd(ADC1,ENABLE);
|
75 | ADC_SoftwareStartConv(ADC1);
|
76 | }
|