HWA
Bare metal programming with style
hwa_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 
17 #define HWA_E(...) _HWA_E_2(__COUNTER__,__VA_ARGS__ [__FILE__:__LINE__])
18 #define _HWA_E_2(...) _HWA_E_3(__VA_ARGS__)
19 #define _HWA_E_3(num,...) \
20  do{ \
21  extern void __attribute__((error(#__VA_ARGS__))) hwa_##num(void); \
22  hwa_##num(); \
23  }while(0)
24 
25 extern uint8_t hw_foo();
26 
27 
37 #define hw_asm(...) __asm__ __volatile__(__VA_ARGS__)
38 
39 
40 #define hwa_begin_ , _hwa_begin_
41 #define hwa_begin_reset , _hwa_begin_reset
42 
43 
51 #define _hwa_begin_(g,...) HW_B(_hwa_begin_,g)(g,__VA_ARGS__)
52 #define _hwa_begin_0(g,...) HW_E(HW_EM_AI(g))
53 #define _hwa_begin_1(...) \
54  _hwa_check_optimizations(0); \
55  hwa_t hwa_st ; hwa_t *hwa = &hwa_st ; \
56  _hwa_setup_context(hwa) ; \
57  uint8_t hwa_xcommit = 0 /* Will warn if hwa(commit) is not called */
58 
59 
70 #define _hwa_begin_reset(r,g,...) HW_B(_hwa_begin_reset_,g)(g,__VA_ARGS__)
71 #define _hwa_begin_reset_0(r,g,...) HW_E(HW_EM_AI(g))
72 #define _hwa_begin_reset_1(...) \
73  _hwa_check_optimizations(0); \
74  hwa_t hwa_st ; hwa_t *hwa = &hwa_st ; \
75  _hwa_setup_context(hwa) ; \
76  _hwa_init_context(hwa) ; \
77  _hwa_nocommit_() ; \
78  uint8_t hwa_xcommit = 0
79 
80 
90 /* _hwa_commit_context() must be defined somewhere in the device-specific files.
91  */
92 #define _hwa_commit_(...) \
93  do { \
94  uint8_t foo __attribute__((unused)) = hwa_xcommit ; \
95  hwa->commit = 1 ; \
96  _hwa_commit_context(hwa); \
97  } while(0)
98 
99 #define hwa_commit_ , _hwa_commit_
100 
101 
110 #define _hwa_nocommit_(...) \
111  do { \
112  hwa->commit = 0 ; \
113  _hwa_commit_context(hwa); \
114  } while(0)
115 
116 #define hwa_nocommit_ , _hwa_nocommit_
117 
118 
128 #define HW_FC(...) _HW_FC(__VA_ARGS__)
129 #define _HW_FC(f,c,...) f##c(__VA_ARGS__,,)
130 
131 
140 #define _hw_read(o,r) HW_FC(_hw_read_,HW_X((o,r)),)
141 
142 #define _hw_read_(o,...) HW_E(HW_A0(__VA_ARGS__)) // Error message
143 
151 #define _hw_atomic_read(o,r) HW_FC(_hw_atomic_read_,HW_X((o,r)),)
152 
153 
154 #define hw_uint_t__r8 uint8_t
155 #define hw_uint_t__r16 uint16_t
156 #define hw_uint_t__r32 uint32_t
157 
158 
168 #define _hw_write(o,r,v) HW_FC(_hw_write_,HW_X((o,r)),v,)
169 
170 #define _hw_write_(o,...) HW_E(HW_A0(__VA_ARGS__)) // Error message
171 
181 #define _hwa_write(o,r,v) HW_FC(_hwa_write_,HW_X((o,r)),v,)
182 
183 #define _hwa_write_(o,...) HW_E(HW_A0(__VA_ARGS__)) // Error message
184 
185 
186 /* Read/write _mem8/_mem16 (memory positions)
187  * Used by _swuart to access dt0/dtn registers.
188  */
189 #define hw_read__mem8 , _hw_read_mem8
190 #define _hw_read_mem8(o,a,...) *a
191 
192 #define hw_read__mem16 , _hw_read_mem16
193 #define _hw_read_mem16(o,a,...) *a
194 
195 #define hw_write__mem8 , _hw_write_mem8
196 #define _hw_write_mem8(o,a,v,...) *a = (v)
197 
198 #define hw_write__mem16 , _hw_write_mem16
199 #define _hw_write_mem16(o,a,v,...) *a = (v)
200 
201 
202 /* Read/write memory of registers
203  */
204 #define hw_read__m11 , _hw_read__m11
205 #define _hw_read__m11(n,o,r,c,a,wm,fm,bn,bp,...) _hw_read_##c(a,bn,bp)
206 
207 #define hw_readnp__m11 , _hw_readnp__m11
208 #define _hw_readnp__m11(n,o,r,c,a,wm,fm,bn,bp,_n,_p,...) _hw_read_##c(a,_n,_p)
209 
210 #define hwa_write__m11 , _hwa_write__m11
211 
212 #define _hwa_write__m11(n,o,r,c,a,wm,fm,bn,bp,v,...) \
213  _hwa_write##c(&hwa->o.r,wm,fm,((1ULL<<bn)-1)<<bp,((unsigned long long)(v))<<bp)
214 
215 #define hw_write__m11 , _hw_write__m11
216 
217 #define _hw_write__m11(n,o,r,c,a,wm,fm,bn,bp,v,...) \
218  _hw_write_##c(a,wm,fm,bn,bp,v)
219 
220 #define hw_toggle__m11 , _hw_toggle__m11
221 
222 #define _hw_toggle__m11(n,o,r,c,a,wm,fm,bn,bp,...) \
223  _hw_write_##c(a,wm,fm,bn,bp,((1UL<<bn)-1)&(((1UL<<bn)-1)^_hw_read_##c(a,bn,bp)))
224 
225 #define _hw_write__m12(n,o,r,c,a,wm,fm,bn1,bp1,vp1,bn2,bp2,vp2,v,...) \
226  do{ \
227  hw_uint_t_##c val = v ; \
228  _hw_write##c( a, wm, fm, \
229  (((1ULL<<bn1)-1)<<bp1) | (((1ULL<<bn2)-1)<<bp2), \
230  (((val>>vp1)&((1<<bn1)-1))<<bp1) | (((val>>bp2)&((1<<bn2)-1))<<bp2)); \
231  }while(0)
232 
233 
234 #define hwa_write__m22 , _hwa_write__m22
235 
236 #define _hwa_write__m22( n, o, \
237  r1,c1,a1,wm1,fm1,bn1,bp1,vp1, \
238  r2,c2,a2,wm2,fm2,bn2,bp2,vp2, v, ... ) \
239  do { \
240  hw_uint_t_##c1 val = (v); \
241  _hwa_write_##c1(&hwa->o.r1, wm1,fm1, bn1,bp1, (val>>(vp1))&((1ULL<<bn1)-1)); \
242  _hwa_write_##c2(&hwa->o.r2, wm2,fm2, bn2,bp2, (val>>(vp2))&((1ULL<<bn2)-1)); \
243  } while(0)
244 
245 
246 /*
247  * @brief Write the register of an object
248  */
249 #define _hwa_write_o(c,o,r,v,...) _hwa_write(o,r,v) HW_EOL(__VA_ARGS__)
250 
251 
252 #define hwa_write__xb1 , _hwa__write__xb1
253 
254 #define _hwa_write__xb1(o,r,bn,bp,v) _hwa_write__xb1_2(hw_##o##_##r,o,r,bn,bp,v)
255 #define _hwa_write__xb1_2(...) _hwa_write__xb1_3(__VA_ARGS__)
256 #define _hwa_write__xb1_3(rc,ra,rwm,rfm,o,r,bn,bp,v) \
257  _hwa_write_##rc( &hwa->o.r, rwm,rfm, bn,bp, v )
258 
259 /* Added for atmel/avr/classes/io1a_2.h:
260  * _hwa(write,_##o##_##did, 1);
261  * _hwa_write(_##o##_##did, 1);
262  * -> _hwa__write__xb1(hw_shared, did, 1, 0, 1,);
263  * FIXME: keep?
264  */
265 #define _hwa__write__xb1(o,r,bn,bp,v,...) _hwa_write__xb1(o,r,bn,bp,v)
266 
267 
280 #define _hw_write_m(o,r,...) HW_FC(_hw_wrorm,HW_X((o,r)),__VA_ARGS__,)
281 
282 #define _hw_wrorm_m11(n,o,r,c,a,wm,fm,bn,bp,m,v,...) _hw_write##c(a,wm,fm,m,v)
283 
284 #define hw_writenp__m11 , _hw_writenp_m11
285 #define _hw_writenp_m11(oo,o,r,rc,ra,rwm,rfm,rbn,rbp,n,p,v,...) \
286  _hw_write##rc(ra,rwm,rfm,(((1U<<n)-1)<<p),((v)<<p))
287 
288 
298 #define _hwa_write_m(o,r,...) HW_FC(_hwa_wrorm,HW_X((o,r)),__VA_ARGS__,)
299 
300 #define _hwa_wrorm_m11(n,o,r,c,a,wm,fm,bn,bp,m,v,...) \
301  _hwa_write##c(&hwa->o.r,wm,fm,m,v)
302 
303 
313 #define hwa_writenp__m11 , _hwa_writenp_m11
314 #define _hwa_writenp_m11(oo,o,r,rc,ra,rwm,rfm,rbn,rbp,n,p,v,...) \
315  _hwa_write##rc(&hwa->o.r,rwm,rfm,(((1U<<n)-1)<<p),((v)<<p))
316 
317 
322 #define _hwa_setup_o(o) _hwa_setup00( o, hw_##o )
323 #define _hwa_setup00(...) _hwa_setup01(__VA_ARGS__)
324 #define _hwa_setup01(o,c,...) _hwa_setup_##c(o,__VA_ARGS__)
325 
326 
331 #define _hwa_init_o(o) _hwa_init00( o, hw_##o )
332 #define _hwa_init00(...) _hwa_init01(__VA_ARGS__)
333 #define _hwa_init01(o,c,...) _hwa_init_##c(o,__VA_ARGS__)
334 
335 
340 #define _hwa_solve_o(o) _hwa_solve00( o, hw_##o )
341 #define _hwa_solve00(...) _hwa_solve01(__VA_ARGS__)
342 #define _hwa_solve01(o,c,...) _hwa_solve_##c(o,__VA_ARGS__)
343 
344 
349 #define _hwa_commit_o(o) _hwa_commit00( o, hw_##o )
350 #define _hwa_commit00(...) _hwa_commit01(__VA_ARGS__)
351 #define _hwa_commit01(o,c,...) _hwa_commit_##c(o,__VA_ARGS__)
352 
353 
359 #define _hwa_setup_r(o,r) _hwa_setup_or02(HW_X((o,r)))
360 #define _hwa_setup_or02(...) _hwa_setup_or03(__VA_ARGS__)
361 #define _hwa_setup_or03(m,n,o,r,c,a,...) _hwa_setup_##c(&hwa->o.r, a)
362 
363 
369 #define _hwa_init_r(o,r,v) _hwa_init_reg_2(v,HW_X((o,r)))
370 #define _hwa_init_reg_2(...) _hwa_init_reg_3(__VA_ARGS__)
371 #define _hwa_init_reg_3(v,m,n,o,r,c,a,...) _hwa_set_##c(&hwa->o.r, v)
372 
373 
379 #define _hwa_commit_r(o,r) HW_FC(_hwa_commit,HW_X((o,r)))
380 
381 #define _hwa_commit_m11(n,o,r,c,a,wm,fm,bn,bp,...) _hwa_commit_##c(&hwa->o.r,wm,fm,hwa->commit)
382 
383 #define _hwa_nocommit_r(o,r) HW_FC(_hwa_nocommit,HW_X((o,r)))
384 
385 #define _hwa_nocommit_m11(n,o,r,c,a,wm,fm,bn,bp,...) _hwa_commit_##c(&hwa->o.r,wm,fm,0)
386 
387 
397 #define _hwa_mmask(o,r) HW_FC(_hwa_mmask_,HW_X(o,r))
398 
399 #define _hwa_mmask__m11(n,o,r,c,a,wm,fm,bn,bp,...) (((hwa->o.r.mmask)>>bp)&((1ULL<<bn)-1))
400 
401 
407 #define _hwa_mvalue(o,r) HW_FC(_hwa_mvalue_,HW_X(o,r))
408 
409 #define _hwa_mvalue__m11(n,o,r,c,a,wm,fm,bn,bp,...) (((hwa->o.r.mvalue)>>bp)&((1ULL<<bn)-1))
410 
411 
417 #define _hwa_ovalue(o,r) HW_FC(_hwa_ovalue_,HW_X(o,r))
418 
419 #define _hwa_ovalue__m11(n,o,r,c,a,wm,fm,bn,bp,...) (((hwa->o.r.ovalue)>>bp)&((1ULL<<bn)-1))
420 
421 
422 
423 HW_INLINE void _hwa_setup__r8 ( hwa_r8_t *r, intptr_t a )
424 {
425  r->a = a ;
426  r->mmask = 0 ;
427  r->mvalue = 0 ;
428  r->omask = 0 ;
429  r->ovalue = 0 ;
430 }
431 
432 HW_INLINE void _hwa_setup__r16 ( hwa_r16_t *r, intptr_t a )
433 {
434  r->a = a ;
435  r->mmask = 0 ;
436  r->mvalue = 0 ;
437  r->omask = 0 ;
438  r->ovalue = 0 ;
439 }
440 
441 HW_INLINE void _hwa_setup__r32 ( hwa_r32_t *r, intptr_t a )
442 {
443  r->a = a ;
444  r->mmask = 0 ;
445  r->mvalue = 0 ;
446  r->omask = 0 ;
447  r->ovalue = 0 ;
448 }
449 
450 
456 HW_INLINE void _hwa_set__r8 ( hwa_r8_t *r, uint8_t v )
457 {
458  if ( r->mmask )
459  HWA_E(HW_EM_COMMITRQ);
460 
461  r->mmask = 0xFF ;
462  r->mvalue = v ;
463 }
464 
465 HW_INLINE void _hwa_set__r16 ( hwa_r16_t *r, uint16_t v )
466 {
467  if ( r->mmask )
468  HWA_E(HW_EM_COMMITRQ);
469 
470  r->mmask = 0xFFFF ;
471  r->mvalue = v ;
472 }
473 
474 HW_INLINE void _hwa_set__r32 ( hwa_r32_t *r, uint32_t v )
475 {
476  if ( r->mmask )
477  HWA_E(HW_EM_COMMITRQ);
478 
479  r->mmask = 0xFFFFFFFF ;
480  r->mvalue = v ;
481 }
482 
483 
501 HW_INLINE void _hwa_write_r8 ( hwa_r8_t *r, uint8_t rwm, uint8_t rfm, uint8_t msk, uint8_t v )
502 {
503  if (v & ~msk)
504  HWA_E(HW_EM_X("_hwa_write_r8: value overflows the mask."));
505 
506  if ((rwm & msk) != msk)
507  HWA_E(HW_EM_X("_hwa_write_r8: trying to modify bits that are not writeable."));
508 
509  if ((r->mmask & msk) != 0 && (r->mvalue & msk) != v)
510  HWA_E(HW_EM_COMMITRQ);
511 
512  if ( msk & rfm )
513  if ( v == 0 )
514  HWA_E(HW_EM_X("_hwa_write_r8: flag bit can only be cleared by writing 1 into it."));
515 
516  r->mmask |= msk ;
517  r->mvalue = (r->mvalue & ~msk) | (msk & v) ;
518 }
519 
520 HW_INLINE void _hwa_write_r16 ( hwa_r16_t *r, uint16_t rwm, uint16_t rfm, uint16_t msk, uint16_t v )
521 {
522  if (v & ~msk)
523  HWA_E(HW_EM_X("_hwa_write_r16: value overflows the mask."));
524 
525  if ((rwm & msk) != msk)
526  HWA_E(HW_EM_X("_hwa_write_r16: trying to modify bits that are not writeable."));
527 
528  if ((r->mmask & msk) != 0 && (r->mvalue & msk) != v)
529  HWA_E(HW_EM_COMMITRQ);
530 
531  if ( msk & rfm )
532  if ( v == 0 )
533  HWA_E(HW_EM_X("_hwa_write_r16: flag bit can only be cleared by writing 1 into it."));
534 
535  r->mmask |= msk ;
536  r->mvalue = (r->mvalue & ~msk) | (msk & v) ;
537 }
538 
539 HW_INLINE void _hwa_write_r32 ( hwa_r32_t *r, uint32_t rwm, uint32_t rfm, uint32_t msk, uint32_t v )
540 {
541  if ( (v & msk & rwm) != v )
542  HWA_E(HW_EM_X("_hwa_write_r32: value overflow."));
543 
544  if ((rwm & msk) != msk && msk != 0xFFFFFFFF )
545  HWA_E(HW_EM_X("_hwa_write_r32: trying to modify bits that are not writeable."));
546 
547  if ((r->mmask & msk) != 0 && (r->mvalue & msk) != v)
548  HWA_E(HW_EM_COMMITRQ);
549 
550  if ( msk & rfm )
551  if ( v == 0 )
552  HWA_E(HW_EM_X("_hwa_write_r32: flag bit can only be cleared by writing 1 into it."));
553 
554  r->mmask |= msk ;
555  r->mvalue = (r->mvalue & ~msk) | (msk & v) ;
556 }
557 
558 
564 HW_INLINE void _hwa_check_optimizations ( uint8_t x )
565 {
566  if (x) { HWA_E(HW_EM_OPTIM); }
567 }
568 
569 
570 #define _hw_write__r8(ra,rwm,rfm,bn,bp,v) _hw_write_r8(ra,rwm,rfm,((1UL<<bn)-1)<<bp,((uint8_t)(v))<<bp)
571 #define _hw_write__r16(ra,rwm,rfm,bn,bp,v) _hw_write_r16(ra,rwm,rfm,((1UL<<bn)-1)<<bp,(v)<<bp)
572 #define _hw_write__r32(ra,rwm,rfm,bn,bp,v) _hw_write_r32(ra,rwm,rfm,((1ULL<<bn)-1)<<bp,(v)<<bp)
573 
574 #define _hwa_write__r8(ra,rwm,rfm,bn,bp,v) _hwa_write_r8(ra,rwm,rfm,((1UL<<bn)-1)<<bp,((uint8_t)(v))<<bp)
575 #define _hwa_write__r16(ra,rwm,rfm,bn,bp,v) _hwa_write_r16(ra,rwm,rfm,((1UL<<bn)-1)<<bp,(v)<<bp)
576 #define _hwa_write__r32(ra,rwm,rfm,bn,bp,v) _hwa_write_r32(ra,rwm,rfm,((1ULL<<bn)-1)<<bp,(v)<<bp)
577 
578 
_hwa_check_optimizations
HW_INLINE void _hwa_check_optimizations(uint8_t x)
Trigger an error if optimizers failed to remove this code.
Definition: hwa_2.h:564
HWA_E
#define HWA_E(...)
Trigger an error after code optimization.
Definition: hwa_2.h:17
_hwa_set__r8
HW_INLINE void _hwa_set__r8(hwa_r8_t *r, uint8_t v)
Initialize a HWA register to a specific value (usually the reset value).
Definition: hwa_2.h:456
_hwa_write_r8
HW_INLINE void _hwa_write_r8(hwa_r8_t *r, uint8_t rwm, uint8_t rfm, uint8_t msk, uint8_t v)
Write into one 8-bit context register.
Definition: hwa_2.h:501