61 #define hwa_configure__ctd , _hwa_cfctd
68 #define _hwa_cfctd(o,a,k,...) do { HW_BW(_hwa_cfctd1,clock,k)(o,k,__VA_ARGS__,,) } while(0)
69 #define _hwa_cfctd10(o,k,...) HW_E(HW_EM_AN(k,clock))
70 #define _hwa_cfctd11(o,k,v,...) HW_B(_hwa_cfctd11,_hw_c1clk_##v)(o,v,__VA_ARGS__)
71 #define _hwa_cfctd110(o,v,...) HW_E(HW_EM_VAL(v,clock,(none,ioclk,ioclk/8,ioclk/64,ioclk/256,ioclk/1024,external_falling,external_rising)))
72 #define _hwa_cfctd111(o,v,k,...) \
73 hwa->o.config.clock = HW_VF(_hw_c1clk_##v); \
74 HW_BW(_hwa_cfctd_kmode_,direction,k)(o,k,__VA_ARGS__)
79 #define _hw_ctd_direction_up_loop , 1
80 #define _hw_ctd_direction_updown_loop , 2
82 #define _hwa_cfctd_kmode_0(o,k,...) \
83 HW_E(HW_EM_AN(k,direction))
85 #define _hwa_cfctd_kmode_1(o,k,v,...) \
86 HW_B(_hwa_cfctd_vmode_,_hw_ctd_direction_##v)(o,v,__VA_ARGS__)
88 #define _hwa_cfctd_vmode_0(o,v,...) HW_E(HW_EM_VAL(v,direction,(up_loop,updown_loop)))
89 #define _hwa_cfctd_vmode_1(o,v,k,...) \
90 hwa->o.config.direction = HW_A1(_hw_ctd_direction_##v); \
91 HW_B(_hwa_cfctd_kbottom_,_hw_is_bottom_##k)(o,k,__VA_ARGS__)
95 #define _hwa_cfctd_kbottom_1(o,k,v,...) HW_G2(_hwa_cfctd_vbottom,HW_IS(0,v))(o,v,__VA_ARGS__)
96 #define _hwa_cfctd_vbottom_0(o,v,...) HW_E(HW_EM_VAL(v,bottom,(0)))
97 #define _hwa_cfctd_vbottom_1(o,v,k,...) HW_B(_hwa_cfctd_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
98 #define _hwa_cfctd_kbottom_0(o,k,...) HW_B(_hwa_cfctd_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
102 #define _hw_ctd_top_0x00FF , 1
103 #define _hw_ctd_top_0xFF , 1
104 #define _hw_ctd_top_255 , 1
105 #define _hw_ctd_top_0x01FF , 2
106 #define _hw_ctd_top_0x1FF , 2
107 #define _hw_ctd_top_511 , 2
108 #define _hw_ctd_top_0x03FF , 3
109 #define _hw_ctd_top_0x3FF , 3
110 #define _hw_ctd_top_1023 , 3
111 #define _hw_ctd_top_0xFFFF , 4
112 #define _hw_ctd_top_65536 , 4
113 #define _hw_ctd_top_max , 4
114 #define _hw_ctd_top_capture0 , 5
115 #define _hw_ctd_top_compare0 , 6
117 #define _hwa_cfctd_ktop_1(o,k,v,...) \
118 HW_B(_hwa_cfctd_vtop_,_hw_ctd_top_##v)(o,v,__VA_ARGS__)
120 #define _hwa_cfctd_vtop_0(o,v,...) \
121 HW_E(HW_EM_VAL(v,top,(0xFF,0x1FF,0x3FF,0xFFFF,max,capture0,compare0)))
123 #define _hwa_cfctd_vtop_1(o,v,k,...) \
124 hwa->o.config.top = HW_A1(_hw_ctd_top_##v); \
125 HW_BW(_hwa_cfctdovf,overflow,k)(o,k,__VA_ARGS__)
127 #define _hwa_cfctd_ktop_0(o,k,...) HW_BW(_hwa_cfctdovf,overflow,k)(o,k,__VA_ARGS__)
131 #define _hwa_cfctdovf1(o,k,v,...) HW_BV(_hwa_cfctdovf1,ctdovf_,v,o) HW_EOL(__VA_ARGS__)
132 #define _hwa_cfctdovf10(v,o) HW_E(HW_EM_VOAL(v,overflow,(after_bottom,after_top,after_max)))
133 #define _hwa_cfctdovf11(v,o) hwa->o.config.overflow = v;
134 #define _hwa_cfctdovf0(o,...) HW_EOL(__VA_ARGS__)
136 #define _hw_ctdovf_after_bottom , 0
137 #define _hw_ctdovf_after_top , 1
138 #define _hw_ctdovf_after_max , 2
152 #define _hwa_solve__ctd( o, a ) \
154 uint8_t r = _hwa_solve_ctd( &hwa->o, &hwa->o.compare0, &hwa->o.compare1, &hwa->o.capture0 ); \
159 if ( hwa->o.solved.cs != 0xFF ) _hwa_write( o, cs, hwa->o.solved.cs ); \
160 if ( hwa->o.solved.wgm != 0xFF ) _hwa_write( o, wgm, hwa->o.solved.wgm ); \
161 if ( hwa->o.compare0.solved.com != 0xFF ) _hwa_write( o, com0, hwa->o.compare0.solved.com ); \
162 if ( hwa->o.compare1.solved.com != 0xFF ) _hwa_write( o, com1, hwa->o.compare1.solved.com ); \
163 if ( hwa->o.capture0.solved.acic != 0xFF ) _hwa_write( o, acic, hwa->o.capture0.solved.acic ); \
164 if ( hwa->o.capture0.solved.ices != 0xFF ) _hwa_write( o, ices, hwa->o.capture0.solved.ices ); \
165 if ( hwa->o.capture0.solved.icnc != 0xFF ) _hwa_write( o, icnc, hwa->o.capture0.solved.icnc ); \
169 if ( hwa->o.compare0.config.output != 0xFF \
170 && hwa->o.compare0.config.output != HW_A1(_hw_occ_output_disconnected) ) \
171 _hwa( configure, (o,compare0,pin), mode, digital_output ); \
172 if ( hwa->o.compare1.config.output != 0xFF \
173 && hwa->o.compare1.config.output != HW_A1(_hw_occ_output_disconnected) ) \
174 _hwa( configure, (o,compare1,pin), mode, digital_output ); \
178 HWA_E(HW_EM_ADOO(update,(o,compare0),(o,compare1))); \
181 HWA_E(HW_EM_XSO(wgm,o)); \
184 HWA_E(HW_EM_COR(o)); \
186 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
187 toggle_after_match, \
189 set_after_match))); \
191 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
192 set_at_bottom_clear_after_match, \
193 clear_at_bottom_set_after_match))); \
195 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
196 toggle_after_match, \
197 set_at_bottom_clear_after_match, \
198 clear_at_bottom_set_after_match))); \
200 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
201 clear_after_match_up_set_after_match_down, \
202 set_after_match_up_clear_after_match_down))); \
204 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
205 toggle_after_match, \
206 clear_after_match_up_set_after_match_down, \
207 set_after_match_up_clear_after_match_down))); \
210 else if ( r == 10 ) \
211 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
212 toggle_after_match, \
214 set_after_match))); \
215 else if ( r == 11 ) \
216 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
217 set_at_bottom_clear_after_match, \
218 clear_at_bottom_set_after_match))); \
219 else if ( r == 12 ) \
220 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
221 clear_after_match_up_set_after_match_down, \
222 set_after_match_up_clear_after_match_down))); \
223 else if ( r == 13 ) \
224 HWA_E(HW_EM_AOVM(update,o,immediately)); \
225 else if ( r == 14 ) \
226 HWA_E(HW_EM_AOVM(update,o,after_bottom)); \
227 else if ( r == 15 ) \
228 HWA_E(HW_EM_AOVM(update,o,after_top)); \
229 else if ( r == 16 ) \
230 HWA_E(HW_EM_AOVM(overflow,o,after_max)); \
231 else if ( r == 17 ) \
232 HWA_E(HW_EM_AOVM(overflow,o,after_top)); \
233 else if ( r == 18 ) \
234 HWA_E(HW_EM_AOVM(overflow,o,after_bottom)); \
236 HWA_E(HW_EM_X(in _hwa_solve__cta: __LINE__)); \
243 HW_INLINE uint8_t _hwa_solve_ctd ( hwa_ctd_t *c, hwa_occ_t *compare0,
244 hwa_occ_t *compare1, hwa_ica_t *capture0 )
246 c->solved.cs = 0xFF ;
247 c->solved.wgm = 0xFF ;
248 compare0->solved.com = 0xFF ;
249 compare1->solved.com = 0xFF ;
250 capture0->solved.acic = 0xFF ;
251 capture0->solved.ices = 0xFF ;
252 capture0->solved.icnc = 0xFF ;
254 if ( c->config.clock == 0xFF )
259 c->solved.cs = c->config.clock ;
263 if ( c->config.top == 0xFF )
264 c->config.top =
HW_A1(_hw_ctd_top_max);
268 uint8_t overflow = c->config.overflow ;
269 if ( overflow == 0xFF && c->config.top ==
HW_A1(_hw_ctd_top_compare0) ) {
270 if ( c->config.direction ==
HW_A1(_hw_ctd_direction_up_loop) )
271 overflow =
HW_A1(_hw_ctdovf_after_top);
273 overflow =
HW_A1(_hw_ctdovf_after_bottom);
278 uint8_t compare_update = 0xFF ;
279 if ( compare0->config.update != 0xFF && compare1->config.update != 0xFF
280 && compare0->config.update != compare1->config.update )
282 compare_update = compare0->config.update ;
313 if ( c->config.direction ==
HW_A1(_hw_ctd_direction_up_loop)
314 && c->config.top ==
HW_A1(_hw_ctd_top_compare0)
315 && overflow ==
HW_A1(_hw_ctdovf_after_top) )
318 if ( c->config.direction ==
HW_A1(_hw_ctd_direction_up_loop) ) {
319 if ( c->config.top ==
HW_A1(_hw_ctd_top_0xFFFF) )
321 else if (c->config.top ==
HW_A1(_hw_ctd_top_0xFF) )
323 else if (c->config.top ==
HW_A1(_hw_ctd_top_0x1FF) )
325 else if (c->config.top ==
HW_A1(_hw_ctd_top_0x3FF) )
327 else if (c->config.top ==
HW_A1(_hw_ctd_top_compare0) ) {
328 if ( compare_update ==
HW_A1(_hw_occ_update_immediately)
329 || overflow ==
HW_A1(_hw_ctdovf_after_top)
330 || compare1->config.output ==
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
331 || compare1->config.output ==
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match))
337 if (compare_update ==
HW_A1(_hw_occ_update_after_top)
338 || overflow ==
HW_A1(_hw_ctdovf_after_top)
339 || compare0->config.output ==
HW_A1(_hw_occ_output_toggle_after_match)
340 || compare0->config.output ==
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
341 || compare0->config.output ==
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match)
342 || compare1->config.output ==
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
343 || compare1->config.output ==
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match))
350 if (c->config.top ==
HW_A1(_hw_ctd_top_0xFF) )
352 else if (c->config.top ==
HW_A1(_hw_ctd_top_0x1FF) )
354 else if (c->config.top ==
HW_A1(_hw_ctd_top_0x3FF) )
356 else if (c->config.top ==
HW_A1(_hw_ctd_top_compare0) ) {
357 if (compare_update ==
HW_A1(_hw_occ_update_after_bottom)
358 || compare1->config.output ==
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
359 || compare1->config.output ==
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down))
365 if (compare_update ==
HW_A1(_hw_occ_update_after_bottom)
366 || compare0->config.output ==
HW_A1(_hw_occ_output_toggle_after_match)
367 || compare0->config.output ==
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
368 || compare0->config.output ==
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down)
369 || compare1->config.output ==
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
370 || compare1->config.output ==
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down))
380 c->solved.wgm = wgm ;
384 if ( compare0->config.output != 0xFF ) {
386 uint8_t mode = 0xFF ;
388 if ( compare0->config.output ==
HW_A1(_hw_occ_output_disconnected) )
390 else if ( compare0->config.output ==
HW_A1(_hw_occ_output_toggle_after_match) )
392 else if ( compare0->config.output ==
HW_A1(_hw_occ_output_clear_after_match)
393 || compare0->config.output ==
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
394 || compare0->config.output ==
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down) )
399 compare0->solved.com = mode ;
404 if ( compare1->config.output != 0xFF ) {
406 uint8_t mode = 0xFF ;
408 if ( compare1->config.output ==
HW_A1(_hw_occ_output_disconnected) )
410 else if ( compare1->config.output ==
HW_A1(_hw_occ_output_toggle_after_match) )
412 else if ( compare1->config.output ==
HW_A1(_hw_occ_output_clear_after_match)
413 || compare1->config.output ==
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
414 || compare1->config.output ==
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down) )
419 compare1->solved.com = mode ;
425 if ( capture0->config.input != 0xFF )
426 capture0->solved.acic = capture0->config.input-1 ;
427 if ( capture0->config.edge != 0xFF )
428 capture0->solved.ices = capture0->config.edge-1 ;
429 if ( capture0->config.filter != 0xFF )
430 capture0->solved.icnc = capture0->config.filter ;
436 if ( c->config.direction != 0xFF || compare0->config.output != 0xFF || compare1->config.output != 0xFF ) {
438 if ( c->config.direction == 0xFF )
443 if ( compare0->config.output != 0xFF ) {
444 if ( wgm==0 || wgm==12 ) {
445 if ( compare0->config.output !=
HW_A1(_hw_occ_output_disconnected)
446 && compare0->config.output !=
HW_A1(_hw_occ_output_clear_after_match)
447 && compare0->config.output !=
HW_A1(_hw_occ_output_set_after_match)
448 && compare0->config.output !=
HW_A1(_hw_occ_output_toggle_after_match) )
454 else if ( wgm==5 || wgm==6 || wgm==7 ) {
455 if ( compare0->config.output !=
HW_A1(_hw_occ_output_disconnected)
456 && compare0->config.output !=
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
457 && compare0->config.output !=
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match) )
463 else if ( wgm==14 ) {
464 if ( compare0->config.output !=
HW_A1(_hw_occ_output_disconnected)
465 && compare0->config.output !=
HW_A1(_hw_occ_output_toggle_after_match)
466 && compare0->config.output !=
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
467 && compare0->config.output !=
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match) )
474 else if ( wgm==1 || wgm==2 || wgm==3 ) {
475 if ( compare0->config.output !=
HW_A1(_hw_occ_output_disconnected)
476 && compare0->config.output !=
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
477 && compare0->config.output !=
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down) )
483 else if ( wgm==8 || wgm==10 ) {
484 if ( compare0->config.output !=
HW_A1(_hw_occ_output_disconnected)
485 && compare0->config.output !=
HW_A1(_hw_occ_output_toggle_after_match)
486 && compare0->config.output !=
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
487 && compare0->config.output !=
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down) )
495 else if ( compare0->config.output )
502 if ( compare1->config.output != 0xFF ) {
503 if ( wgm==0 || wgm==4 || wgm==12 ) {
504 if ( compare1->config.output !=
HW_A1(_hw_occ_output_disconnected)
505 && compare1->config.output !=
HW_A1(_hw_occ_output_clear_after_match)
506 && compare1->config.output !=
HW_A1(_hw_occ_output_set_after_match)
507 && compare1->config.output !=
HW_A1(_hw_occ_output_toggle_after_match) )
513 else if ( wgm==5 || wgm==6 || wgm==7 || wgm==14 || wgm==15 ) {
514 if ( compare1->config.output !=
HW_A1(_hw_occ_output_disconnected)
515 && compare1->config.output !=
HW_A1(_hw_occ_output_set_at_bottom_clear_after_match)
516 && compare1->config.output !=
HW_A1(_hw_occ_output_clear_at_bottom_set_after_match) )
523 if ( compare1->config.output !=
HW_A1(_hw_occ_output_disconnected)
524 && compare1->config.output !=
HW_A1(_hw_occ_output_clear_after_match_up_set_after_match_down)
525 && compare1->config.output !=
HW_A1(_hw_occ_output_set_after_match_up_clear_after_match_down) )
535 if ( compare_update != 0xFF ) {
536 if ( wgm==0 || wgm==4 || wgm==12 ) {
537 if ( compare_update !=
HW_A1(_hw_occ_update_immediately) )
542 else if ( wgm==8 || wgm==9 ) {
543 if ( compare_update !=
HW_A1(_hw_occ_update_after_bottom) )
549 if( compare_update !=
HW_A1(_hw_occ_update_after_top) )
557 if ( overflow != 0xFF ) {
558 if ( (wgm==0 || wgm==4 || wgm==12) ) {
559 if ( overflow !=
HW_A1(_hw_ctdovf_after_max) )
564 else if ( (wgm==5 || wgm==6 || wgm==7 || wgm==14 || wgm==15) ) {
565 if ( overflow !=
HW_A1(_hw_ctdovf_after_top) )
570 else if ( overflow !=
HW_A1(_hw_ctdovf_after_bottom) )
600 #define hw_read__ctd , _hw_read_ctd
601 #define _hw_read_ctd(o,a,...) _hw_read(o,count) HW_EOL(__VA_ARGS__)
603 #define hw_write__ctd , _hw_write_ctd
604 #define _hw_write_ctd(o,a,v,...) _hw_write(o,count,v) HW_EOL(__VA_ARGS__)
606 #define hwa_write__ctd , _hwa_write_ctd
607 #define _hwa_write_ctd(o,a,v) _hwa_write(o,count,v)
616 #define _hwa_setup__ctd(o,a) \
617 _hwa_setup_r( o, ccra ); \
618 _hwa_setup_r( o, ccrb ); \
619 _hwa_setup_r( o, ocr0 ); \
620 _hwa_setup_r( o, ocr1 ); \
621 _hwa_setup_r( o, icr0 ); \
622 _hwa_setup_r( o, ccrc ); \
623 _hwa_setup_r( o, count ); \
624 _hwa_setup_r( o, imsk ); \
625 _hwa_setup_r( o, ifr ); \
626 hwa->o.config.clock = 0xFF ; \
627 hwa->o.config.direction = 0xFF ; \
628 hwa->o.config.top = 0xFF ; \
629 hwa->o.config.overflow = 0xFF ; \
630 hwa->o.compare0.config.update = 0xFF ; \
631 hwa->o.compare0.config.output = 0xFF ; \
632 hwa->o.compare1.config.update = 0xFF ; \
633 hwa->o.compare1.config.output = 0xFF ; \
634 hwa->o.capture0.config.input = 0xFF ; \
635 hwa->o.capture0.config.edge = 0xFF ; \
636 hwa->o.capture0.config.filter = 0xFF
638 #define _hwa_init__ctd(o,a) \
639 _hwa_init_r( o, ccra, 0 ); \
640 _hwa_init_r( o, ccrb, 0 ); \
641 _hwa_init_r( o, ocr0, 0 ); \
642 _hwa_init_r( o, ocr1, 0 ); \
643 _hwa_init_r( o, icr0, 0 ); \
644 _hwa_init_r( o, ccrc, 0 ); \
645 _hwa_init_r( o, count, 0 ); \
646 _hwa_init_r( o, imsk, 0 ); \
647 _hwa_init_r( o, ifr, 0 )
649 #define _hwa_commit__ctd(o,a) \
650 _hwa_commit_r( o, ccra ); \
651 _hwa_commit_r( o, ccrb ); \
652 _hwa_commit_r( o, ccrc ); \
653 _hwa_commit_r( o, count ); \
654 _hwa_commit_r( o, ocr0 ); \
655 _hwa_commit_r( o, ocr1 ); \
656 _hwa_commit_r( o, icr0 ); \
657 _hwa_commit_r( o, imsk ); \
658 _hwa_commit_r( o, ifr )