src/carboard.c
author Tero Marttila <terom@paivola.fi>
Wed, 08 Oct 2014 23:21:01 +0300
changeset 5 5c86d54080c1
parent 4 d0f29c45fe52
permissions -rw-r--r--
carboard: use adxl for x/y/z readings and data; signed sensor values are still completely broken
#include <avr/interrupt.h>
#include <avr/io.h>

#include "stdlib.h"

#define DEBUG_DDR DDRB
#define DEBUG_PIN 5
#define DEBUG_PORT PORTB

/* Relay outputs */
#define RELAY_DDR DDRC
#define RELAY_PORT PORTC
#define RELAY_PIN PINC
#define RELAY_PINS 4

#define RELAY_DOWN1 0
#define RELAY_DOWN2 1
#define RELAY_LEFT  2
#define RELAY_RIGHT 3

/* Switch inputs */
static ioport_t *const SWITCH_DDR = &DDRD;
static ioport_t *const SWITCH_PORT = &PORTD;
static ioport_t *const SWITCH_PIN = &PIND;
static ioport_t *const SWITCH_PCMSK = &PCMSK2;
static const byte SWITCH_PCIE = PCIE2;
static const byte SWITCH_PCIF = PCIF2;

enum switch_bits {
    SWITCH_LEFT         = 0b00000100,
    SWITCH_RIGHT        = 0b00001000,
    SWITCH_HORN1        = 0b00010000,
    SWITCH_HORN2        = 0b00100000,

    SWITCH_MASK         = 0b00111100,
};

#include "adxl345.h"
#include "debug.h"
#include "relay.h"
#include "serial.h"
#include "spi.h"
#include "switch.h"
#include "timer.h"

int main (void)
{
    adxl345_init();
    debug_init();
    relay_init(RELAY_PINS);
    serial_init(SERIAL_BAUD_9600, SERIAL_PARITY_N, SERIAL_STOPBITS_1);
    spi_init();
    switch_init();
    timer_init();

    // init
    unsigned char c = '.';
    byte s;
    unsigned short timeout = 8000;
    int16_t adxl;

    debug_set();
    sei();

    adxl345_setup();

    // start
    while (true) {
        c = s = 0;
        adxl = 0;

        if (timer_sleep(timeout)) {
            c = 0;
        } else if ((c = serial_read())) {
            switch (c) {
                case 'L':       relay_open(RELAY_LEFT); break;
                case 'R':       relay_open(RELAY_RIGHT); break;
                case 'B':
                                relay_open(RELAY_DOWN1);
                                relay_open(RELAY_DOWN2);
                                break;

                case 'l':       relay_toggle(RELAY_LEFT); break;
                case 'r':       relay_toggle(RELAY_RIGHT); break;
                case 'b':
                                relay_close(RELAY_DOWN1);
                                relay_close(RELAY_DOWN2);
                                break;

                case 'd':       c = adxl345_read_devid(); break;
                case 'x':       adxl = adxl345_read_x(); break;
                case 'y':       adxl = adxl345_read_y(); break;
                case 'z':       adxl = adxl345_read_z(); break;

                default:
                    c = '!';
                    break;
            }
        } else if (switch_read(&s)) {
            c = '*';

            if (s & SWITCH_LEFT)
                c = 'l';

            if (s & SWITCH_RIGHT)
                c = 'r';

            if (s & SWITCH_HORN1)
                c = 'h';

            if (s & SWITCH_HORN2)
                c = 'h';

        } else {
            // XXX: for some reason this occasionally gets stuck in an interrupt loop here after some switch events..
            c = '?';
        }

        // out
        debug_toggle();

        if (c == 'x' || c == 'y' || c == 'z') {
            int8_t v = adxl / 255;

            /*
            if (adxl > 0)
                serial_write('+');
            else if (adxl < 0)
                serial_write('-');
            else
                serial_write(' ');
            */
            serial_write(v);
        } else if (c) {
            serial_write(c);
        }
    }
}