Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
adc_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Pascal Brisset, Antoine Drouin
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
30 #include "mcu_periph/adc.h"
31 
32 #include "LPC21xx.h"
33 #include "armVIC.h"
34 #include BOARD_CONFIG
35 
36 
37 #ifdef USE_AD0
38 #ifndef AD0_VIC_SLOT
39 #define AD0_VIC_SLOT 2
40 #endif
41 #endif
42 
43 #ifdef USE_AD1
44 #ifndef AD1_VIC_SLOT
45 #define AD1_VIC_SLOT 4
46 #endif
47 #endif
48 
49 
51 static struct adc_buf *buffers[NB_ADC * 2];
52 
53 volatile uint16_t adc0_val[NB_ADC] = {1, 2, 3, 4, 5, 6, 7, 8};
54 volatile uint16_t adc1_val[NB_ADC] = {9, 10, 11, 12, 13, 14, 15, 16};
55 
56 void adcISR0(void) __attribute__((naked));
57 void adcISR1(void) __attribute__((naked));
58 
59 void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
60 {
61  // check for out-of-bounds access
62  if (adc_channel >= (NB_ADC * 2)) return;
63  buffers[adc_channel] = s;
65 }
66 
67 /*
68 
69 pin11 AD0.0 P0.27 PINSEL1 1 << 22
70 pin13 AD0.1 P0.28 PINSEL1 1 << 24
71 pin14 AD0.2 P0.29 PINSEL1 1 << 26
72 pin15 AD0.3 P0.30 PINSEL1 1 << 28
73 pin9 AD0.4 P0.25 PINSEL1 1 << 18
74 pin10 AD0.5 P0.26 PINSEL1 1 << 20
75 pin27 AD0.6 P0.4 PINSEL0 3 << 8
76 pin29 AD0.7 P0.5 PINSEL0 3 << 10
77 
78 pin30 AD1.0 P0.6 PINSEL0 3 << 12
79 pin33 AD1.1 P0.8 PINSEL0 3 << 16
80 pin35 AD1.2 P0.10 PINSEL0 3 << 20
81 pin38 AD1.3 P0.12 PINSEL0 3 << 24
82 pin39 AD1.4 P0.13 PINSEL0 3 << 26
83 pin45 AD1.5 P0.15 PINSEL0 3 << 30
84 pin1 AD1.6 P0.21 PINSEL1 2 << 10
85 pin2 AD1.7 P0.22 PINSEL1 1 << 12
86 
87 */
88 
89 static const uint32_t ADC_PINSEL0_ONES = 0
90 #if defined USE_AD0_6
91  | 3 << 8
92 #endif
93 #if defined USE_AD0_7
94  | 3 << 10
95 #endif
96 #if defined USE_AD1_0
97  | 3 << 12
98 #endif
99 #if defined USE_AD1_1
100  | 3 << 16
101 #endif
102 #if defined USE_AD1_2
103  | 3 << 20
104 #endif
105 #if defined USE_AD1_3
106  | 3 << 24
107 #endif
108 #if defined USE_AD1_4
109  | 3 << 26
110 #endif
111 #if defined USE_AD1_5
112  | 3 << 30
113 #endif
114  ;
115 
116 static const uint32_t ADC_PINSEL1_ONES = 0
117 #if defined USE_AD0_0
118  | 1 << 22
119 #endif
120 #if defined USE_AD0_1
121  | 1 << 24
122 #endif
123 #if defined USE_AD0_2
124  | 1 << 26
125 #endif
126 #if defined USE_AD0_3
127  | 1 << 28
128 #endif
129 #if defined USE_AD0_4
130  | 1 << 18
131 #endif
132 #if defined USE_AD0_5
133  | 1 << 20
134 #endif
135 #if defined USE_AD1_6
136  | 2 << 10
137 #endif
138 #if defined USE_AD1_7
139  | 1 << 12
140 #endif
141  ;
142 
143 #ifdef USE_AD0
144 static const uint32_t ADC_AD0CR_SEL_HW_SCAN = 0
145 #if defined USE_AD0_0
146  | 1 << 0
147 #endif
148 #if defined USE_AD0_1
149  | 1 << 1
150 #endif
151 #if defined USE_AD0_2
152  | 1 << 2
153 #endif
154 #if defined USE_AD0_3
155  | 1 << 3
156 #endif
157 #if defined USE_AD0_4
158  | 1 << 4
159 #endif
160 #if defined USE_AD0_5
161  | 1 << 5
162 #endif
163 #if defined USE_AD0_6
164  | 1 << 6
165 #endif
166 #if defined USE_AD0_7
167  | 1 << 7
168 #endif
169  ;
170 #endif
171 
172 #ifdef USE_AD1
173 static const uint32_t ADC_AD1CR_SEL_HW_SCAN = 0
174 #if defined USE_AD1_0
175  | 1 << 0
176 #endif
177 #if defined USE_AD1_1
178  | 1 << 1
179 #endif
180 #if defined USE_AD1_2
181  | 1 << 2
182 #endif
183 #if defined USE_AD1_3
184  | 1 << 3
185 #endif
186 #if defined USE_AD1_4
187  | 1 << 4
188 #endif
189 #if defined USE_AD1_5
190  | 1 << 5
191 #endif
192 #if defined USE_AD1_6
193  | 1 << 6
194 #endif
195 #if defined USE_AD1_7
196  | 1 << 7
197 #endif
198  ;
199 #endif
200 
201 void adc_init(void)
202 {
203 
204  /* connect pins for selected ADCs */
207 
208 #ifdef USE_AD0
209  /* FIXME: this needs to be investigated, we should run just below 4.5MHz,
210  but we are a lot slower (e.g. 58.6kHz with PCLK = 15MHz), see
211  lpc_vor_convertions.c for right timing code */
212  /* setup hw scan - PCLK/256 ( 58.6kHz/117.2kHz/234.4kHz ) - BURST ON */
213  AD0CR = ADC_AD0CR_SEL_HW_SCAN | 0xFF << 8 | 1 << 16 | 0x01 << 21 ;
214  /* AD0 selected as IRQ */
216  /* AD0 interrupt enabled */
218  /* AD0 interrupt as VIC2 */
219  _VIC_CNTL(AD0_VIC_SLOT) = VIC_ENABLE | VIC_AD0;
220  _VIC_ADDR(AD0_VIC_SLOT) = (uint32_t)adcISR0;
221 #endif
222 
223 #ifdef USE_AD1
224  /* FIXME: this needs to be investigated, we should run just below 4.5MHz,
225  but we are a lot slower (e.g. 58.6kHz with PCLK = 15MHz), see
226  lpc_vor_convertions.c for right timing code */
227  /* setup hw scan - PCLK/256 ( 58.6kHz/117.2kHz/234.4kHz ) - BURST ON */
228  AD1CR = ADC_AD1CR_SEL_HW_SCAN | 0xFF << 8 | 1 << 16 | 0x01 << 21 ;
229  /* AD1 selected as IRQ */
231  /* AD1 interrupt enabled */
233  /* AD1 interrupt as VIC2 */
234  _VIC_CNTL(AD1_VIC_SLOT) = VIC_ENABLE | VIC_AD1;
235  _VIC_ADDR(AD1_VIC_SLOT) = (uint32_t)adcISR1;
236 #endif
237 
238 }
239 
240 
241 void adcISR0(void)
242 {
243  ISR_ENTRY();
244  uint32_t tmp = AD0GDR;
245  uint8_t channel = (uint8_t)(tmp >> 24) & 0x07;
246  uint16_t value = (uint16_t)(tmp >> 6) & 0x03FF;
247  adc0_val[channel] = value;
248 
249  struct adc_buf *buf = buffers[channel];
250  if (buf) {
251  uint8_t new_head = buf->head + 1;
252  if (new_head >= buf->av_nb_sample) { new_head = 0; }
253  buf->sum -= buf->values[new_head];
254  buf->values[new_head] = value;
255  buf->sum += value;
256  buf->head = new_head;
257  }
258 
259  VICVectAddr = 0x00000000; // clear this interrupt from the VIC
260  ISR_EXIT(); // recover registers and return
261 }
262 
263 void adcISR1(void)
264 {
265  ISR_ENTRY();
266  uint32_t tmp = AD1GDR;
267  uint8_t channel = (uint8_t)(tmp >> 24) & 0x07;
268  uint16_t value = (uint16_t)(tmp >> 6) & 0x03FF;
269  adc1_val[channel] = value;
270  struct adc_buf *buf = buffers[channel + NB_ADC];
271  if (buf) {
272  uint8_t new_head = buf->head + 1;
273  if (new_head >= buf->av_nb_sample) { new_head = 0; }
274  buf->sum -= buf->values[new_head];
275  buf->values[new_head] = value;
276  buf->sum += value;
277  buf->head = new_head;
278  }
279 
280  VICVectAddr = 0x00000000; // clear this interrupt from the VIC
281  ISR_EXIT(); // recover registers and return
282 }
uint8_t av_nb_sample
Definition: adc.h:57
#define VICIntSelect
Definition: LPC21xx.h:430
unsigned short uint16_t
Definition: types.h:16
#define VIC_AD0
Definition: lpcVIC.h:88
volatile uint16_t adc0_val[NB_ADC]
Definition: adc_arch.c:53
#define _VIC_CNTL(idx)
Definition: armVIC.h:19
static const uint32_t ADC_PINSEL1_ONES
Definition: adc_arch.c:116
void adc_buf_channel(uint8_t adc_channel, struct adc_buf *s, uint8_t av_nb_sample)
Link between ChibiOS ADC drivers and Paparazzi adc_buffers.
Definition: adc_arch.c:281
uint32_t sum
Definition: adc.h:54
#define NB_ADC
8 ADCs for bank 0, others for bank 2
Definition: adc_arch.h:41
uint8_t head
Definition: adc.h:56
void adcISR1(void)
Definition: adc_arch.c:263
arch independent ADC (Analog to Digital Converter) API
#define _VIC_ADDR(idx)
Definition: armVIC.h:20
Generic interface for all ADC hardware drivers, independent from microcontroller architecture.
Definition: adc.h:53
volatile uint16_t adc1_val[NB_ADC]
Definition: adc_arch.c:54
#define AD0CR
Definition: LPC21xx.h:356
#define AD1CR
Definition: LPC21xx.h:373
#define VICVectAddr
Definition: LPC21xx.h:436
unsigned long uint32_t
Definition: types.h:18
void adcISR0(void)
Definition: adc_arch.c:241
static const uint32_t ADC_PINSEL0_ONES
Definition: adc_arch.c:89
#define VIC_BIT(chan)
Definition: lpcVIC.h:105
uint16_t values[MAX_AV_NB_SAMPLE]
Definition: adc.h:55
#define PINSEL0
Definition: LPC21xx.h:347
static struct adc_buf * buffers[NB_ADC *2]
First NB_ADC for bank 0, others for bank 2.
Definition: adc_arch.c:51
unsigned char uint8_t
Definition: types.h:14
#define ISR_EXIT()
Definition: armVIC.h:61
#define VICIntEnable
Definition: LPC21xx.h:431
#define PINSEL1
Definition: LPC21xx.h:348
#define VIC_AD1
Definition: lpcVIC.h:91
void adc_init(void)
Adc init.
Definition: adc_arch.c:304
static uint8_t channel
Definition: ADS8344.c:80
#define ISR_ENTRY()
Definition: armVIC.h:40
#define AD1GDR
Definition: LPC21xx.h:374
#define VIC_ENABLE
Definition: lpcVIC.h:102
#define AD0GDR
Definition: LPC21xx.h:357