HWA
Bare metal programming with style
adc_2.h
Go to the documentation of this file.
1 
2 /* This file is part of the HWA project.
3  * Copyright (c) 2012,2015 Christophe Duparquet.
4  * All rights reserved. Read LICENSE.TXT for details.
5  */
6 
12 /* Base class
13  */
14 #include "adx_2.h"
15 
97 #define hwa_configure__adc , _hwa_cfadc
98 
99 /* Mandatory parameter `clock`
100  */
101 #define _hwa_cfadc(o,a,k,...) \
102  do { \
103  uint8_t gain __attribute__((unused)) = 1 ; \
104  _hwa_write(o,en,1); /* enable the ADC */ \
105  HW_BW(_hwa_cfadcck,clock,k)(o,k,__VA_ARGS__,,); \
106  } while(0)
107 
108 
109 /* Mandatory parameter 'clock'
110  */
111 #define _hwa_cfadcck0(o,k,...) HW_E(HW_EM_AN(k,clock))
112 #define _hwa_cfadcck1(o,k,v,...) HW_BV(_hwa_cfadcck1,adxclock_,v,o)(o,v,__VA_ARGS__) // Push
113 #define _hwa_cfadcck10(v,o) HW_E(HW_EM_VAL(v,clock,(min, max, ioclk/2**(1..7)))) HW_EAT // Pop
114 #define _hwa_cfadcck11(f,v,o) _hwa_write(o,ps,f(v)); _hwa_cfadctrg // Pop
115 
116 /* Mandatory parameter 'trigger'
117  */
118 #define _hwa_cfadctrg(o,v,k,...) HW_BW(_hwa_cfadctrg,trigger,k)(o,v,__VA_ARGS__)
119 #define _hwa_cfadctrg0(o,k,...) HW_E(HW_EM_AN(k,trigger))
120 #define _hwa_cfadctrg1(o,k,v,...) HW_B(_hwa_cfadctrg2, _hw_par v)(o,v,__VA_ARGS__)
121 
122 /* "manual" or "auto"
123  */
124 #define _hwa_cfadctrg20(o,v,...) HW_BV(_hwa_cfadctrg20,adctrg_,v,o)(o,v,__VA_ARGS__) // Push
125 #define _hwa_cfadctrg201(_ate,_ts,o) _hwa_write(o,ate,_ate); _hwa_write(o,ts,_ts); _hwa_cfadcref
126 #define _hwa_cfadctrg200(v,...) HW_E(HW_EM_VAL(v,trigger,(manual, auto, (int0,irq), (acmp0,irq), \
127  (counter0,compare0,irq), (counter0,overflow,irq), \
128  (counter1,compare1,irq), (counter1,overflow,irq), \
129  (counter1,capture0,irq)))); HW_EAT // Pop
130 /* IRQs
131  */
132 #define _hwa_cfadctrg21(o,v,...) _hwa_cfadctrg22((HW_X(v)),o,v,__VA_ARGS__)
133 #define _hwa_cfadctrg22(...) _hwa_cfadctrg23(__VA_ARGS__)
134 #define _hwa_cfadctrg23(d,...) HW_BW(_hwa_cfadctrg3,_irq,HW_RP d)(d,__VA_ARGS__)
135 #define _hwa_cfadctrg30(d,o,v,...) _hwa_cfadctrg200(v,)(o,v,__VA_ARGS__) // Push
136 #define _hwa_cfadctrg31(d,o,v,...) HW_BV(_hwa_cfadctrg20,adctrg_,HW_A1 d,)(o,v,__VA_ARGS__) // Push
137 
138 #define _hw_adctrg_manual , 0, 0 /* , ate, ts */
139 #define _hw_adctrg_auto , 1, 0
140 #define _hw_adctrg_acmp0_irq , 1, 1
141 #define _hw_adctrg_int0_irq , 1, 2
142 #define _hw_adctrg_counter0_compare0_irq , 1, 3
143 #define _hw_adctrg_counter0_overflow_irq , 1, 4
144 #define _hw_adctrg_counter0_compare1_irq , 1, 5
145 #define _hw_adctrg_pcic0 , 1, 6
146 
147 /* Mandatory parameter 'vref'
148  */
149 #define _hwa_cfadcref(o,v,k,...) HW_BW(_hwa_cfadcref,vref,k)(o,k,__VA_ARGS__)
150 #define _hwa_cfadcref0(o,k,...) HW_E(HW_EM_AN(k,vref))
151 #define _hwa_cfadcref1(o,k,v,...) HW_B(_hwa_cfadcref2, _hw_par v)(o,v,__VA_ARGS__)
152 
153 /* "bandgap_1100mV"
154  */
155 #define _hwa_cfadcref20(o,v,...) HW_BV(_hwa_cfadcref20,adcref_,v,o)(o,v,__VA_ARGS__) // Push
156 #define _hwa_cfadcref201(v,o) _hwa_write(o,refs,v); _hwa_cfadcal // Pop
157 #define _hwa_cfadcref200(v,...) HW_E(HW_EM_VAL(v,vref,(vcc, (pin,aref), bandgap_1100mV, \
158  bandgap_2560mV, bandgap_2560mV_aref))) HW_EAT // Pop
159 
160 /* vcc, (pin,aref)
161  */
162 #define _hwa_cfadcref21(o,v,...) _hwa_cfadcref22((HW_X(v)),o,v,__VA_ARGS__)
163 #define _hwa_cfadcref22(...) _hwa_cfadcref23(__VA_ARGS__)
164 #define _hwa_cfadcref23(d,...) HW_BW(_hwa_cfadcref3,_pin,HW_RP d)(d,__VA_ARGS__)
165 #define _hwa_cfadcref30(d,o,v,...) _hwa_cfadcref200(v,)(o,v,__VA_ARGS__) // Push
166 #define _hwa_cfadcref31(d,o,v,...) HW_BV(_hwa_cfadcref20,adcref_,HW_A1 d,o)(o,v,__VA_ARGS__) // Push
167 
168 #define _hw_adcref_vcc , 0 /* , refs */
169 #define _hw_adcref_pin_aref , 1
170 #define _hw_adcref_bandgap_1100mV , 2
171 #define _hw_adcref_bandgap_2560mV , 6
172 #define _hw_adcref_bandgap_2560mV_aref , 7
173 
174 /* Optionnal parameter 'align'
175  */
176 #define _hwa_cfadcal(o,v,k,...) HW_BW(_hwa_cfadcal,align,k)(o,k,__VA_ARGS__)
177 #define _hwa_cfadcal0 _hwa_cfadcpo
178 #define _hwa_cfadcal1(o,k,v,...) HW_BV(_hwa_cfadcal1,adcal_,v,o)(o,v,__VA_ARGS__) // Push
179 #define _hwa_cfadcal10(v,o) HW_E(HW_EM_VOAL(v,align,(left,right))) HW_EAT // Pop
180 #define _hwa_cfadcal11(v,o) _hwa_write(o,lar,v); _hwa_cfadcal12 // Pop
181 #define _hwa_cfadcal12(o,v,k,...) _hwa_cfadcpo(o,k,__VA_ARGS__)
182 
183 #define _hw_adcal_left , 1 /* , lar */
184 #define _hw_adcal_right , 0
185 
186 /* Optionnal parameter `polarity`
187  */
188 #define _hwa_cfadcpo(o,k,...) HW_BW(_hwa_cfadcpo,polarity,k)(o,k,__VA_ARGS__)
189 #define _hwa_cfadcpo0 _hwa_cfadcgn
190 #define _hwa_cfadcpo1(o,k,v,...) HW_BV(_hwa_cfadcpo1,adcpo_,v,o)(o,v,__VA_ARGS__) // PUSH
191 #define _hwa_cfadcpo10(v,o) HW_E(HW_EM_VOAL(v,polarity,(unipolar,bipolar))) HW_EAT // POP
192 #define _hwa_cfadcpo11(v,o) _hwa_write(o,bin,v); _hwa_cfadcgn // POP
193 
194 #define _hw_adcpo_unipolar , 0 /* , bin */
195 #define _hw_adcpo_bipolar , 1
196 
197 /* Optionnal parameter `gain`
198  */
199 #define _hwa_cfadcgn(o,k,...) HW_BW(_hwa_cfadcgn,gain,k)(o,k,__VA_ARGS__)
200 #define _hwa_cfadcgn0 _hwa_cfadcin // -> 'input'
201 #define _hwa_cfadcgn1(o,k0,v,k,...) gain = (uint8_t)(v); _hwa_cfadcpi(o,k,__VA_ARGS__) // -> 'positive_input'
202 
203 /* Optionnal parameter `input`
204  */
205 #define _hwa_cfadcin(o,k,...) HW_BW(_hwa_cfadcin,input,k)(o,k,__VA_ARGS__)
206 #define _hwa_cfadcin0 _hwa_cfadcpi
207 #define _hwa_cfadcin1(o,k,v,...) HW_BV(_hwa_cfadcin1,adcin_,v,o)(o,v,__VA_ARGS__) // PUSH
208 #define _hwa_cfadcin10(v,o) HW_E(HW_EM_VAL(v,input,((pin,adc0..3),temperature,bandgap,gnd))) HW_EAT // POP
209 #define _hwa_cfadcin11(v,o) _hwa_write(o,mux,v); _hwa_cfadcin12 // Pop
210 #define _hwa_cfadcin12(o,v,...) if ( gain != 1 ) HWA_E(HW_EM_AVM(gain,1)); HW_EOL(__VA_ARGS__)
211 
212 #define _hwa_cfadcin1_(o,v,...) _hwa_write(o,mux,_hw_adcmuxse(HW_ADDRESS(v))); HW_EOL(__VA_ARGS__)
213 
214 #define _hw_adcin_bandgap , 12 /* , mux */
215 #define _hw_adcin_gnd , 13
216 #define _hw_adcin_temperature , 15
217 
218 /* Compute the mux register value from input pin address
219  */
220 HW_INLINE uint8_t _hw_adcmuxse( uint32_t a )
221 {
222  if ( a==HW_ADDRESS(pin_adc0) ) return 0;
223  if ( a==HW_ADDRESS(pin_adc1) ) return 1;
224  if ( a==HW_ADDRESS(pin_adc2) ) return 2;
225  if ( a==HW_ADDRESS(pin_adc3) ) return 3;
226  HWA_E(HW_EM_AVL(input,((pin,adc0..3),temperature,bandgap,gnd)));
227  return 0 ;
228 }
229 
230 /* Process 'positive_input' & 'negative_input' for differential mode
231  */
232 #define _hwa_cfadcpi(o,k,...) HW_BW(_hwa_cfadcpi,positive_input,k)(o,k,__VA_ARGS__)
233 #define _hwa_cfadcpi0(o,k,...) HW_E(HW_EM_AN(k,positive_input))
234 #define _hwa_cfadcpi1(o,k0,v,k,...) \
235  uint8_t pi __attribute__((unused)) = _hw_adcin(HW_ADDRESS(v)); \
236  HW_BW(_hwa_cfadcni,negative_input,k)(o,k,__VA_ARGS__)
237 #define _hwa_cfadcni0(o,k,...) HW_E(HW_EM_AN(k,negative_input))
238 #define _hwa_cfadcni1(o,k,v,...) \
239  uint8_t ni __attribute__((unused)) = _hw_adcin(HW_ADDRESS(v)); \
240  _hwa_write(o,mux,_hw_adcmuxdi(pi,ni,gain)); HW_EOL(__VA_ARGS__)
241 
242 /* Compute the mux register value from inputs and gain
243  */
244 HW_INLINE uint8_t _hw_adcmuxdi ( uint8_t pos, uint8_t neg, uint8_t gain )
245 {
246  if ( gain != 1 && gain != 20 ) {
247  HWA_E(HW_EM_AVL(gain,(1, 20)));
248  return 0;
249  }
250 
251  if ( pos==0 ) {
252  if ( neg==0 )
253  return 0x08 + (gain==20);
254  else if ( neg==1 )
255  return 0x0A + (gain==20);
256  HWA_E(HW_EM_AVL(negative_input,((pin,adc0), (pin,adc1))));
257  }
258  else if ( pos==2 ) {
259  if ( neg==2 )
260  return 0x04 + (gain==20);
261  else if ( neg==3 )
262  return 0x06 + (gain==20);
263  HWA_E(HW_EM_AVL(negative_input,((pin,adc2), (pin,adc3))));
264  }
265  else
266  HWA_E(HW_EM_AVL(positive_input,((pin,adc0), (pin,adc2))));
267  return 0;
268 }
269 
270 
271 /* Power management
272  */
273 #define hw_power__adc , _hw_power
274 #define hwa_power__adc , _hwa_power
275 
276 
290 #define hw_enable__adc , _hw_enable_adx_
291 #define hwa_enable__adc , _hwa_enable_adx_
292 
293 
307 #define hw_disable__adc , _hw_disable_adx_
308 #define hwa_disable__adc , _hwa_disable_adx_
309 
310 
324 #define hw_trigger__adc , _hw_trigger_adx_
325 #define hwa_trigger__adc , _hwa_trigger_adx_
326 
327 
337 #define hw_read__adc , _hw_rdadx_
338 
349 #define hw_read_atomic__adc , _hw_ardadx_
350 
351 
374 #define hw_stat__adc , _hw_stat_adx_
375 
376 
377 /*******************************************************************************
378  * *
379  * Context management *
380  * *
381  *******************************************************************************/
382 
383 #define _hwa_setup__adc(o,a) _hwa_setup__adx_(o)
384 #define _hwa_init__adc(o,a) _hwa_init__adx_(o)
385 #define _hwa_commit__adc(o,a) _hwa_commit__adx_(o)
386 
387 
HWA_E
#define HWA_E(...)
Trigger an error after code optimization.
Definition: hwa_2.h:17
HW_ADDRESS
#define HW_ADDRESS(...)
Returns the address of an object or -1 if the object does not exist.
Definition: hwa_1.h:454
adx_2.h
10-bit analog to digital converter common methods