1 | HAL_ADC_Start_DMA(&hadc3, (uint32_t*)ADC3_DMA_Buffer, ADC3_DMA_BUFFER_SIZE);
|
2 |
|
3 | #define ADC3_DMA_NR_OF_CHANNELS 4
|
4 | #define ADC3_DMA_NR_OF_SAMPLES 32 // muss eine Zweierpotenz sein
|
5 | #define ADC3_DMA_BUFFER_SIZE (ADC3_DMA_NR_OF_CHANNELS * ADC3_DMA_NR_OF_SAMPLES) // es werden 4 ADC Channel je DMA Aufruf ADC3_DMA_NR_OF_SAMPLES mal gesampelt
|
6 | extern volatile uint16_t ADC3_DMA_Buffer[];
|
7 |
|
8 | static void ConfigureDMA2_Stream0(void)
|
9 | {
|
10 | __DMA2_CLK_ENABLE();
|
11 | hadc3dma.Instance = DMA2_Stream0;
|
12 |
|
13 | hadc3dma.Init.Channel = DMA_CHANNEL_2;
|
14 | hadc3dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
15 | hadc3dma.Init.PeriphInc = DMA_PINC_DISABLE;
|
16 | hadc3dma.Init.MemInc = DMA_MINC_ENABLE;
|
17 | hadc3dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
18 | hadc3dma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
19 | hadc3dma.Init.Mode = DMA_NORMAL; // DMA_NORMAL is needed to avoid DMA buffer index shift if ADC is not stopped fast enough in continuous mode, if ADC not in continuous mode DMA_CIRCULAR is needed
|
20 | hadc3dma.Init.Priority = DMA_PRIORITY_HIGH;
|
21 | hadc3dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
22 | hadc3dma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; // only relevant if FIFO mode enabled
|
23 | hadc3dma.Init.MemBurst = DMA_MBURST_SINGLE;
|
24 | hadc3dma.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
25 |
|
26 | HAL_DMA_Init(&hadc3dma);
|
27 |
|
28 | __HAL_LINKDMA(&hadc3, DMA_Handle, hadc3dma);
|
29 |
|
30 | HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
|
31 | HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
|
32 | }
|
33 |
|
34 | // ADC3 init function
|
35 | void MX_ADC3_Init(void)
|
36 | {
|
37 | ADC_ChannelConfTypeDef sConfig;
|
38 |
|
39 | // Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
|
40 |
|
41 | hadc3.Instance = ADC3;
|
42 | hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
|
43 | hadc3.Init.Resolution = ADC_RESOLUTION_12B;
|
44 | hadc3.Init.ScanConvMode = ENABLE; // enables the sampling of a regular group
|
45 | hadc3.Init.ContinuousConvMode = ENABLE; // continuous mode is needed to trigger with one DMA start more than one group conversion (but ADC must be disabled manually after DMA stream complete), if ADC not in continuous mode DMA_CIRCULAR is needed
|
46 | hadc3.Init.DiscontinuousConvMode = DISABLE;
|
47 | hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
48 | hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
49 | hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
50 | hadc3.Init.NbrOfConversion = 4; // Anzahl der ADC channels in regular group
|
51 | hadc3.Init.DMAContinuousRequests = ENABLE; // enable, sonst kann der DMA nur einmal gestartet werden
|
52 | hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; // hat bei DMA vermutlich keinen Einfluss
|
53 | if (HAL_ADC_Init(&hadc3) != HAL_OK)
|
54 | {
|
55 | _Error_Handler(__FILE__, __LINE__);
|
56 | }
|
57 |
|
58 | __HAL_ADC_DISABLE(&hadc3); // bei ExternalTrigConv = ADC_SOFTWARE_START eigentlich unnötig, aber vorsichtshalber trotzdemn ADC definitiv anhalten
|
59 |
|
60 | // Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
61 |
|
62 | sConfig.Channel = ADC3_CH_ACC_X;
|
63 | sConfig.Rank = 1;
|
64 | sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
|
65 | sConfig.Offset = 0;
|
66 | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
|
67 | {
|
68 | _Error_Handler(__FILE__, __LINE__);
|
69 | }
|
70 |
|
71 | sConfig.Channel = ADC3_CH_ACC_Y;
|
72 | sConfig.Rank = 2;
|
73 | sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
|
74 | sConfig.Offset = 0;
|
75 | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
|
76 | {
|
77 | _Error_Handler(__FILE__, __LINE__);
|
78 | }
|
79 |
|
80 | sConfig.Channel = ADC3_CH_ACC_Z;
|
81 | sConfig.Rank = 3;
|
82 | sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
|
83 | sConfig.Offset = 0;
|
84 | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
|
85 | {
|
86 | _Error_Handler(__FILE__, __LINE__);
|
87 | }
|
88 |
|
89 | sConfig.Channel = ADC3_CH_POTI;
|
90 | sConfig.Rank = 4;
|
91 | sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
|
92 | sConfig.Offset = 0;
|
93 | if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
|
94 | {
|
95 | _Error_Handler(__FILE__, __LINE__);
|
96 | }
|
97 |
|
98 | ConfigureDMA2_Stream0();
|
99 |
|
100 | ADC3_inited = 1;
|
101 | }
|
102 |
|
103 | void DMA2_Stream0_IRQHandler(void)
|
104 | {
|
105 | // end of transfer
|
106 | HAL_DMA_IRQHandler(&hadc3dma);
|
107 | }
|
108 |
|
109 | void ADC_IRQHandler(void)
|
110 | {
|
111 | // seems to be not called with DMA?
|
112 | HAL_ADC_IRQHandler(&hadc3);
|
113 | }
|
114 |
|
115 | void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* adcHandle)
|
116 | {
|
117 | if (adcHandle->Instance == ADC3) {
|
118 | // Stream transfer complete (can be after multiple ADC group scanns)
|
119 | __HAL_ADC_DISABLE(adcHandle); // to interrupt ADC continuous mode
|
120 | // alle 3ms Start einer neuen ADC DMA Wandlung im HAL_SYSTICK_Callback()
|
121 | // Wandlung von 4 Kanälen mit den hier gemachten Einstellungen dauert ca.10us
|
122 |
|
123 | // die Daten liegen immer so im Buffer ch1 ... ch4, ch1 ... ch4, ...
|
124 | ...
|
125 | }
|
126 |
|
127 | // einfacher Mittelwert über ADC_DMA_NR_OF_SAMPLES Werte
|
128 | uint16_t md_ADC3_avgDMAvalues(ADC3_NAME_t adc_name) {
|
129 | uint32_t buffer = 0;
|
130 | uint16_t retVal;
|
131 |
|
132 | #if (ADC3_DMA_NR_OF_SAMPLES == 1)
|
133 | uint8_t anz_bit = 0;
|
134 | return ADC3_DMA_Buffer[adc_name];
|
135 | #elif (ADC3_DMA_NR_OF_SAMPLES == 2)
|
136 | uint8_t anz_bit = 1;
|
137 | #elif (ADC3_DMA_NR_OF_SAMPLES == 4)
|
138 | uint8_t anz_bit = 2;
|
139 | #elif (ADC3_DMA_NR_OF_SAMPLES == 8)
|
140 | uint8_t anz_bit = 3;
|
141 | #elif (ADC3_DMA_NR_OF_SAMPLES == 16)
|
142 | uint8_t anz_bit = 4;
|
143 | #elif (ADC3_DMA_NR_OF_SAMPLES == 32)
|
144 | uint8_t anz_bit = 5;
|
145 | #elif (ADC3_DMA_NR_OF_SAMPLES == 64)
|
146 | uint8_t anz_bit = 6;
|
147 | #elif (ADC3_DMA_NR_OF_SAMPLES == 128)
|
148 | uint8_t anz_bit = 7;
|
149 | #elif (ADC3_DMA_NR_OF_SAMPLES == 256)
|
150 | uint8_t anz_bit = 8;
|
151 | #elif (ADC3_DMA_NR_OF_SAMPLES == 512)
|
152 | uint8_t anz_bit = 9;
|
153 | #elif (ADC3_DMA_NR_OF_SAMPLES == 1024)
|
154 | uint8_t anz_bit = 10;
|
155 | #elif (ADC3_DMA_NR_OF_SAMPLES == 2048)
|
156 | uint8_t anz_bit = 11;
|
157 | #elif (ADC3_DMA_NR_OF_SAMPLES == 4096)
|
158 | uint8_t anz_bit = 12;
|
159 | #else
|
160 | #error no valid size for division by shifting
|
161 | #endif
|
162 |
|
163 | // in ADC_DMA_Buffer liegen immer die 4 ADC Kanäle hintereinander
|
164 | for (uint32_t i=adc_name; i < ADC3_DMA_BUFFER_SIZE; i=i+ADC3_DMA_NR_OF_CHANNELS) {
|
165 | buffer += ADC3_DMA_Buffer[i];
|
166 | }
|
167 |
|
168 | retVal = (buffer >> anz_bit);
|
169 |
|
170 | return retVal;
|
171 | }
|