413 return 0; |
413 return 0; |
414 */ |
414 */ |
415 |
415 |
416 // start |
416 // start |
417 byte channels[4] = { }; |
417 byte channels[4] = { }; |
|
418 enum channel_state { |
|
419 CHANNEL_IDLE = 0, |
|
420 CHANNEL_INC, |
|
421 CHANNEL_DEC, |
|
422 } channel_state[4] = { }; |
|
423 byte channel_count[4] = { }; |
418 char c; |
424 char c; |
419 |
425 |
420 while (true) { |
426 while (true) { |
421 // scan input |
427 // scan input |
422 byte buttons = lkm_buttons(); |
428 byte buttons = lkm_buttons(); |
423 |
429 |
424 for (c = 0; c < 4; c++) { |
430 for (c = 0; c < 4; c++) { |
|
431 enum channel_state state = channel_state[c], next; |
|
432 byte count = channel_count[c]; |
|
433 |
|
434 // decode buttons -> state |
425 if (buttons & 0b1) { |
435 if (buttons & 0b1) { |
426 channels[c]++; |
436 next = CHANNEL_INC; |
427 lkm_led(c * 2 + 0, LKM_LED_GREEN); |
|
428 lkm_led(c * 2 + 1, LKM_LED_OFF); |
|
429 } else if (buttons & 0b10) { |
437 } else if (buttons & 0b10) { |
430 channels[c]--; |
438 next = CHANNEL_DEC; |
431 lkm_led(c * 2 + 0, LKM_LED_OFF); |
|
432 lkm_led(c * 2 + 1, LKM_LED_RED); |
|
433 } else { |
439 } else { |
434 lkm_led(c * 2 + 0, LKM_LED_OFF); |
440 next = CHANNEL_IDLE; |
435 lkm_led(c * 2 + 1, LKM_LED_OFF); |
|
436 } |
441 } |
437 |
442 |
438 buttons >>= 2; |
443 buttons >>= 2; |
439 |
444 |
|
445 // feedback |
|
446 if (state == CHANNEL_INC || next == CHANNEL_INC) |
|
447 lkm_led(c * 2 + 0, LKM_LED_GREEN); |
|
448 else if (state == CHANNEL_DEC && next == CHANNEL_DEC) |
|
449 lkm_led(c * 2 + 0, LKM_LED_RED); |
|
450 else |
|
451 lkm_led(c * 2 + 0, LKM_LED_OFF); |
|
452 |
|
453 if (state == CHANNEL_DEC || next == CHANNEL_DEC) |
|
454 lkm_led(c * 2 + 1, LKM_LED_RED); |
|
455 else if (state == CHANNEL_INC && next == CHANNEL_INC) |
|
456 lkm_led(c * 2 + 1, LKM_LED_GREEN); |
|
457 else |
|
458 lkm_led(c * 2 + 1, LKM_LED_OFF); |
|
459 |
|
460 // counts |
|
461 if ((channel_state[c] = next) != state) |
|
462 channel_count[c] = 0; |
|
463 else |
|
464 count = ++channel_count[c]; |
|
465 |
|
466 // state transitions |
|
467 if (next == CHANNEL_INC && count > 0) { |
|
468 channels[c] += count; |
|
469 } else if (next == CHANNEL_DEC && count > 0) { |
|
470 channels[c] -= count; |
|
471 } else if (state == CHANNEL_INC && !count) { |
|
472 channels[c] = 0xff; |
|
473 } else if (state == CHANNEL_DEC && !count) { |
|
474 channels[c] = 0x00; |
|
475 } |
|
476 |
440 lkm_display_hh(c * 2, channels[c]); |
477 lkm_display_hh(c * 2, channels[c]); |
441 |
478 |
442 xbi(&DEBUG_PORT, DEBUG_LED); |
479 xbi(&DEBUG_PORT, DEBUG_LED); |
443 } |
480 } |
444 |
481 |
445 timer_sleep(1000); |
482 timer_sleep(8000); |
446 } |
483 } |
447 } |
484 } |