--- a/src/hello-lkm.c Sat Apr 05 02:19:36 2014 +0300
+++ b/src/hello-lkm.c Sat Apr 05 02:53:17 2014 +0300
@@ -415,6 +415,12 @@
// start
byte channels[4] = { };
+ enum channel_state {
+ CHANNEL_IDLE = 0,
+ CHANNEL_INC,
+ CHANNEL_DEC,
+ } channel_state[4] = { };
+ byte channel_count[4] = { };
char c;
while (true) {
@@ -422,26 +428,57 @@
byte buttons = lkm_buttons();
for (c = 0; c < 4; c++) {
+ enum channel_state state = channel_state[c], next;
+ byte count = channel_count[c];
+
+ // decode buttons -> state
if (buttons & 0b1) {
- channels[c]++;
- lkm_led(c * 2 + 0, LKM_LED_GREEN);
- lkm_led(c * 2 + 1, LKM_LED_OFF);
+ next = CHANNEL_INC;
} else if (buttons & 0b10) {
- channels[c]--;
- lkm_led(c * 2 + 0, LKM_LED_OFF);
- lkm_led(c * 2 + 1, LKM_LED_RED);
+ next = CHANNEL_DEC;
} else {
- lkm_led(c * 2 + 0, LKM_LED_OFF);
- lkm_led(c * 2 + 1, LKM_LED_OFF);
+ next = CHANNEL_IDLE;
}
buttons >>= 2;
+ // feedback
+ if (state == CHANNEL_INC || next == CHANNEL_INC)
+ lkm_led(c * 2 + 0, LKM_LED_GREEN);
+ else if (state == CHANNEL_DEC && next == CHANNEL_DEC)
+ lkm_led(c * 2 + 0, LKM_LED_RED);
+ else
+ lkm_led(c * 2 + 0, LKM_LED_OFF);
+
+ if (state == CHANNEL_DEC || next == CHANNEL_DEC)
+ lkm_led(c * 2 + 1, LKM_LED_RED);
+ else if (state == CHANNEL_INC && next == CHANNEL_INC)
+ lkm_led(c * 2 + 1, LKM_LED_GREEN);
+ else
+ lkm_led(c * 2 + 1, LKM_LED_OFF);
+
+ // counts
+ if ((channel_state[c] = next) != state)
+ channel_count[c] = 0;
+ else
+ count = ++channel_count[c];
+
+ // state transitions
+ if (next == CHANNEL_INC && count > 0) {
+ channels[c] += count;
+ } else if (next == CHANNEL_DEC && count > 0) {
+ channels[c] -= count;
+ } else if (state == CHANNEL_INC && !count) {
+ channels[c] = 0xff;
+ } else if (state == CHANNEL_DEC && !count) {
+ channels[c] = 0x00;
+ }
+
lkm_display_hh(c * 2, channels[c]);
-
+
xbi(&DEBUG_PORT, DEBUG_LED);
}
- timer_sleep(1000);
+ timer_sleep(8000);
}
}