hello: interactive console
authorTero Marttila <terom@paivola.fi>
Thu, 03 Apr 2014 22:24:46 +0300
changeset 54 ec42f36d8614
parent 53 dfe67409fbcd
child 55 04c625712e35
hello: interactive console
src/hello.c
src/timer.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 = '?';
         }
--- 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;
     }
 }