94 #define hwa_configure__cta , _hwa_cfcta
101 #define _hwa_cfcta(o,a,k,...) \
102 do { HW_B(_hwa_cfcta_kclock_,_hw_is_clock_##k)(o,k,__VA_ARGS__,,) } while(0)
104 #define _hwa_cfcta_kclock_0(o,k,...) HW_E(HW_EM_AN(k,clock))
105 #define _hwa_cfcta_kclock_1(o,k,v,...) HW_B(_hwa_cfcta_vclock_,_hw_c1clk_##v)(o,v,__VA_ARGS__)
106 #define _hwa_cfcta_vclock_0(o,v,...) HW_E(HW_EM_VAL(v,clock,(none,ioclk/8,ioclk/64,ioclk/256,ioclk/1024,external_falling,external_rising)))
108 #define _hwa_cfcta_vclock_1(o,v,k,...) \
109 hwa->o.config.clock = HW_VF(_hw_c1clk_##v); \
110 HW_B(_hwa_cfcta_kmode_,_hw_is_direction_##k)(o,k,__VA_ARGS__)
114 #define _hw_cta_direction_up_loop , 1
115 #define _hw_cta_direction_updown_loop , 2
117 #define _hwa_cfcta_kmode_0(o,k,...) HW_E(HW_EM_AN(k,direction))
118 #define _hwa_cfcta_kmode_1(o,k,v,...) HW_B(_hwa_cfcta_vmode_,_hw_cta_direction_##v)(o,v,__VA_ARGS__)
119 #define _hwa_cfcta_vmode_0(o,v,...) HW_E(HW_EM_VAL(v,direction,(up_loop,updown_loop)))
120 #define _hwa_cfcta_vmode_1(o,v,k,...) \
121 hwa->o.config.direction = HW_A1(_hw_cta_direction_##v); \
122 HW_B(_hwa_cfcta_kbottom_,_hw_is_bottom_##k)(o,k,__VA_ARGS__)
126 #define _hwa_cfcta_kbottom_1(o,k,v,...) HW_G2(_hwa_cfcta_vbottom,HW_IS(0,v))(o,v,__VA_ARGS__)
127 #define _hwa_cfcta_vbottom_0(o,v,...) HW_E(HW_EM_VAL(v,bottom,(0)))
128 #define _hwa_cfcta_vbottom_1(o,v,k,...) HW_B(_hwa_cfcta_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
129 #define _hwa_cfcta_kbottom_0(o,k,...) HW_B(_hwa_cfcta_ktop_,_hw_is_top_##k)(o,k,__VA_ARGS__)
133 #define _hw_cta_top_0xFF , 1
134 #define _hw_cta_top_0x00FF , 1
135 #define _hw_cta_top_255 , 1
136 #define _hw_cta_top_max , 1
137 #define _hw_cta_top_compare0 , 2
139 #define _hwa_cfcta_ktop_1(o,k,v,...) HW_B(_hwa_cfcta_vtop_,_hw_cta_top_##v)(o,v,__VA_ARGS__)
140 #define _hwa_cfcta_vtop_0(o,v,...) HW_E(HW_EM_VAL(v,top,(0xFF,max,compare0)))
141 #define _hwa_cfcta_vtop_1(o,v,k,...) \
142 hwa->o.config.top = HW_A1(_hw_cta_top_##v); \
143 HW_B(_hwa_cfcta_koverflow_,_hw_is_overflow_##k)(o,k,__VA_ARGS__)
145 #define _hwa_cfcta_ktop_0(o,k,...) HW_B(_hwa_cfcta_koverflow_,_hw_is_overflow_##k)(o,k,__VA_ARGS__)
149 #define _hw_cta_overflow_after_bottom , 0
150 #define _hw_cta_overflow_after_top , 1
151 #define _hw_cta_overflow_after_max , 2
153 #define _hwa_cfcta_koverflow_1(o,k,v,...) HW_B(_hwa_cfcta_voverflow_,_hw_cta_overflow_##v)(o,v,__VA_ARGS__)
154 #define _hwa_cfcta_voverflow_0(o,v,...) HW_E(HW_EM_VOAL(v,overflow,(after_bottom,after_top,after_max)))
155 #define _hwa_cfcta_voverflow_1(o,v,...) \
156 if ( hwa->o.config.direction == HW_A1(_hw_cta_direction_up_loop) \
157 && HW_A1(_hw_cta_overflow_##v) == HW_A1(_hw_cta_overflow_after_bottom) ) \
158 HWA_E(HW_EM_VOAL(v,overflow,(after_max,after_top))); \
159 hwa->o.config.overflow = HW_A1(_hw_cta_overflow_##v); HW_EOL(__VA_ARGS__)
161 #define _hwa_cfcta_koverflow_0(o,...) \
176 #define _hwa_solve__cta( o,a ) \
178 uint8_t r = _hwa_solve_cta( &hwa->o, &hwa->o.compare0, &hwa->o.compare1 ); \
183 if ( hwa->o.solved.cs != 0xFF ) _hwa_write( o, cs, hwa->o.solved.cs ); \
184 if ( hwa->o.solved.wgm != 0xFF ) _hwa_write( o, wgm, hwa->o.solved.wgm ); \
185 if ( hwa->o.compare0.solved.com != 0xFF ) _hwa_write( o, com0, hwa->o.compare0.solved.com ); \
186 if ( hwa->o.compare1.solved.com != 0xFF ) _hwa_write( o, com1, hwa->o.compare1.solved.com ); \
190 if ( hwa->o.compare0.config.output != 0xFF \
191 && hwa->o.compare0.config.output != HW_A1(_hw_oca_output_disconnected) ) \
192 _hwa( configure, (o,compare0,pin), mode, digital_output ); \
193 if ( hwa->o.compare1.config.output != 0xFF \
194 && hwa->o.compare1.config.output != HW_A1(_hw_oca_output_disconnected) ) \
195 _hwa( configure, (o,compare1,pin), mode, digital_output ); \
198 HWA_E(HW_EM_ADOO(update,(o,compare0),(o,compare1))); \
200 HWA_E(HW_EM_XSO(wgm,o)); \
202 HWA_E(HW_EM_COR(o)); \
204 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
205 toggle_after_match, \
207 set_after_match))); \
209 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
210 set_at_bottom_clear_after_match, \
211 clear_at_bottom_set_after_match))); \
213 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
214 toggle_after_match, \
215 set_at_bottom_clear_after_match, \
216 clear_at_bottom_set_after_match))); \
218 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
219 clear_after_match_up_set_after_match_down, \
220 set_after_match_up_clear_after_match_down))); \
222 HWA_E(HW_EM_AVOL(mode,compare0, (disconnected, \
223 toggle_after_match, \
224 clear_after_match_up_set_after_match_down, \
225 set_after_match_up_clear_after_match_down))); \
227 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
228 toggle_after_match, \
230 set_after_match))); \
231 else if ( r == 10 ) \
232 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
233 set_at_bottom_clear_after_match, \
234 clear_at_bottom_set_after_match))); \
235 else if ( r == 11 ) \
236 HWA_E(HW_EM_AVOL(mode,compare1, (disconnected, \
237 clear_after_match_up_set_after_match_down, \
238 set_after_match_up_clear_after_match_down))); \
239 else if ( r == 12 ) \
240 HWA_E(HW_EM_AOVM(update,o,immediately)); \
241 else if ( r == 13 ) \
242 HWA_E(HW_EM_AOVM(update,o,after_bottom)); \
243 else if ( r == 14 ) \
244 HWA_E(HW_EM_AOVM(update,o,after_top)); \
245 else if ( r == 15 ) \
246 HWA_E(HW_EM_AOVM(overflow,o,after_top)); \
247 else if ( r == 16 ) \
248 HWA_E(HW_EM_AOVM(overflow,o,after_bottom)); \
249 else if ( r == 17 ) \
250 HWA_E(HW_EM_AOVM(overflow,o,after_max)); \
252 HWA_E(HW_EM_X(in _hwa_solve__cta: __LINE__)); \
256 HW_INLINE uint8_t _hwa_solve_cta ( hwa_cta_t *p, hwa_oca_t *compare0, hwa_oca_t *compare1 )
260 p->solved.cs = 0xFF ;
261 p->solved.wgm = 0xFF ;
262 compare0->solved.com = 0xFF ;
263 compare1->solved.com = 0xFF ;
265 if ( p->config.clock == 0xFF )
270 p->solved.cs = p->config.clock ;
274 if ( p->config.top == 0xFF )
275 p->config.top =
HW_A1(_hw_cta_top_max);
279 uint8_t overflow = p->config.overflow ;
280 if ( overflow == 0xFF && p->config.top ==
HW_A1(_hw_cta_top_compare0) ) {
281 if ( p->config.direction ==
HW_A1(_hw_cta_direction_up_loop) )
282 overflow =
HW_A1(_hw_cta_overflow_after_top);
284 overflow =
HW_A1(_hw_cta_overflow_after_bottom);
289 uint8_t compare_update = 0xFF ;
290 if ( compare0->config.update != 0xFF && compare1->config.update != 0xFF
291 && compare0->config.update != compare1->config.update )
294 compare_update = compare0->config.update ;
315 if ( p->config.direction ==
HW_A1(_hw_cta_direction_up_loop) ) {
316 if ( p->config.top ==
HW_A1(_hw_cta_top_0xFF) ) {
317 if ( compare_update ==
HW_A1(_hw_oca_update_after_bottom)
318 || compare0->config.output ==
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
319 || compare0->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
320 || compare1->config.output ==
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
321 || compare1->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match))
333 if ( compare_update ==
HW_A1(_hw_oca_update_after_bottom )
334 || overflow ==
HW_A1(_hw_cta_overflow_after_top)
335 || compare0->config.output ==
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
336 || compare0->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
337 || compare1->config.output ==
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match)
338 || compare1->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match))
345 if ( p->config.top ==
HW_A1(_hw_cta_top_0xFF) )
356 p->solved.wgm = wgm ;
361 if ( compare0->config.output != 0xFF ) {
363 uint8_t mode = 0xFF ;
365 if ( compare0->config.output ==
HW_A1(_hw_oca_output_disconnected) )
367 else if ( compare0->config.output ==
HW_A1(_hw_oca_output_toggle_after_match) )
369 else if ( compare0->config.output ==
HW_A1(_hw_oca_output_clear_after_match)
370 || compare0->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
371 || compare0->config.output ==
HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down) )
376 compare0->solved.com = mode ;
382 if ( compare1->config.output != 0xFF ) {
384 uint8_t mode = 0xFF ;
386 if ( compare1->config.output ==
HW_A1(_hw_oca_output_disconnected) )
388 else if ( compare1->config.output ==
HW_A1(_hw_oca_output_toggle_after_match) )
390 else if ( compare1->config.output ==
HW_A1(_hw_oca_output_clear_after_match)
391 || compare1->config.output ==
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
392 || compare1->config.output ==
HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down) )
397 compare1->solved.com = mode ;
402 if ( compare0->config.output != 0xFF ) {
403 if ( wgm==0 || wgm==2 ) {
404 if ( compare0->config.output !=
HW_A1(_hw_oca_output_disconnected)
405 && compare0->config.output !=
HW_A1(_hw_oca_output_toggle_after_match)
406 && compare0->config.output !=
HW_A1(_hw_oca_output_clear_after_match)
407 && compare0->config.output !=
HW_A1(_hw_oca_output_set_after_match))
415 if ( compare0->config.output !=
HW_A1(_hw_oca_output_disconnected)
416 && compare0->config.output !=
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
417 && compare0->config.output !=
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
424 if ( compare0->config.output !=
HW_A1(_hw_oca_output_disconnected)
425 && compare0->config.output !=
HW_A1(_hw_oca_output_toggle_after_match)
426 && compare0->config.output !=
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
427 && compare0->config.output !=
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
435 if ( compare0->config.output !=
HW_A1(_hw_oca_output_disconnected)
436 && compare0->config.output !=
HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
437 && compare0->config.output !=
HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
444 if ( compare0->config.output !=
HW_A1(_hw_oca_output_disconnected)
445 && compare0->config.output !=
HW_A1(_hw_oca_output_toggle_after_match)
446 && compare0->config.output !=
HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
447 && compare0->config.output !=
HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
458 if ( compare1->config.output != 0xFF ) {
459 if ( wgm==0 || wgm==2 ) {
460 if ( compare1->config.output !=
HW_A1(_hw_oca_output_disconnected)
461 && compare1->config.output !=
HW_A1(_hw_oca_output_toggle_after_match)
462 && compare1->config.output !=
HW_A1(_hw_oca_output_clear_after_match)
463 && compare1->config.output !=
HW_A1(_hw_oca_output_set_after_match))
469 else if ( wgm==3 || wgm==7 ) {
470 if ( compare1->config.output !=
HW_A1(_hw_oca_output_disconnected)
471 && compare1->config.output !=
HW_A1(_hw_oca_output_set_at_bottom_clear_after_match)
472 && compare1->config.output !=
HW_A1(_hw_oca_output_clear_at_bottom_set_after_match) )
478 else if ( wgm==1 || wgm==5 ) {
479 if ( compare1->config.output !=
HW_A1(_hw_oca_output_disconnected)
480 && compare1->config.output !=
HW_A1(_hw_oca_output_clear_after_match_up_set_after_match_down)
481 && compare1->config.output !=
HW_A1(_hw_oca_output_set_after_match_up_clear_after_match_down) )
491 if ( compare_update != 0xFF ) {
492 if ( wgm==0 || wgm==2 ) {
493 if ( compare_update !=
HW_A1(_hw_oca_update_immediately) )
498 else if ( wgm==3 || wgm==7 ) {
499 if ( compare_update !=
HW_A1(_hw_oca_update_after_bottom) )
505 if( compare_update !=
HW_A1(_hw_oca_update_after_top) )
513 if ( overflow != 0xFF ) {
515 if ( overflow !=
HW_A1(_hw_cta_overflow_after_top) )
520 else if ( (wgm==1 || wgm==5) ) {
521 if ( overflow !=
HW_A1(_hw_cta_overflow_after_bottom) )
526 else if ( overflow !=
HW_A1(_hw_cta_overflow_after_max) )
555 #define hw_read__cta , _hw_read_cta
556 #define _hw_read_cta(o,a,...) _hw_read(o,count) HW_EOL(__VA_ARGS__)
558 #define hw_write__cta , _hw_write_cta
559 #define _hw_write_cta(o,a,v,...) _hw_write(o,count,v) HW_EOL(__VA_ARGS__)
561 #define hwa_write__cta , _hwa_write_cta
562 #define _hwa_write_cta(o,a,v,...) _hwa_write(o,count,v) HW_EOL(__VA_ARGS__)
574 #define hw_clear__cta , _hw_clear_cta
575 #define _hw_clear_cta(o,a,...) _hw_write(o,count,0) HW_EOL(__VA_ARGS__)
584 #define _hwa_setup__cta(o,a) \
586 _hwa_setup_r( o, ccra); \
587 _hwa_setup_r( o, ccrb); \
588 _hwa_setup_r( o, count); \
589 _hwa_setup_r( o, imsk); \
590 _hwa_setup_r( o, ifr); \
591 _hwa_setup_r( o, ocr0); \
592 _hwa_setup_r( o, ocr1); \
593 hwa->o.config.clock = 0xFF; \
594 hwa->o.config.direction = 0xFF; \
595 hwa->o.config.top = 0xFF; \
596 hwa->o.config.overflow = 0xFF; \
597 hwa->o.compare0.config.update = 0xFF ; \
598 hwa->o.compare0.config.output = 0xFF ; \
599 hwa->o.compare1.config.update = 0xFF ; \
600 hwa->o.compare1.config.output = 0xFF
603 #define _hwa_init__cta(o,a) \
605 _hwa_init_r( o, ccra, 0 ); \
606 _hwa_init_r( o, ccrb, 0 ); \
607 _hwa_init_r( o, count, 0 ); \
608 _hwa_init_r( o, imsk, 0 ); \
609 _hwa_init_r( o, ifr, 0 ); \
610 _hwa_init_r( o, ocr0, 0 ); \
611 _hwa_init_r( o, ocr1, 0 )
614 #define _hwa_commit__cta(o,a) \
616 _hwa_commit_r( o, ccra); \
617 _hwa_commit_r( o, ccrb); \
618 _hwa_commit_r( o, count); \
619 _hwa_commit_r( o, ocr0 ); \
620 _hwa_commit_r( o, ocr1 ); \
621 _hwa_commit_r( o, imsk); \
622 _hwa_commit_r( o, ifr)