HWA
Bare metal programming with style
ctc_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 
57 #define hwa_configure__ctc , _hwa_config_ctc
58 
59 /* Mandatory argument `clock`
60  *
61  * Add 2 void arguments to the end of the list so that there are always
62  * 3 arguments following the last non-void argument.
63  */
64 #define _hwa_config_ctc(o,a,k,...) \
65  do { HW_B(_hwa_cfctc_kclock_,_hw_is_clock_##k)(o,k,__VA_ARGS__,,) } while(0)
66 
67 #define _hwa_cfctc_kclock_0(o,k,...) \
68  HW_E(HW_EM_AN(k,clock))
69 
70 #define _hwa_cfctc_kclock_1(o,k,v,...) \
71  HW_B(_hwa_cfctc_vclock_,_hw_ctc_clock_##v)(o,v,__VA_ARGS__)
72 
73 #define _hwa_cfctc_vclock_0(o,v,...) \
74  HW_E(HW_EM_VAL(v,clock,(none,ioclk/8,ioclk/32,ioclk/64,ioclk/128,ioclk/256,ioclk/512,ioclk/1024,external_xosc)))
75 
76 #define _hwa_cfctc_vclock_1(o,v,k,...) \
77  hwa->o.config.clock = HW_VF(_hw_ctc_clock_##v); \
78  HW_B(_hwa_cfctc_kmode_,_hw_is_direction_##k)(o,k,__VA_ARGS__)
79 
80 #define _hw_ctc_clock_none , _hw_ctcck_none, 0
81 #define _hw_ctc_clock_ioclk , _hw_ctcck_ioclk, 1.0
82 #define _hw_ctc_clock_external_xosc , _hw_ctcck_xosc, 0
83 
84 HW_INLINE uint8_t _hw_ctcck_none( float v )
85 {
86  if ( v != 0 )
87  HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
88 
89  return 0 ;
90 }
91 
92 HW_INLINE uint8_t _hw_ctcck_ioclk( float v )
93 {
94  if ( v == 1.0 )
95  return 1 ;
96  if ( v == 1.0/8 )
97  return 2 ;
98  if ( v == 1.0/32 )
99  return 3 ;
100  if ( v == 1.0/64 )
101  return 4 ;
102  if ( v == 1.0/128 )
103  return 5 ;
104  if ( v == 1.0/256 )
105  return 6 ;
106  if ( v == 1.0/1024 )
107  return 7 ;
108 
109  HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
110  return 0 ;
111 }
112 
113 HW_INLINE uint8_t _hw_ctcck_xosc( float v )
114 {
115  if ( v != 0 )
116  HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
117 
118  return 8 ;
119 }
120 
121 /* Optionnal argument `direction`
122  */
123 #define _hw_ctc_direction_up_loop , 1
124 #define _hw_ctc_direction_updown_loop , 2
125 
126 #define _hwa_cfctc_kmode_0(o,k,...) \
127  HW_E(HW_EM_AN(k,direction))
128 
129 #define _hwa_cfctc_kmode_1(o,k,v,...) \
130  HW_B(_hwa_cfctc_vmode_,_hw_ctc_direction_##v)(o,v,__VA_ARGS__)
131 
132 #define _hwa_cfctc_vmode_0(o,v,...) \
133  HW_E(HW_EM_VAL(v,mode,(up_loop,updown_loop)))
134 
135 #define _hwa_cfctc_vmode_1(o,v,k,...) \
136  hwa->o.config.direction = HW_A1(_hw_ctc_direction_##v); \
137  HW_B(_hwa_cfctc_kbottom_,_hw_is_bottom_##k)(o,k,__VA_ARGS__)
138 
139 /* Optionnal argument `bottom`
140  */
141 #define _hwa_cfctc_kbottom_1(o,k,v,...) \
142  HW_G2(_hwa_cfctc_vbottom,HW_IS(0,v))(o,v,__VA_ARGS__)
143 
144 #define _hwa_cfctc_vbottom_0(o,v,...) \
145  HW_E(HW_EM_VAL(v,bottom,(0)))
146 
147 #define _hwa_cfctc_vbottom_1(o,v,k,...) \
148  HW_B(_hwa_cfctc_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
149 
150 #define _hwa_cfctc_kbottom_0(o,k,...) \
151  HW_B(_hwa_cfctc_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
152 
153 /* Optionnal argument `top`
154  */
155 #define _hw_ctc_top_fixed_0xFF , 1
156 #define _hw_ctc_top_max , 1
157 #define _hw_ctc_top_compare0 , 2
158 
159 #define _hwa_cfctc_ktop_1(o,k,v,...) \
160  HW_B(_hwa_cfctc_vtop_,_hw_ctc_top_##v)(o,v,__VA_ARGS__)
161 
162 #define _hwa_cfctc_vtop_0(o,v,...) \
163  HW_E(HW_EM_VAL(v,top,(fixed_0xFF,max,compare0)))
164 
165 #define _hwa_cfctc_vtop_1(o,v,k,...) \
166  hwa->o.config.top = HW_A1(_hw_ctc_top_##v); \
167  HW_B(_hwa_cfctc_koverflow_,_hw_is_overflow_##k)(o,k,__VA_ARGS__)
168 
169 #define _hwa_cfctc_ktop_0(o,k,...) \
170  HW_B(_hwa_cfctc_koverflow_,_hw_is_overflow_##k)(o,k,__VA_ARGS__)
171 
172 /* Optionnal argument `overflow`
173  */
174 #define _hw_ctc_overflow_after_bottom , 0
175 #define _hw_ctc_overflow_after_top , 1
176 #define _hw_ctc_overflow_after_max , 2
177 
178 #define _hwa_cfctc_koverflow_1(o,k,v,...) \
179  HW_B(_hwa_cfctc_voverflow_,_hw_ctc_overflow_##v)(o,v,__VA_ARGS__)
180 
181 #define _hwa_cfctc_voverflow_0(o,v,...) \
182  HW_E(HW_EM_VOAL(v,overflow,(after_bottom,after_top,after_max)))
183 
184 #define _hwa_cfctc_voverflow_1(o,v,...) \
185  if ( hwa->o.config.direction == HW_A1(_hw_ctc_direction_up_loop) \
186  && HW_A1(_hw_ctc_overflow_##v) == HW_A1(_hw_ctc_overflow_after_bottom) ) \
187  HWA_E(HW_EM_VOAL(v,overflow,(after_max,after_top))); \
188  hwa->o.config.overflow = HW_A1(_hw_ctc_overflow_##v); HW_EOL(__VA_ARGS__)
189 
190 #define _hwa_cfctc_koverflow_0(o,...) \
191  HW_EOL(__VA_ARGS__)
192 
193 
194 /* Solve and check the configuration of the counter and its compare units.
195  *
196  * Writing code for a HW_INLINE function is more comfortable than for a
197  * function-like macro but functions can not use object names. So, this
198  * function-like macro expands to the HW_INLINE function _hwa_solve_ctc() which
199  * uses pointers on objects in the HWA context to compute values to be written
200  * into the registers, stores them into the `solve` structure and returns an
201  * error code that is processed by _hwa_solve__ctc() which knows the names of
202  * the objects and then can put computed registers values into the context, even
203  * in the case of external register access, and display accurate error messages.
204  */
205 #define _hwa_solve__ctc( o, a ) /* copy of _hwa_solve__cta */ \
206  do { \
207  uint8_t r = _hwa_solve_ctc( &hwa->o, &hwa->o.compare0, &hwa->o.compare1 ); \
208  if ( r == 0 ) { \
209  /* \
210  * Write solved registers \
211  */ \
212  if ( hwa->o.solved.cs != 0xFF ) _hwa_write( o, cs, hwa->o.solved.cs ); \
213  if ( hwa->o.solved.wgm != 0xFF ) _hwa_write( o, wgm, hwa->o.solved.wgm ); \
214  if ( hwa->o.compare0.solved.com != 0xFF ) _hwa_write( o, com0, hwa->o.compare0.solved.com ); \
215  if ( hwa->o.compare1.solved.com != 0xFF ) _hwa_write( o, com1, hwa->o.compare1.solved.com ); \
216  /* \
217  * Configure used compare outputs as i/o outputs \
218  */ \
219  if ( hwa->o.compare0.config.output != 0xFF \
220  && hwa->o.compare0.config.output != HW_A1(_hw_oca_output_disconnected) ) \
221  _hwa( configure, (o,compare0,pin), mode, digital_output ); \
222  if ( hwa->o.compare1.config.output != 0xFF \
223  && hwa->o.compare1.config.output != HW_A1(_hw_oca_output_disconnected) ) \
224  _hwa( configure, (o,compare1,pin), mode, digital_output ); \
225  } \
226  else if ( r == 1 ) \
227  /* `update` must be the same for both compare units of `o`" */ \
228  HWA_E(HW_EM_ADOO(update,(o,compare0),(o,compare1))); \
229  else if ( r == 2 ) \
230  /* "WGM value could not be solved for o" */ \
231  HWA_E(HW_EM_XSO(wgm,o)); \
232  else if ( r == 3 ) \
233  /* "configuration of `o` is required */ \
234  HWA_E(HW_EM_COR(o)); \
235  else if ( r == 4 ) \
236  HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
237  toggle_after_match, \
238  clear_after_match, \
239  set_after_match))); \
240  else if ( r == 5 ) \
241  HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
242  set_at_bottom_clear_after_match, \
243  clear_at_bottom_set_after_match))); \
244  else if ( r == 6 ) \
245  HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
246  toggle_after_match, \
247  set_at_bottom_clear_after_match, \
248  clear_at_bottom_set_after_match))); \
249  else if ( r == 7 ) \
250  HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
251  clear_after_match_up_set_after_match_down, \
252  set_after_match_up_clear_after_match_down))); \
253  else if ( r == 8 ) \
254  HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
255  toggle_after_match, \
256  clear_after_match_up_set_after_match_down, \
257  set_after_match_up_clear_after_match_down))); \
258  else if ( r == 9 ) \
259  HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
260  toggle_after_match, \
261  clear_after_match, \
262  set_after_match))); \
263  else if ( r == 10 ) \
264  HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
265  set_at_bottom_clear_after_match, \
266  clear_at_bottom_set_after_match))); \
267  else if ( r == 11 ) \
268  HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
269  clear_after_match_up_set_after_match_down, \
270  set_after_match_up_clear_after_match_down))); \
271  else if ( r == 12 ) \
272  HWA_E(HW_EM_AOVM(update,o,immediately)); \
273  else if ( r == 13 ) \
274  HWA_E(HW_EM_AOVM(update,o,after_bottom)); \
275  else if ( r == 14 ) \
276  HWA_E(HW_EM_AOVM(update,o,after_top)); \
277  else if ( r == 15 ) \
278  HWA_E(HW_EM_AOVM(overflow,o,after_top)); \
279  else if ( r == 16 ) \
280  HWA_E(HW_EM_AOVM(overflow,o,after_bottom)); \
281  else if ( r == 17 ) \
282  HWA_E(HW_EM_AOVM(overflow,o,after_max)); \
283  else \
284  HWA_E(HW_EM_X(in _hwa_solve__cta: __LINE__)); \
285  }while(0)
286 
287 
288 HW_INLINE uint8_t _hwa_solve_ctc ( hwa_ctc_t *p, hwa_oca_t *compare0, hwa_oca_t *compare1 )
289 {
290  /* 0xFF == unchanged
291  */
292  p->solved.cs = 0xFF ;
293  p->solved.wgm = 0xFF ;
294  compare0->solved.com = 0xFF ;
295  compare1->solved.com = 0xFF ;
296 
297  if ( p->config.clock == 0xFF )
298  return 0 ;
299 
300  /* Clock selection
301  */
302  p->solved.cs = p->config.clock ;
303 
304  /* Default config for top
305  */
306  if ( p->config.top == 0xFF )
307  p->config.top = HW_A1(_hw_ctc_top_max);
308 
309  /* Default config for overflow
310  */
311  uint8_t overflow = p->config.overflow ;
312  if ( overflow == 0xFF && p->config.top == HW_A1(_hw_ctc_top_compare0) ) {
313  if ( p->config.direction == HW_A1(_hw_ctc_direction_up_loop) )
314  overflow = HW_A1(_hw_ctc_overflow_after_top);
315  else /* if ( p->config.direction == HW_A1(_hw_ctc_direction_up_loop) ) */
316  overflow = HW_A1(_hw_ctc_overflow_after_bottom);
317  }
318 
319  /* Compare update setting
320  */
321  uint8_t compare_update = 0xFF ;
322  if ( compare0->config.update != 0xFF && compare1->config.update != 0xFF
323  && compare0->config.update != compare1->config.update )
324  return 1 ; //("`update` must be the same for both compare units.");
325 
326  compare_update = compare0->config.update ;
327 
328 
329  /* Mode WGM Operation COUNTMODE TOP UPD OVF OCA OCB
330  *
331  * 0 000 Normal LOOP_UP 0xFF IMM MAX DIS,ToM,CoM,SoM DIS,ToM,CoM,SoM
332  * 2 010 CTC LOOP_UP OCRA IMM MAX DIS,ToM,CoM,SoM DIS,ToM,CoM,SoM
333  *
334  * 3 011 Fast PWM LOOP_UP 0xFF BOT MAX DIS,SaBCoM,CaBSoM DIS,SaBCoM,CaBSoM
335  * 7 111 Fast PWM LOOP_UP OCRA BOT TOP DIS,ToM,CoMSaB,SoMCaB DIS,SaBCoM,CaBSoM
336  *
337  * 1 001 PWM, PhC LOOP_UPDOWN 0xFF TOP BOT DIS,CmuSmd,SmuCmd DIS,CmuSmd,SmuCmd
338  * 5 101 PWM, PhC LOOP_UPDOWN OCRA TOP BOT DIS,ToM,CmuSmd,SmuCmd DIS,CmuSmd,SmuCmd
339  *
340  * 4 100 *Reserved*
341  * 6 110 *Reserved*
342  */
343 
344  /* Determine WGM
345  */
346  uint8_t wgm = 0xFF ;
347  if ( p->config.direction == HW_A1(_hw_ctc_direction_up_loop) ) {
348  if ( p->config.top == HW_A1(_hw_ctc_top_fixed_0xFF) ) {
349  if ( compare_update == HW_A1(_hw_oca_update_after_bottom)
350  || compare0->config.output == HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
351  || compare0->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
352  || compare1->config.output == HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
353  || compare1->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match))
354  wgm = 3 ;
355  else
356  wgm = 0 ;
357  }
358  else /* top == ocra */ {
359  /*
360  * FIXME: a change of output_mode from one of the 4 modes below to
361  * 'disconnected' causes a useless modification of wgm from 7 to 2. As
362  * wgm2 is not in the same register as wgm1:0, this generates useless
363  * code.
364  */
365  if ( compare_update == HW_A1(_hw_oca_update_after_bottom )
366  || overflow == HW_A1(_hw_ctc_overflow_after_top)
367  || compare0->config.output == HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
368  || compare0->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
369  || compare1->config.output == HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
370  || compare1->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match))
371  wgm = 7 ;
372  else
373  wgm = 2 ;
374  }
375  }
376  else /* direction == updown_loop */ {
377  if ( p->config.top == HW_A1(_hw_ctc_top_fixed_0xFF) )
378  wgm = 1 ;
379  else /* top == ocra */
380  wgm = 5 ;
381  }
382 
383  if (wgm == 0xFF) {
384  // ("WGM value could not be solved for _ctc class counter.");
385  return 2 ;
386  }
387 
388  p->solved.wgm = wgm ;
389 
390 
391  /* Solve the configuration of compare output A
392  */
393  if ( compare0->config.output != 0xFF ) {
394 
395  uint8_t mode = 0xFF ;
396 
397  if ( compare0->config.output == HW_A1(_hw_oca_output_disconnected) )
398  mode = 0 ;
399  else if ( compare0->config.output == HW_A1(_hw_oca_output_toggle_after_match) )
400  mode = 1 ;
401  else if ( compare0->config.output == HW_A1(_hw_oca_output_clear_after_match)
402  || compare0->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
403  || compare0->config.output == HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down) )
404  mode = 2 ;
405  else
406  mode = 3 ;
407 
408  compare0->solved.com = mode ;
409  }
410 
411 
412  /* Solve the configuration of compare output B
413  */
414  if ( compare1->config.output != 0xFF ) {
415 
416  uint8_t mode = 0xFF ;
417 
418  if ( compare1->config.output == HW_A1(_hw_oca_output_disconnected) )
419  mode = 0 ;
420  else if ( compare1->config.output == HW_A1(_hw_oca_output_toggle_after_match) )
421  mode = 1 ;
422  else if ( compare1->config.output == HW_A1(_hw_oca_output_clear_after_match)
423  || compare1->config.output == HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
424  || compare1->config.output == HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down) )
425  mode = 2 ;
426  else
427  mode = 3 ;
428 
429  compare1->solved.com = mode ;
430  }
431 
432 
433  /* Check the validity of the configuration
434  */
435  if ( p->config.clock != 0xFF || compare0->config.output != 0xFF \
436  || compare1->config.output != 0xFF ) {
437 
438  if ( p->config.clock == 0xFF ) {
439  // ("configuration of counter is required.");
440  return 3 ;
441  }
442 
443  /* Compare output A
444  */
445  if ( compare0->config.output != 0xFF ) {
446  if ( wgm==0 || wgm==2 ) {
447  if ( compare0->config.output != HW_A1(_hw_oca_output_disconnected)
448  && compare0->config.output != HW_A1(_hw_oca_output_toggle_after_match)
449  && compare0->config.output != HW_A1(_hw_oca_output_clear_after_match)
450  && compare0->config.output != HW_A1(_hw_oca_output_set_after_match))
451  return 4 ;
452  /* ("compare output A of class _ctc counter mode must be " */
453  /* "'disconnected', 'toggle_after_match', 'clear_after_match', or " */
454  /* "'set_after_match'."); */
455 
456  }
457  else if ( wgm==3 ) {
458  if ( compare0->config.output != HW_A1(_hw_oca_output_disconnected)
459  && compare0->config.output != HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
460  && compare0->config.output != HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
461  return 5 ;
462  /* ("compare output A of class _ctc counter mode must be " */
463  /* "'disconnected', 'set_at_bottom_clear_after_match', or " */
464  /* "'clear_at_bottom_set_after_match'."); */
465  }
466  else if ( wgm==7 ) {
467  if ( compare0->config.output != HW_A1(_hw_oca_output_disconnected)
468  && compare0->config.output != HW_A1(_hw_oca_output_toggle_after_match)
469  && compare0->config.output != HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
470  && compare0->config.output != HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
471  return 6 ;
472  /* ("compare output A of class _ctc counter mode must be " */
473  /* "'disconnected', 'toggle_after_match', " */
474  /* "'set_at_bottom_clear_after_match', or " */
475  /* "'clear_at_bottom_set_after_match'."); */
476  }
477  else if ( wgm==1 ) {
478  if ( compare0->config.output != HW_A1(_hw_oca_output_disconnected)
479  && compare0->config.output != HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
480  && compare0->config.output != HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
481  /* ("compare output A of class _ctc counter mode must be " */
482  /* "'disconnected', 'clear_after_match_up_set_after_match_down', " */
483  /* "or 'set_after_match_up_clear_after_match_down'."); */
484  return 7 ;
485  }
486  else if ( wgm==5 ) {
487  if ( compare0->config.output != HW_A1(_hw_oca_output_disconnected)
488  && compare0->config.output != HW_A1(_hw_oca_output_toggle_after_match)
489  && compare0->config.output != HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
490  && compare0->config.output != HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
491  /* ("compare output A of class _ctc counter mode must be " */
492  /* "'disconnected', 'toggle_after_match', " */
493  /* "'clear_after_match_up_set_after_match_down', " */
494  /* "or 'set_after_match_up_clear_after_match_down'."); */
495  return 8 ;
496  }
497  }
498 
499  /* Compare output B
500  */
501  if ( compare1->config.output != 0xFF ) {
502  if ( wgm==0 || wgm==2 ) {
503  if ( compare1->config.output != HW_A1(_hw_oca_output_disconnected)
504  && compare1->config.output != HW_A1(_hw_oca_output_toggle_after_match)
505  && compare1->config.output != HW_A1(_hw_oca_output_clear_after_match)
506  && compare1->config.output != HW_A1(_hw_oca_output_set_after_match))
507  /* ("compare output B of class _ctc counter mode must be " */
508  /* "'disconnected', 'toggle_after_match', 'clear_after_match', or " */
509  /* "'set_after_match'."); */
510  return 9 ;
511  }
512  else if ( wgm==3 || wgm==7 ) {
513  if ( compare1->config.output != HW_A1(_hw_oca_output_disconnected)
514  && compare1->config.output != HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
515  && compare1->config.output != HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
516  /* ("compare output B of class _ctc counter mode must be " */
517  /* "'disconnected', 'set_at_bottom_clear_after_match', or " */
518  /* "'clear_at_bottom_set_after_match'."); */
519  return 10 ;
520  }
521  else if ( wgm==1 || wgm==5 ) {
522  if ( compare1->config.output != HW_A1(_hw_oca_output_disconnected)
523  && compare1->config.output != HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
524  && compare1->config.output != HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
525  /* ("compare output B of class _ctc counter mode must be " */
526  /* "'disconnected', 'clear_after_match_up_set_after_match_down', " */
527  /* "or 'set_after_match_up_clear_after_match_down'."); */
528  return 11 ;
529  }
530  }
531 
532  /* Update
533  */
534  if ( compare_update != 0xFF ) {
535  if ( wgm==0 || wgm==2 ) {
536  if ( compare_update != HW_A1(_hw_oca_update_immediately) )
537  /* ("optionnal parameter 'update' of class _ctc counter must be "\ */
538  /* "'immediately'."); */
539  return 12 ;
540  }
541  else if ( wgm==3 || wgm==7 ) {
542  if ( compare_update != HW_A1(_hw_oca_update_after_bottom) )
543  /* ("optionnal parameter 'update' of class _ctc counter must be " */
544  /* "'after_bottom'."); */
545  return 13 ;
546  }
547  else
548  if( compare_update != HW_A1(_hw_oca_update_after_top) )
549  /* ("optionnal parameter 'update' of class _ctc counter must be " */
550  /* "'after_top'."); */
551  return 14 ;
552  }
553 
554  /* Overflow
555  */
556  if ( overflow != 0xFF ) {
557  if ( wgm==7 ) {
558  if ( overflow != HW_A1(_hw_ctc_overflow_after_top) )
559  /* ("optionnal parameter 'overflow' of class _ctc counter must be " */
560  /* "'after_top'."); */
561  return 15 ;
562  }
563  else if ( (wgm==1 || wgm==5) ) {
564  if ( overflow != HW_A1(_hw_ctc_overflow_after_bottom) )
565  /* ("optionnal parameter 'overflow' of class _ctc counter must be " */
566  /* "'after_bottom'."); */
567  return 16 ;
568  }
569  else if ( overflow != HW_A1(_hw_ctc_overflow_after_max) )
570  /* ("optionnal parameter 'overflow' of class _ctc counter must be " */
571  /* "'after_max'."); */
572  return 17 ;
573  }
574  }
575 
576  return 0 ;
577 }
578 
579 
599 #define hw_read__ctc , _hw_read_ctc
600 #define _hw_read_ctc(o,a,...) _hw_read(o,count) HW_EOL(__VA_ARGS__)
601 
602 #define hw_write__ctc , _hw_write_ctc
603 #define _hw_write_ctc(o,a,v,...) _hw_write(o,count,v) HW_EOL(__VA_ARGS__)
604 
605 #define hwa_write__ctc , _hwa_write_ctc
606 #define _hwa_write_ctc(o,a,v) _hwa_write(o,count,v)
607 
608 
609 /*******************************************************************************
610  * *
611  * Context management *
612  * *
613  *******************************************************************************/
614 
615 #define _hwa_setup__ctc(o,a) \
616  _hwa_setup_r( o, ccra); \
617  _hwa_setup_r( o, ccrb); \
618  _hwa_setup_r( o, count); \
619  _hwa_setup_r( o, imsk); \
620  _hwa_setup_r( o, ifr); \
621  hwa->o.config.clock = 0xFF; \
622  hwa->o.config.direction = 0xFF; \
623  hwa->o.config.top = 0xFF; \
624  hwa->o.config.overflow = 0xFF; \
625  hwa->o.compare0.config.update = 0xFF ; \
626  hwa->o.compare0.config.output = 0xFF ; \
627  hwa->o.compare1.config.update = 0xFF ; \
628  hwa->o.compare1.config.output = 0xFF
629 
630 
631 #define _hwa_init__ctc(o,a) \
632  _hwa_init_r( o, ccra, 0x00 ); \
633  _hwa_init_r( o, ccrb, 0x00 ); \
634  _hwa_init_r( o, count, 0x00 ); \
635  _hwa_init_r( o, imsk, 0x00 ); \
636  _hwa_init_r( o, ifr, 0x00 )
637 
638 
639 #define _hwa_commit__ctc(o,a) \
640  _hwa_commit_r( o, ccra); \
641  _hwa_commit_r( o, ccrb); \
642  _hwa_commit_r( o, count); \
643  _hwa_commit_r( o, imsk); \
644  _hwa_commit_r( o, ifr)
645 
646 
HW_A1
#define HW_A1(...)
Element a1 of the list a0,a1,...
Definition: hwa_macros.h:36
HWA_E
#define HWA_E(...)
Trigger an error after code optimization.
Definition: hwa_2.h:17