Subversion Repositories group.electronics

Rev

Rev 82 | Blame | Last modification | View Log | RSS feed

/* Name: main.c
 * Project: EasyLogger
 * Author: Christian Starkjohann
 * Creation Date: 2006-04-23
 * Tabsize: 4
 * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
 * License: Proprietary, free under certain conditions. See Documentation.
 * This Revision: $Id$
 */

#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#include "config.h"

#ifndef NULL
#define NULL    ((void *)0)
#endif

/* ------------------------------------------------------------------------- */

uint8_t getKey(void);

struct {
        union {
                int16_t axis[2];
                struct {
                        int16_t axis0:16;
                        int16_t axis1:16;
                };
                uint8_t buttons;
                struct {
                        int8_t b1:1;
                        int8_t b2:2;
                        int8_t b3:3;
                        int8_t b4:4;
                        int8_t b5:5;
                        int8_t b6:6;
                        int8_t b7:7;
                        int8_t b8:8;
                };
        };
} reportBuffer;

/*
volatile struct {
        uint8_t current;
        uint8_t last;
        uint8_t mask;
} pcInt[1];
*/


volatile struct {
        uint8_t buttons;
        uint8_t waitup;
        uint8_t timer;
} debounce;


volatile uint8_t tmr0_ovf = 0;
volatile uint32_t systime = 0;

/* ------------------------------------------------------------------------- */

int main(void) {

  /*
  DDR : 1 = Output, 0 = Input
  PORT: 1 = Pullup for Input, otherwise set output
  PIN : Read input pin
  */
  /*

        PA0     - Input, Pullup - ButtonPad 1
        PA1     - Input, Pullup - ButtonPad 0
        PA2     - Output        - Reset
  */
  DDRA          = 0B00000000;
  PORTA         = 0B00000011;
  /*
        PB0     - Output                - LED 0
        PB1     - Output                - LED 1
        PB2     - Output                - LED 2
        PB3     - Output                - LED 3
        PB4     - Output                - LED 4
        PB5     - Output                - LED 5
        PB6     - Output                - LED 6
        PB7     - Output                - LED 7
  */
  DDRB          = 0B11111111;
  PORTB         = 0B00000000;
  /*

        PD0     - Output        - ButtonPad Gnd1
        PD1     - Output        - ButtonPad Gnd2
        PD2     - Output        - USB D+
        PD3     - Output        - USB D-
        PD4     - Input, Pullup - ButtonPad 2
        PD5     - Input, Pullup - ButtonPad 3
        PD6     - Input, Pullup - Select Switch
  */
  DDRD          = 0B00000011;
  PORTD         = 0B01110011;


    TIMSK = (1<<TOIE0);                    // Enable timer overflow
    TCNT0 = 0x00;                           // Set Timer0 initial value to 0
    TCCR0B = (1<< CS01) ;                   // /1 prescaler

    sei();

    reportBuffer.axis0 = 0;
    reportBuffer.axis1 = 0;
    reportBuffer.buttons = 0;

        PORTB = 255;

        _delay_ms(20);

        uint8_t currleds = 0;
        PORTB = 128;

    for(;;){    /* main event loop */
        wdt_reset();

        uint8_t pressed = getKey();

        // Deboucing
        // When i key first goes down, wait 5 ms, check it again to see if its still down
        if (pressed && debounce.buttons == 0 && debounce.timer == 0) {
                debounce.buttons = pressed;
                debounce.timer = 5;
        }

        // The key has come up
        if (pressed != debounce.buttons) {
                debounce.buttons = 0;
                debounce.timer = 0;
                debounce.waitup = 0;
        }
        
        // Debounce timer is up, process our button     
        if (debounce.buttons && debounce.timer == 0 && debounce.waitup != 1) {
                uint8_t i = 0;
                for (i=0; i<=7; i++) {
                        // Button pressed and the led is currently on
                        if ( rbi(debounce.buttons, i) == 1 && rbi(currleds, i) == 1 ) {
                                if ( i == 6 && rbi(currleds, 7) != 1)  //Dont turn off com1 if no comm2
                                        break;

                                if ( i == 7 && rbi(currleds, 6) != 1)  //Dont turn off com2 if no comm1
                                        break;

                                cbi(currleds, i);
                        // Button is pressed and led is currently off
                         } else if ( rbi(debounce.buttons, i) == 1 && rbi(currleds, i) == 0 ) {
                                if ( i == 6 && rbi(currleds, 7) == 1)  //Turn on comm2, turn off comm1
                                        cbi(currleds,7);

                                if ( i == 7 && rbi(currleds, 6) == 1)  //Turn on comm1, turn off comm2
                                        cbi(currleds,6);

                                sbi(currleds, i);
                        }
                }
                PORTB = currleds;
                reportBuffer.buttons = debounce.buttons;
                // Set debounce to wait to button up
                debounce.waitup = 1;
        }

        _delay_ms(1);
    }
    return 0;
}

// Gnd = PD0, PD1
// Btn = PA1, PA0, PD4, PD5
uint8_t getKey() {
        uint8_t key = 0;

        cbi(PORTD, 0);
        _delay_us(10);        // Wait for the port change
        if (rbi(PIND, 5) == 0) key = 1;
        if (rbi(PIND, 4) == 0) key = 2;
        if (rbi(PINA, 0) == 0) key = 4;
        if (rbi(PINA, 1) == 0) key = 8;
        sbi(PORTD, 0);

        cbi(PORTD, 1);
        _delay_us(10);
        if (rbi(PIND, 5) == 0) key = 16;
        if (rbi(PIND, 4) == 0) key = 32;
        if (rbi(PINA, 0) == 0) key = 64;
        if (rbi(PINA, 1) == 0) key = 128;
        sbi(PORTD, 1);

        return key;
}

/*
void pcInterrupt(uint8_t pcint) {

        switch (pcint) {
                case 0: pcInt[pcint].current = PINB; break;
        }
        pcInt[pcint].mask = pcInt[pcint].current ^ pcInt[pcint].last;
        pcInt[pcint].last = pcInt[pcint].current;

        if (pcInt[pcint].mask == 0)
                return;

        // PCINT logic here

        // Clear the mask so we know we've delth with it
        pcInt[pcint].mask = 0;
}

ISR(PCINT0_vect) {
        pcInterrupt(0);
}
*/

ISR(TIMER0_OVF_vect) {
        tmr0_ovf++;

        //16.5Mhz, 1ms = 50 ovf

        if (tmr0_ovf>=5) {
                systime++;
                tmr0_ovf = 0;

                if (debounce.timer != 0)
                        debounce.timer--;
        }
}