/* Skip table: serial skip update -> update skip table computer state table update -> reset skip lines of updated computers Computer state table: Host state change detection -> lookup skip table -> update computer state table computer button toggle -> update computer state table serial logical computer state toggle -> update computer state table Outlet table: outlet toggle button -> update table computer state table update -> update table serial toggle command -> update table Outlet table update can start timer (doing eventually a relay switch on or off action), switch on relay directly, switch off relay directly. */ /* sources of wakeup are: * - every button press * - computer state input change * - uart rx */ #define OUTLET_BUTTONS_MASK 0x1F #define COMPUTER_BUTTONS_MASK 0x60 #define OUTLET_BUTTONS_SHIFT 0 #define COMPUTER_BUTTONS_SHIFT 5 static struct tables_t { volatile uint8_t buttons:7; // accessed by interrupt functions uint8_t buttons_old:7; volatile uint8_t computers:2; // accessed by interrupt functions uint8_t computers_old:2; uint8_t computer_state:2; uint8_t computer_state_old:2; } tables; static struct uart_t { volatile uint8_t rxfifo[8]; volatile uint8_t txfifo[8]; volatile uint8_t rxindex:4; volatile uint8_t txindex:4; } uart; static void interrupt_pin_change(void) { update_button_table(); update_computer_input_table(); } static void interrupt_uart_rx(void) { echo_back(); update_rx_fifo(); } static void process_uart_rx(void) { switch (get_next_char()) { case 'C': break; case 'T': break; case 'c': break; case 't': break; case 's': break; case 255: break; } } static void update_outlet_table(uint8_t changed) { } static void update_computer_table(uint8_t changed) { } static void main_loop(void) { uint8_t changed; for (;;) { // read tables.buttons only one time (8bits access, 8bits cpu, atomic) changed = tables.buttons ^ tables.buttons_old; tables.buttons_old ^= changed; if (changed & COMPUTER_BUTTONS_MASK) { update_computer_table(changed >> COMPUTER_BUTTONS_SHIFT); } changed = tables.computer_state ^ tables.computer_state_old; tables.computer_state_old ^= changed; if (changed & OUTLET_BUTTONS_MASK) { update_outlet_table(changed >> OUTLET_BUTTONS_SHIFT); } changed = tables.computer_state ^ tables.computer_state_old; tables.computer_state_old ^= changed; // read computers state change changed = tables.computers ^ tables.computers_old; if (changed) { } process_uart_rx(); standby(); } }