src/hello.c
author Tero Marttila <terom@paivola.fi>
Sun, 20 Apr 2014 23:51:57 +0300
changeset 80 5254ba612630
parent 57 ee412c5be8b1
permissions -rw-r--r--
dmx-web: slightly better RGB colorpicker control..
#include <avr/io.h>

#include "stdlib.h"

// XXX
#include "timer.c"
#include "serial.c"
#include "spi.c"
#include "led7.c"

static enum state {
    START       = '\n',
    CMD_SET     = 's',
    CMD_INC     = '+',
    CMD_DEC     = '-',
    CMD_READ    = 'r',
    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;

        case CMD_INC:
            if (led_state == 0xff)
                return 1;

            led_state++;
            return 0;

        case CMD_DEC:
            if (!led_state)
                return 1;

            led_state--;
            return 0;

        case CMD_READ:
            led_state = spi_rx[1]; // XXX
            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:
            case CMD_INC:
            case CMD_DEC:
                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;
                } else if (c == 'S') {
                    cmd = state = CMD_SET;
                    arg_char = 255;
                } else if (c == '+') {
                    cmd = state = CMD_INC;
                } else if (c == '-') {
                    cmd = state = CMD_DEC;
                } else if (c == 'r') {
                    cmd = state = CMD_READ;
                } else {
                    break;
                }
                
                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');
                } else {
                    break;
                }
                    
                return c;
            break;
        }

        // reject
        state = ERROR;
        return ERROR;

    } else {
        // ignore
        return ' ';
    }
}


#define DEBUG_DDR   DDRB
#define DEBUG_PORT  PORTB
#define DEBUG_LED   0

int main (void)
{
    led7_init();
    timer_init();
    serial_init();
    spi_init();

    // led_init();
    sbi(&DEBUG_DDR, DEBUG_LED);

    sei();

    // start
    char c;
    unsigned short timeout = 0;
        
    serial_write(state);

    while (true) {
        // TODO: SPI timer
        led7_update(led_state);
        spi_update();

        // toggle
        if (led_state == 0) {
            timeout = 0;
            cbi(&DEBUG_PORT, DEBUG_LED);

        } else if (led_state == 255) {
            timeout = 0;
            sbi(&DEBUG_PORT, DEBUG_LED);

        } else {
            // as Hz
            timeout = (16000 / led_state);
            xbi(&DEBUG_PORT, DEBUG_LED);
        }
        
        // sleep
        if (timer_sleep(timeout)) {
            c = '.';

        } else if ((c = serial_read())) {
            // got serial data
            c = input(c);

        } else {
            c = '?';
        }
        
        // output...
        serial_write(c);
    }
}