struct switchcfg { uint8_t targets0[2]; uint8_t targets1[2]; uint8_t lastclick; int8_t dir; __extension__ uint8_t tgt1active : 1; __extension__ uint8_t enabled : 1; __extension__ uint8_t unused : 6; }; #define T_DOUBLECLICK 75 static struct switchcfg sw; static uint8_t tast_curstate(void) { uint16_t sum = 0; sum += target_get(sw.targets0[0]); sum += target_get(sw.targets0[1]); if (sw.tgt1active) { sum += target_get(sw.targets1[0]); sum += target_get(sw.targets1[1]); sum++; sum >>= 1; } sum++; sum >>= 1; return sum; } static void tast_applystate(uint8_t all, uint8_t target) { if (!sw.enabled) return; target_set(sw.targets0[0], target); target_set(sw.targets0[1], target); if (all) { target_set(sw.targets1[0], target); target_set(sw.targets1[1], target); } } static void tast_click(void) { uint8_t ltarget, all; uart_puts("# click\n"); if (sw.lastclick < T_DOUBLECLICK) { sw.lastclick = T_DOUBLECLICK; sw.tgt1active = 1; sw.dir = -1; ltarget = 0xff; all = 1; } else { sw.lastclick = 0; ltarget = tast_curstate(); if (ltarget) { sw.tgt1active = 0; sw.dir = +1; ltarget = 0; all = 1; } else { sw.dir = -1; ltarget = 0xff; all = 0; } } tast_applystate(all, ltarget); } static void do_tick(void) { static uint8_t history; static uint8_t downctr; uint8_t state; history <<= 1; history |= (PIND >> D_TAST) & 1; if (sw.lastclick < 0xff) sw.lastclick++; if (history & 0x3f) { if (!downctr) return; if (downctr < 60) { //PORTD &= ~(1 << D_LED1); tast_click(); } else sw.dir = -sw.dir; downctr = 0; return; } if (downctr < 60) { PORTD |= (1 << D_LED1); downctr++; } else { state = tast_curstate(); PORTD &= ~(1 << D_LED1); uart_puts("\t# dim "); uart_puthex(state); uart_puts(" "); uart_puthex(sw.dir); uart_puts("\n"); for (int i = 0; i < 6; i++) { state += sw.dir; if (state == 0xff) state = 0xfe; if (state < 0x55) state = 0x55; } tast_applystate(sw.tgt1active, state); } } static void dim_init(void) { sw.targets0[0] = 0x03; sw.targets0[1] = 0x04; sw.targets1[0] = 0x01; sw.targets1[1] = 0x02; sw.lastclick = 0xff; sw.dir = 1; sw.tgt1active = 0; sw.enabled = 1; }