57 #define hwa_configure__ctc , _hwa_config_ctc
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)
67 #define _hwa_cfctc_kclock_0(o,k,...) \
68 HW_E(HW_EM_AN(k,clock))
70 #define _hwa_cfctc_kclock_1(o,k,v,...) \
71 HW_B(_hwa_cfctc_vclock_,_hw_ctc_clock_##v)(o,v,__VA_ARGS__)
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)))
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__)
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
84 HW_INLINE uint8_t _hw_ctcck_none(
float v )
87 HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
92 HW_INLINE uint8_t _hw_ctcck_ioclk(
float v )
109 HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
113 HW_INLINE uint8_t _hw_ctcck_xosc(
float v )
116 HWA_E(HW_EM_AVL(clock,(none, ioclk/(1, 8, 32, 64, 128, 256, 512, 1024, external_osc))));
123 #define _hw_ctc_direction_up_loop , 1
124 #define _hw_ctc_direction_updown_loop , 2
126 #define _hwa_cfctc_kmode_0(o,k,...) \
127 HW_E(HW_EM_AN(k,direction))
129 #define _hwa_cfctc_kmode_1(o,k,v,...) \
130 HW_B(_hwa_cfctc_vmode_,_hw_ctc_direction_##v)(o,v,__VA_ARGS__)
132 #define _hwa_cfctc_vmode_0(o,v,...) \
133 HW_E(HW_EM_VAL(v,mode,(up_loop,updown_loop)))
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__)
141 #define _hwa_cfctc_kbottom_1(o,k,v,...) \
142 HW_G2(_hwa_cfctc_vbottom,HW_IS(0,v))(o,v,__VA_ARGS__)
144 #define _hwa_cfctc_vbottom_0(o,v,...) \
145 HW_E(HW_EM_VAL(v,bottom,(0)))
147 #define _hwa_cfctc_vbottom_1(o,v,k,...) \
148 HW_B(_hwa_cfctc_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
150 #define _hwa_cfctc_kbottom_0(o,k,...) \
151 HW_B(_hwa_cfctc_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
155 #define _hw_ctc_top_fixed_0xFF , 1
156 #define _hw_ctc_top_max , 1
157 #define _hw_ctc_top_compare0 , 2
159 #define _hwa_cfctc_ktop_1(o,k,v,...) \
160 HW_B(_hwa_cfctc_vtop_,_hw_ctc_top_##v)(o,v,__VA_ARGS__)
162 #define _hwa_cfctc_vtop_0(o,v,...) \
163 HW_E(HW_EM_VAL(v,top,(fixed_0xFF,max,compare0)))
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__)
169 #define _hwa_cfctc_ktop_0(o,k,...) \
170 HW_B(_hwa_cfctc_koverflow_,_hw_is_overflow_##k)(o,k,__VA_ARGS__)
174 #define _hw_ctc_overflow_after_bottom , 0
175 #define _hw_ctc_overflow_after_top , 1
176 #define _hw_ctc_overflow_after_max , 2
178 #define _hwa_cfctc_koverflow_1(o,k,v,...) \
179 HW_B(_hwa_cfctc_voverflow_,_hw_ctc_overflow_##v)(o,v,__VA_ARGS__)
181 #define _hwa_cfctc_voverflow_0(o,v,...) \
182 HW_E(HW_EM_VOAL(v,overflow,(after_bottom,after_top,after_max)))
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__)
190 #define _hwa_cfctc_koverflow_0(o,...) \
205 #define _hwa_solve__ctc( o, a ) \
207 uint8_t r = _hwa_solve_ctc( &hwa->o, &hwa->o.compare0, &hwa->o.compare1 ); \
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 ); \
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 ); \
228 HWA_E(HW_EM_ADOO(update,(o,compare0),(o,compare1))); \
231 HWA_E(HW_EM_XSO(wgm,o)); \
234 HWA_E(HW_EM_COR(o)); \
236 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
237 toggle_after_match, \
239 set_after_match))); \
241 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
242 set_at_bottom_clear_after_match, \
243 clear_at_bottom_set_after_match))); \
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))); \
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))); \
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))); \
259 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
260 toggle_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)); \
284 HWA_E(HW_EM_X(in _hwa_solve__cta: __LINE__)); \
288 HW_INLINE uint8_t _hwa_solve_ctc ( hwa_ctc_t *p, hwa_oca_t *compare0, hwa_oca_t *compare1 )
292 p->solved.cs = 0xFF ;
293 p->solved.wgm = 0xFF ;
294 compare0->solved.com = 0xFF ;
295 compare1->solved.com = 0xFF ;
297 if ( p->config.clock == 0xFF )
302 p->solved.cs = p->config.clock ;
306 if ( p->config.top == 0xFF )
307 p->config.top =
HW_A1(_hw_ctc_top_max);
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);
316 overflow =
HW_A1(_hw_ctc_overflow_after_bottom);
321 uint8_t compare_update = 0xFF ;
322 if ( compare0->config.update != 0xFF && compare1->config.update != 0xFF
323 && compare0->config.update != compare1->config.update )
326 compare_update = compare0->config.update ;
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))
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))
377 if ( p->config.top ==
HW_A1(_hw_ctc_top_fixed_0xFF) )
388 p->solved.wgm = wgm ;
393 if ( compare0->config.output != 0xFF ) {
395 uint8_t mode = 0xFF ;
397 if ( compare0->config.output ==
HW_A1(_hw_oca_output_disconnected) )
399 else if ( compare0->config.output ==
HW_A1(_hw_oca_output_toggle_after_match) )
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) )
408 compare0->solved.com = mode ;
414 if ( compare1->config.output != 0xFF ) {
416 uint8_t mode = 0xFF ;
418 if ( compare1->config.output ==
HW_A1(_hw_oca_output_disconnected) )
420 else if ( compare1->config.output ==
HW_A1(_hw_oca_output_toggle_after_match) )
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) )
429 compare1->solved.com = mode ;
435 if ( p->config.clock != 0xFF || compare0->config.output != 0xFF \
436 || compare1->config.output != 0xFF ) {
438 if ( p->config.clock == 0xFF ) {
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))
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) )
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) )
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) )
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) )
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))
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) )
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) )
534 if ( compare_update != 0xFF ) {
535 if ( wgm==0 || wgm==2 ) {
536 if ( compare_update !=
HW_A1(_hw_oca_update_immediately) )
541 else if ( wgm==3 || wgm==7 ) {
542 if ( compare_update !=
HW_A1(_hw_oca_update_after_bottom) )
548 if( compare_update !=
HW_A1(_hw_oca_update_after_top) )
556 if ( overflow != 0xFF ) {
558 if ( overflow !=
HW_A1(_hw_ctc_overflow_after_top) )
563 else if ( (wgm==1 || wgm==5) ) {
564 if ( overflow !=
HW_A1(_hw_ctc_overflow_after_bottom) )
569 else if ( overflow !=
HW_A1(_hw_ctc_overflow_after_max) )
599 #define hw_read__ctc , _hw_read_ctc
600 #define _hw_read_ctc(o,a,...) _hw_read(o,count) HW_EOL(__VA_ARGS__)
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__)
605 #define hwa_write__ctc , _hwa_write_ctc
606 #define _hwa_write_ctc(o,a,v) _hwa_write(o,count,v)
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
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 )
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)