# HG changeset patch # User Tero Marttila # Date 1396553086 -10800 # Node ID ec42f36d861491051468946dcc004787e8691952 # Parent dfe67409fbcd6364c0d0842db28ded0517bcb3de hello: interactive console diff -r dfe67409fbcd -r ec42f36d8614 src/hello.c --- a/src/hello.c Thu Apr 03 20:25:12 2014 +0300 +++ b/src/hello.c Thu Apr 03 22:24:46 2014 +0300 @@ -4,24 +4,149 @@ #include "timer.c" // XXX #include "serial.c" // XXX +static enum state { + START = '\n', + CMD_SET = 's', + ARG_CHAR = '0', + ERROR = '!', +} state = START, cmd = 0; + +static enum { + CMD_LED_1 = 0, +} cmd_led = 0; + +static char arg_char; + +static unsigned char led_state = 0; + +int command (enum state cmd) +{ + switch (cmd) { + case CMD_SET: + led_state = arg_char; + + return 0; + + default: + return 1; + } +} + +char input (char c) +{ + if (c == '\r') { + char ret = '?'; + + // command state + switch (state) { + case START: + cmd = 0; + break; + + case CMD_SET: + break; + + case ARG_CHAR: + break; + + case ERROR: + cmd = 0; + break; + } + + // command + if (!cmd) { + ret = ' '; + } else if (command(cmd)) { + ret = '!'; + } else { + ret = '\n'; + } + + // return to START with response + state = START; + return ret; + + } else if (31 < c && c < 128) { + // process input char + switch (state) { + case START: + if (c == 's') { + cmd = CMD_SET; + state = ARG_CHAR; + arg_char = 0; + return state; + + } else if (c == 'S') { + cmd = state = CMD_SET; + arg_char = 255; + return state; + } + break; + + /* + case CMD_SET: + if (c == '1') { + cmd_led = CMD_LED_1; + state = ARG_CHAR; + arg_char = 0; + } else { + state = ERROR; + } + + break; + */ + case ARG_CHAR: + if (c >= '0' && c <= '9') { + arg_char *= 10; + arg_char += (c - '0'); + + return c; + } + break; + } + + // reject + state = ERROR; + return ERROR; + + } else { + // ignore + return ' '; + } +} + int main (void) { timer_init(); serial_init(); - // LED + // led_init(); sbi(&DDRB, DDB5); sei(); - // blink - char c = 'X'; - short timeout = 8000; - short delta = 10; + // start + char c; + unsigned short timeout = 0; + + serial_write(state); while (true) { // toggle - xbi(&PORTB, PORTB5); + if (led_state == 0) { + timeout = 0; + cbi(&PORTB, PORTB5); + + } else if (led_state == 255) { + timeout = 0; + sbi(&PORTB, PORTB5); + + } else { + // as Hz + timeout = (16000 / led_state); + xbi(&PORTB, PORTB5); + } // sleep if (timer_sleep(timeout)) { @@ -29,6 +154,8 @@ } else if ((c = serial_read())) { // got serial data + c = input(c); + } else { c = '?'; } diff -r dfe67409fbcd -r ec42f36d8614 src/timer.c --- a/src/timer.c Thu Apr 03 20:25:12 2014 +0300 +++ b/src/timer.c Thu Apr 03 22:24:46 2014 +0300 @@ -69,8 +69,10 @@ */ char timer_sleep (int cycles) { - // set timer - timer1_start(cycles); + if (cycles) { + // set timer + timer1_start(cycles); + } // sleep // TODO: PRR @@ -88,14 +90,14 @@ // cleanup SMCR = 0; - if (tbi(&TIMER_FLAGS, TIMER1_BUSY)) { + if (cycles && !tbi(&TIMER_FLAGS, TIMER1_BUSY)) { + // timeout + return 1; + } else { timer1_stop(); // interrupt return 0; - } else { - // timeout - return 1; } }