HWA
Bare metal programming with style
ada_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 
16 /* #define hw_prescaler_max__ada , hw_adx_prescaler_max */
17 /* #define hw_prescaler_min__ada , hw_adx_prescaler_min */
18 
97 #define hwa_configure__ada , _hwa_cfada
98 
99 /* Mandatory parameter `clock`
100  */
101 #define _hwa_cfada(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_cfadack,clock,k)(o,k,__VA_ARGS__,,); \
106  } while(0)
107 
108 
109 /* Mandatory parameter 'clock'
110  */
111 #define _hwa_cfadack0(o,k,...) HW_E(HW_EM_AN(k,clock))
112 #define _hwa_cfadack1(o,k,v,...) HW_BV(_hwa_cfadack1,adxclock_,v,o)(o,v,__VA_ARGS__) // Push
113 #define _hwa_cfadack10(v,o) HW_E(HW_EM_VAL(v,clock,(min, max, ioclk/2**(1..7)))) HW_EAT // Pop
114 #define _hwa_cfadack11(f,v,o) _hwa_write(o,ps,f(v)); _hwa_cfadatrg // Pop
115 
116 /* Mandatory parameter 'trigger'
117  */
118 #define _hwa_cfadatrg(o,v,k,...) HW_BW(_hwa_cfadatrg,trigger,k)(o,v,__VA_ARGS__)
119 #define _hwa_cfadatrg0(o,k,...) HW_E(HW_EM_AN(k,trigger))
120 #define _hwa_cfadatrg1(o,k,v,...) HW_B(_hwa_cfadatrg2, _hw_par v)(o,v,__VA_ARGS__)
121 
122 /* "manual" or "auto"
123  */
124 #define _hwa_cfadatrg20(o,v,...) HW_BV(_hwa_cfadatrg20,adatrg_,v,o)(o,v,__VA_ARGS__) // Push
125 #define _hwa_cfadatrg201(_ate,_ts,o) _hwa_write(o,ate,_ate); _hwa_write(o,ts,_ts); _hwa_cfadaref
126 #define _hwa_cfadatrg200(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_cfadatrg21(o,v,...) _hwa_cfadatrg22((HW_X(v)),o,v,__VA_ARGS__)
133 #define _hwa_cfadatrg22(...) _hwa_cfadatrg23(__VA_ARGS__)
134 #define _hwa_cfadatrg23(d,...) HW_BW(_hwa_cfadatrg3,_irq,HW_RP d)(d,__VA_ARGS__)
135 #define _hwa_cfadatrg30(d,o,v,...) _hwa_cfadatrg200(v,)(o,v,__VA_ARGS__) // Push
136 #define _hwa_cfadatrg31(d,o,v,...) HW_BV(_hwa_cfadatrg20,adatrg_,HW_A1 d,)(o,v,__VA_ARGS__) // Push
137 
138 #define _hw_adatrg_manual , 0, 0 /* , ate, ts */
139 #define _hw_adatrg_auto , 1, 0
140 #define _hw_adatrg_acmp0_irq , 1, 1
141 #define _hw_adatrg_int0_irq , 1, 2
142 #define _hw_adatrg_counter0_compare0_irq , 1, 3
143 #define _hw_adatrg_counter0_overflow_irq , 1, 4
144 #define _hw_adatrg_counter1_compare1_irq , 1, 5
145 #define _hw_adatrg_counter1_overflow_irq , 1, 6
146 #define _hw_adatrg_counter1_capture0_irq , 1, 7
147 
148 /* Mandatory parameter 'vref'
149  */
150 #define _hwa_cfadaref(o,v,k,...) HW_BW(_hwa_cfadaref,vref,k)(o,k,__VA_ARGS__)
151 #define _hwa_cfadaref0(o,k,...) HW_E(HW_EM_AN(k,vref))
152 #define _hwa_cfadaref1(o,k,v,...) HW_B(_hwa_cfadaref2, _hw_par v)(o,v,__VA_ARGS__)
153 
154 /* "bandgap_1100mV"
155  */
156 #define _hwa_cfadaref20(o,v,...) HW_BV(_hwa_cfadaref20,adaref_,v,o)(o,v,__VA_ARGS__) // Push
157 #define _hwa_cfadaref201(v,o) _hwa_write(o,refs,v); _hwa_cfadaal // Pop
158 #define _hwa_cfadaref200(v,...) HW_E(HW_EM_VAL(v,vref,(vcc, (pin,aref), bandgap_1100mV))) HW_EAT // Pop
159 
160 /* vcc, (pin,aref)
161  */
162 #define _hwa_cfadaref21(o,v,...) _hwa_cfadaref22((HW_X(v)),o,v,__VA_ARGS__)
163 #define _hwa_cfadaref22(...) _hwa_cfadaref23(__VA_ARGS__)
164 #define _hwa_cfadaref23(d,...) HW_BW(_hwa_cfadaref3,_pin,HW_RP d)(d,__VA_ARGS__)
165 #define _hwa_cfadaref30(d,o,v,...) _hwa_cfadaref200(v,)(o,v,__VA_ARGS__) // Push
166 #define _hwa_cfadaref31(d,o,v,...) HW_BV(_hwa_cfadaref20,adaref_,HW_A1 d,o)(o,v,__VA_ARGS__) // Push
167 
168 #define _hw_adaref_vcc , 0 /* , refs */
169 #define _hw_adaref_pin_aref , 1
170 #define _hw_adaref_bandgap_1100mV , 2
171 
172 /* Optionnal parameter 'align'
173  */
174 #define _hwa_cfadaal(o,v,k,...) HW_BW(_hwa_cfadaal,align,k)(o,k,__VA_ARGS__)
175 #define _hwa_cfadaal0 _hwa_cfadapo
176 #define _hwa_cfadaal1(o,k,v,...) HW_BV(_hwa_cfadaal1,adaal_,v,o)(o,v,__VA_ARGS__) // Push
177 #define _hwa_cfadaal10(v,o) HW_E(HW_EM_VOAL(v,align,(left,right))) HW_EAT // Pop
178 #define _hwa_cfadaal11(v,o) _hwa_write(o,lar,v); _hwa_cfadaal12 // Pop
179 #define _hwa_cfadaal12(o,v,k,...) _hwa_cfadapo(o,k,__VA_ARGS__)
180 
181 #define _hw_adaal_left , 1 /* , lar */
182 #define _hw_adaal_right , 0
183 
184 /* Optionnal parameter `polarity`
185  */
186 #define _hwa_cfadapo(o,k,...) HW_BW(_hwa_cfadapo,polarity,k)(o,k,__VA_ARGS__)
187 #define _hwa_cfadapo0 _hwa_cfadagn
188 #define _hwa_cfadapo1(o,k,v,...) HW_BV(_hwa_cfadapo1,adapo_,v,o)(o,v,__VA_ARGS__) // PUSH
189 #define _hwa_cfadapo10(v,o) HW_E(HW_EM_VOAL(v,polarity,(unipolar,bipolar))) HW_EAT // POP
190 #define _hwa_cfadapo11(v,o) _hwa_write(o,bin,v); _hwa_cfadagn // POP
191 
192 #define _hw_adapo_unipolar , 0 /* , bin */
193 #define _hw_adapo_bipolar , 1
194 
195 /* Optionnal parameter `gain`
196  */
197 #define _hwa_cfadagn(o,k,...) HW_BW(_hwa_cfadagn,gain,k)(o,k,__VA_ARGS__)
198 #define _hwa_cfadagn0 _hwa_cfadain // -> 'input'
199 #define _hwa_cfadagn1(o,k0,v,k,...) gain = (uint8_t)(v); _hwa_cfadapi(o,k,__VA_ARGS__) // -> 'positive_input'
200 
201 /* Optionnal parameter `input`
202  */
203 #define _hwa_cfadain(o,k,...) HW_BW(_hwa_cfadain,input,k)(o,k,__VA_ARGS__)
204 #define _hwa_cfadain0 _hwa_cfadapi
205 #define _hwa_cfadain1(o,k,v,...) HW_BV(_hwa_cfadain1,adain_,v,o)(o,v,__VA_ARGS__) // PUSH
206 #define _hwa_cfadain10(v,o) HW_E(HW_EM_VAL(v,input,((pin,ada0..3),temperature,bandgap,gnd))) HW_EAT // POP
207 #define _hwa_cfadain11(v,o) _hwa_write(o,mux,v); _hwa_cfadain12 // Pop
208 #define _hwa_cfadain12(o,v,...) if ( gain != 1 ) HWA_E(HW_EM_AVM(gain,1)); HW_EOL(__VA_ARGS__)
209 
210 #define _hwa_cfadain1_(o,v,...) _hwa_write(o,mux,_hw_adamuxse(HW_ADDRESS(v))); HW_EOL(__VA_ARGS__)
211 
212 #define _hw_adain_gnd , 0x20 /* , mux */
213 #define _hw_adain_bandgap , 0x21
214 #define _hw_adain_temperature , 0x22
215 
216 /* Compute the mux register value from input pin address
217  */
218 HW_INLINE uint8_t _hw_adamuxse( uint32_t a )
219 {
220  if ( a==HW_ADDRESS(pin_adc0) ) return 0;
221  if ( a==HW_ADDRESS(pin_adc1) ) return 1;
222  if ( a==HW_ADDRESS(pin_adc2) ) return 2;
223  if ( a==HW_ADDRESS(pin_adc3) ) return 3;
224  if ( a==HW_ADDRESS(pin_adc4) ) return 4;
225  if ( a==HW_ADDRESS(pin_adc5) ) return 5;
226  if ( a==HW_ADDRESS(pin_adc6) ) return 6;
227  if ( a==HW_ADDRESS(pin_adc7) ) return 7;
228  HWA_E(HW_EM_AVL(input,((pin,adc0..7),temperature,bandgap,gnd)));
229  return 0 ;
230 }
231 
232 /* Process 'positive_input' & 'negative_input' for differential mode
233  */
234 #define _hwa_cfadapi(o,k,...) HW_BW(_hwa_cfadapi,positive_input,k)(o,k,__VA_ARGS__)
235 #define _hwa_cfadapi0(o,k,...) HW_E(HW_EM_AN(k,positive_input))
236 #define _hwa_cfadapi1(o,k0,v,k,...) \
237  uint8_t pi __attribute__((unused)) = _hw_adain(HW_ADDRESS(v)); \
238  HW_BW(_hwa_cfadani,negative_input,k)(o,k,__VA_ARGS__)
239 #define _hwa_cfadani0(o,k,...) HW_E(HW_EM_AN(k,negative_input))
240 #define _hwa_cfadani1(o,k,v,...) \
241  uint8_t ni __attribute__((unused)) = _hw_adain(HW_ADDRESS(v)); \
242  _hwa_write(o,mux,_hw_adamuxdi(pi,ni,gain)); HW_EOL(__VA_ARGS__)
243 
244 /* Compute the mux register value from inputs and gain
245  */
246 HW_INLINE uint8_t _hw_adamuxdi ( uint8_t pos, uint8_t neg, uint8_t gain )
247 {
248  if ( gain != 1 && gain != 20 ) {
249  HWA_E(HW_EM_AVL(gain,(1, 20)));
250  return 0;
251  }
252 
253  if ( pos==0 ) {
254  if ( neg==0 ) {
255  if ( gain != 20 )
256  HWA_E(HW_EM_AVM(gain,20));
257  else
258  return 0x23 ;
259  }
260  else if ( neg==1 )
261  return 0x08 + (gain==20);
262  else if ( neg==3 )
263  return 0x0A + (gain==20);
264  HWA_E(HW_EM_AVL(negative_input,((pin,adc0), (pin,adc1), (pin,adc3))));
265  }
266  else if ( pos==1 ) {
267  if ( neg==0 )
268  return 0x28 + (gain==20);
269  else if ( neg==2 )
270  return 0x0C + (gain==20);
271  else if ( neg==3 )
272  return 0x0E + (gain==20);
273  HWA_E(HW_EM_AVL(negative_input,((pin,adc0), (pin,adc2), (pin,adc3))));
274  }
275  else if ( pos==2 ) {
276  if ( neg==1 )
277  return 0x2C + (gain==20);
278  else if ( neg==3 )
279  return 0x10 + (gain==20);
280  HWA_E(HW_EM_AVL(negative_input,((pin,adc1), (pin,adc3))));
281  }
282  else if ( pos==3 ) {
283  const uint8_t v[8] = { 0x2A, 0x2E, 0x30, 0x24, 0x12, 0x14, 0x16, 0x18 };
284  return v[neg] + (gain==20);
285  }
286  else if ( pos==4 ) {
287  if ( neg==3 )
288  return 0x32 + (gain==20);
289  else if ( neg==5 )
290  return 0x1A + (gain==20);
291  HWA_E(HW_EM_AVL(negative_input,((pin,adc3), (pin,adc5))));
292  }
293  else if ( pos==5 ) {
294  if ( neg==3 )
295  return 0x34 + (gain==20);
296  else if ( neg==4 )
297  return 0x3A + (gain==20);
298  else if ( neg==6 )
299  return 0x1C + (gain==20);
300  HWA_E(HW_EM_AVL(negative_input,((pin,adc3), (pin,adc4), (pin,adc6))));
301  }
302  else if ( pos==6 ) {
303  if ( neg==3 )
304  return 0x36 + (gain==20);
305  else if ( neg==5 )
306  return 0x3C + (gain==20);
307  else if ( neg==7 )
308  return 0x1E + (gain==20);
309  HWA_E(HW_EM_AVL(negative_input,((pin,adc3), (pin,adc5), (pin,adc7))));
310  }
311  else if ( pos==7 ) {
312  if ( neg==3 )
313  return 0x38 + (gain==20);
314  else if ( neg==6 )
315  return 0x3E + (gain==20);
316  else if ( neg==7 )
317  return 0x16 + (gain==20);
318  HWA_E(HW_EM_AVL(negative_input,((pin,adc3), (pin,adc6), (pin,adc7))));
319  }
320  else
321  HWA_E(HW_EM_AVL(positive_input,((pin,adc0..7))));
322  return 0;
323 }
324 
325 
326 /* Power management
327  */
328 #define hw_power__ada , _hw_power
329 #define hwa_power__ada , _hwa_power
330 
331 
345 #define hw_enable__ada , _hw_enable_adx_
346 #define hwa_enable__ada , _hwa_enable_adx_
347 
348 
362 #define hw_disable__ada , _hw_disable_adx_
363 #define hwa_disable__ada , _hwa_disable_adx_
364 
365 
379 #define hw_trigger__ada , _hw_trigger_adx_
380 #define hwa_trigger__ada , _hwa_trigger_adx_
381 
382 
392 #define hw_read__ada , _hw_rdadx_
393 
404 #define hw_read_atomic__ada , _hw_ardadx_
405 
406 
429 #define hw_stat__ada , _hw_stat_adx_
430 
431 
432 /*******************************************************************************
433  * *
434  * Context management *
435  * *
436  *******************************************************************************/
437 
438 #define _hwa_setup__ada(o,a) _hwa_setup__adx_(o)
439 #define _hwa_init__ada(o,a) _hwa_init__adx_(o)
440 #define _hwa_commit__ada(o,a) _hwa_commit__adx_(o)
441 
442 
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