1 | .
|
2 | .
|
3 | .
|
4 | void init_a2d_1(void) {
|
5 | int i = 0;
|
6 |
|
7 | /***** Clock_init *****/
|
8 | rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); /**< Enable internal clock APB2 (60MHZ) for ADC1 */
|
9 | rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC2EN); /**< Enable internal clock APB2 (60MHZ) for ADC2 */
|
10 | //rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); /**< Enable internal clock AHB1 (120MHZ) for analog-input Port A */
|
11 | //rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPCEN); /**< Enable internal clock AHB1 (120MHZ) for analog-input Port C */
|
12 | rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_DMA2EN); /**< Enable internal clock AHB1 (120MHZ) for DMA2 */
|
13 |
|
14 | /*++++++++++++++++++++ gpio_a ++++++++++++++++++++*/
|
15 | /***** Analog, no push/pull to HI or LOW *****/
|
16 | gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO5 | GPIO6 | GPIO7); //optPower, temp1+2
|
17 | gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0 | GPIO4); //stackVoltage, hum
|
18 |
|
19 | /***** enable DMA and config *****/
|
20 | #ifdef DMA_ON
|
21 | /**
|
22 | * Reference manual 10.9
|
23 | * DMA mode 2: on the first request ADC2 and ADC1 are transfered
|
24 | * (ADC2 data take the upper half-word and ADC1 data take the lower half-word)
|
25 | */
|
26 | dma_setup();
|
27 | nvic_enable_irq(NVIC_DMA2_STREAM0_IRQ);
|
28 | nvic_set_priority(NVIC_DMA2_STREAM0_IRQ, configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
29 | nvic_enable_irq(NVIC_DMA2_STREAM2_IRQ);
|
30 | nvic_set_priority(NVIC_DMA2_STREAM2_IRQ, configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
31 | #endif // DMA_ON
|
32 | /********** SINGLE MODE -> ADC1 ***********/
|
33 | /***** Make sure the ADC doesn't run during config *****/
|
34 | adc_off(ADC1);
|
35 | adc_off(ADC2);
|
36 |
|
37 | /***** 12-bit *****/
|
38 | adc_set_resolution(ADC1, ADC_CR1_RES_12BIT);
|
39 | adc_set_resolution(ADC2, ADC_CR1_RES_12BIT);
|
40 |
|
41 | /***** Prescaler 60MHZ/By2 = 30MHZ *****/
|
42 | adc_set_clk_prescale(ADC_CCR_ADCPRE_BY2);
|
43 |
|
44 | #ifdef DMA_ON
|
45 | adc_enable_scan_mode(ADC1);
|
46 | adc_enable_scan_mode(ADC2);
|
47 |
|
48 | // adc_set_single_conversion_mode(ADC1);
|
49 | // adc_set_single_conversion_mode(ADC2);
|
50 |
|
51 | adc_set_continuous_conversion_mode(ADC1);
|
52 | adc_set_continuous_conversion_mode(ADC2);
|
53 |
|
54 | /***** Trigger none *****/
|
55 | adc_disable_external_trigger_regular(ADC1);
|
56 | adc_disable_external_trigger_regular(ADC2);
|
57 |
|
58 | #else
|
59 | adc_set_single_conversion_mode(ADC1);
|
60 | adc_set_single_conversion_mode(ADC2);
|
61 | #endif // DMA_ON
|
62 | /***** result is stored right-aligned *****/
|
63 | adc_set_right_aligned(ADC1); //The result is right_aligned in a 32bit result-register
|
64 | adc_set_right_aligned(ADC2); //The result is right_aligned in a 32bit result-register
|
65 |
|
66 | /***** sampling_time from ADC *****/
|
67 | /* Fast_convertion at 3CYC by reducing the resolution, 28CYC sampletime is much more precise */
|
68 | //adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_112CYC);
|
69 | //adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_56CYC);
|
70 | //adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28CYC);
|
71 | adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_15CYC);
|
72 | adc_set_sample_time_on_all_channels(ADC2, ADC_SMPR_SMP_15CYC);
|
73 | //adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_3CYC);
|
74 |
|
75 | /***** eoc interrupt *****/
|
76 | adc_enable_eoc_interrupt(ADC1); //Interrupt
|
77 | adc_enable_eoc_interrupt(ADC2);
|
78 |
|
79 | uint8_t groupOfChannnels1[3];
|
80 | groupOfChannnels1[0] = ADC_CHANNEL6; //ADC1
|
81 | groupOfChannnels1[1] = ADC_CHANNEL7; //ADC1
|
82 | groupOfChannnels1[2] = ADC_CHANNEL5; //ADC1
|
83 |
|
84 | /***** regular group (channel selection) *****/
|
85 | adc_set_regular_sequence(ADC1, 3, groupOfChannnels1);
|
86 |
|
87 | uint8_t groupOfChannnels2[3];
|
88 | groupOfChannnels2[0] = ADC_CHANNEL10; //ADC2
|
89 | groupOfChannnels2[1] = ADC_CHANNEL14; //ADC2
|
90 | groupOfChannnels2[2] = ADC_CHANNEL10; //ADC2
|
91 |
|
92 | /***** regular group (channel selection) *****/
|
93 | adc_set_regular_sequence(ADC2, 3, groupOfChannnels2);
|
94 |
|
95 | /***** ADC2 for DualMode - activate DualMode just before start ADC1+2 *****/
|
96 | /********* DUAL MODE -> ADC1 + ADC2 *********/
|
97 | /***** Dual mode: regular simultaneous mode *****/
|
98 | adc_set_multi_mode(ADC_CCR_MULTI_DUAL_REGULAR_SIMUL);
|
99 |
|
100 | /***** Start ADC *****/
|
101 | adc_power_on(ADC1);
|
102 | adc_power_on(ADC2);
|
103 |
|
104 | /***** Wait for ADC is up *****/
|
105 | for (i = 0; i < 800000; i++) /* Wait a bit. */
|
106 | __asm__("nop");
|
107 |
|
108 | /***** Start conversion (in simultaneous-mode only ADC1 to be triggered) *****/
|
109 | adc_start_conversion_regular(ADC1);
|
110 |
|
111 | /***** NVIC interrupt ADC *****/
|
112 | // nvic_enable_irq(NVIC_ADC_IRQ);
|
113 | // nvic_set_priority(NVIC_ADC_IRQ, configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
114 | }
|
115 |
|
116 | /**
|
117 | * DMA setup for ADC conversion
|
118 | *
|
119 | * DMA2 - For ADC-converter you must use the DMA2 (Reference Manual 9.3.3)
|
120 | * and make sure, you are using the right streams and channels
|
121 | *
|
122 | * ADC1: DMA2, Channel0, Stream0 and Stream4
|
123 | * ADC2: DMA2, Channel1, Stream2 and Stream3
|
124 | * ADC3: DMA2, Channel2, Stream0 and Stream1
|
125 | *
|
126 | */
|
127 | void dma_setup() {
|
128 | /**
|
129 | * DMA Stream
|
130 | * - Init-procedure is shown in Reference Manual 9.3.17
|
131 | *
|
132 | * Check:
|
133 | * - Step 4. Number of data
|
134 | */
|
135 | /***************************** Stream configuration procedure **********************************/
|
136 |
|
137 | extern ringbufferOUTadc2[3];
|
138 | extern ringbufferOUTadc1[3];
|
139 | extern ringbufferINadc2[3];
|
140 | extern ringbufferINadc1[3];
|
141 |
|
142 | dma_stream_reset(DMA2, DMA_STREAM0);
|
143 | dma_stream_reset(DMA2, DMA_STREAM2);
|
144 |
|
145 | /***** first step, disable streams. Last step, enable stream again! *****/
|
146 | dma_disable_stream(DMA2, DMA_STREAM0);
|
147 | dma_disable_stream(DMA2, DMA_STREAM2);
|
148 |
|
149 | // 2. Set the peripheral port register address in the DMA_SxPAR register. The
|
150 | // data will be moved from/ to this address to/ from the peripheral port
|
151 | // after the peripheral event.
|
152 | // dma_set_peripheral_address(DMA2, DMA_STREAM0, (uint32_t) &DMA_SPAR(DMA_STREAM0, 3) );
|
153 | // dma_set_peripheral_address(DMA2, DMA_STREAM2, (uint32_t) &DMA_SPAR(DMA_STREAM2, 3) );
|
154 | dma_set_peripheral_address(DMA2, DMA_STREAM0, (uint32_t) ringbufferINadc1);
|
155 | dma_set_peripheral_address(DMA2, DMA_STREAM2, (uint32_t) ringbufferINadc2);
|
156 |
|
157 | // 3. Set the memory address in the DMA_SxMA0R register (and in the DMA_SxMA1R
|
158 | // register in the case of a double buffer mode). The data will be written
|
159 | // to or read from this memory after the peripheral event.
|
160 | // dma_set_memory_address(DMA2, DMA_STREAM0, (uint32_t) &DMA_SM0AR(DMA_STREAM0, 3) );
|
161 | // dma_set_memory_address(DMA2, DMA_STREAM2, (uint32_t) &DMA_SM0AR(DMA_STREAM2, 3) );
|
162 | dma_set_memory_address(DMA2, DMA_STREAM0, (uint32_t) &ringbufferOUTadc1);
|
163 | dma_set_memory_address(DMA2, DMA_STREAM2, (uint32_t) &ringbufferOUTadc2);
|
164 |
|
165 | // 4. Configure the total number of data items to be transferred in the
|
166 | // DMA_SxNDTR register. After each peripheral event or each beat of the
|
167 | // burst, this value is
|
168 | // decremented.
|
169 | dma_set_number_of_data(DMA2, DMA_STREAM0, 3);
|
170 | dma_set_number_of_data(DMA2, DMA_STREAM2, 3);
|
171 | // 5. Select the DMA channel (request) using CHSEL[2:0] in the DMA_SxCR
|
172 | // register.
|
173 | dma_channel_select(DMA2, DMA_STREAM0, DMA_SxCR_CHSEL_0);
|
174 | dma_channel_select(DMA2, DMA_STREAM2, DMA_SxCR_CHSEL_1);
|
175 | // 6. If the peripheral is intended to be the flow controller and if it
|
176 | // supports this feature, set the PFCTRL bit in the DMA_SxCR register.
|
177 | // Nope
|
178 | // 7. Configure the stream priority using the PL[1:0] bits in the DMA_SxCR
|
179 | // register.
|
180 | dma_set_priority(DMA2, DMA_STREAM0, DMA_SxCR_PL_MEDIUM);
|
181 | dma_set_priority(DMA2, DMA_STREAM2, DMA_SxCR_PL_MEDIUM);
|
182 | // 8. Configure the FIFO usage (enable or disable, threshold in transmission
|
183 | // and reception) Leave as default (direct mode)
|
184 | // 9. Configure the:
|
185 | // - data transfer direction,
|
186 | dma_set_transfer_mode(DMA2, DMA_STREAM0, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
|
187 | dma_set_transfer_mode(DMA2, DMA_STREAM2, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
|
188 | // - peripheral and memory incremented/fixed mode,
|
189 | dma_disable_peripheral_increment_mode(DMA2, DMA_STREAM0);
|
190 | dma_disable_peripheral_increment_mode(DMA2, DMA_STREAM2);
|
191 | dma_enable_memory_increment_mode(DMA2, DMA_STREAM0);
|
192 | dma_enable_memory_increment_mode(DMA2, DMA_STREAM2);
|
193 | // - single or burst transactions,
|
194 | // Single is default
|
195 | // - peripheral and memory data widths,
|
196 | dma_set_memory_size(DMA2, DMA_STREAM0, DMA_SxCR_MSIZE_32BIT);
|
197 | dma_set_memory_size(DMA2, DMA_STREAM2, DMA_SxCR_MSIZE_32BIT);
|
198 | dma_set_peripheral_size(DMA2, DMA_STREAM0, DMA_SxCR_PSIZE_16BIT);
|
199 | dma_set_peripheral_size(DMA2, DMA_STREAM2, DMA_SxCR_PSIZE_16BIT);
|
200 | // - Circular mode, DMA-controller starts from base-address when internal counter reached 0
|
201 | dma_enable_circular_mode(DMA2, DMA_STREAM0);
|
202 | dma_enable_circular_mode(DMA2, DMA_STREAM2);
|
203 | // - Double buffer mode
|
204 | // Not enabled
|
205 | // - interrupts after half and/or full transfer,
|
206 | // ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
|
207 | // Not yet...
|
208 | // - and/or errors in the DMA_SxCR register.
|
209 | // Not yet...
|
210 |
|
211 | /***** Last step: enable streams again. Activate the stream by setting the EN bit in the DMA_SxCR register. *****/
|
212 | dma_enable_stream(DMA2, DMA_STREAM0);
|
213 | dma_enable_stream(DMA2, DMA_STREAM2);
|
214 |
|
215 | /***** Enable DMA for ADC1, ADC2, ADC3 *****/
|
216 | adc_enable_dma(ADC1);
|
217 | adc_enable_dma(ADC2);
|
218 |
|
219 | /***** Set DMA to Continue *****/
|
220 | // adc_set_dma_continue(ADC1);
|
221 | // adc_set_dma_continue(ADC2);
|
222 |
|
223 | // /***** select channel for ADC1, ADC2, ADC3 *****/
|
224 | // dma_channel_select(DMA2, DMA_STREAM0, 0);
|
225 | // dma_channel_select(DMA2, DMA_STREAM2, 1);
|
226 | }
|