Rev 93 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "usbdrv.h"
#include "config.h"
#ifndef NULL
#define NULL ((void *)0)
#endif
#define USB_GET_STATE 100
#define USB_LEDS_SET 101
/* ------------------------------------------------------------------------- */
uint8_t getKey(void);
void doButtons(uint8_t);
inline void setLeds(uint8_t);
struct {
int16_t axis[2];
uint8_t buttons;
} reportBuffer;
volatile struct {
uint8_t buttons;
uint8_t waitup;
uint8_t timer;
} debounce;
volatile struct {
uint8_t data;
union {
uint8_t led_method:1;
uint8_t other:1;
uint8_t reserved:6;
};
} config;
static uchar usbReplyBuf[16];
volatile uint8_t currLeds = 0;
volatile uint8_t currKeys = 0;
volatile uint8_t tmr0_ovf = 0;
volatile uint32_t systime = 0;
/* ------------------------------------------------------------------------- */
void hadUsbReset(void) {
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
switch (rq->bRequest ) {
case USB_GET_STATE:
usbReplyBuf[0] = currLeds;
usbReplyBuf[1] = currKeys;
usbMsgPtr = usbReplyBuf;
return sizeof(usbReplyBuf);
case USB_LEDS_SET:
currLeds = rq->wValue.bytes[0];
return 0;
}
return 0;
}
int main(void) {
DIDR0 = 0x00;
/*
DDR : 1 = Output, 0 = Input
PORT: 1 = Pullup for Input, otherwise set output
PIN : Read input pin
*/
/*
PB0 - Output - LED 3
PB1 - Output - LED 4
PB2 - Output - LED 5
PB3 - Output - LED 6
PB4 - Output - LED 7
PB5 -
PB6 -
PB7 -
*/
DDRB = 0B00011111;
PORTB = 0B00000000;
/*
PC0 - Output - ButtonPad Gnd0
PC1 - Output - ButtonPad Gnd1
PC2 - Input, Pullup - ButtonPad 0
PC3 - Input, Pullup - ButtonPad 1
PC4 - Input, Pullup - ButtonPad 2
PC5 - Input, Pullup - ButtonPad 3
*/
DDRC = 0B00000011;
PORTC = 0B00111111;
/*
PD0 -
PD1 -
PD2 -
PD3 -
PD4 -
PD5 - Output - LED 0
PD6 - Output - LED 1
PD7 - Output - LED 2
*/
DDRD = 0B11100000;
PORTD = 0B00000000;
setLeds(0xff);
usbDeviceDisconnect();
_delay_ms(500);
usbDeviceConnect();
TIMSK0 = (1<<TOIE0); // Enable timer overflow
TCNT0 = 0x00; // Set Timer0 initial value to 0
TCCR0B = (1<< CS00) ; // /1 prescaler
wdt_enable(WDTO_1S);
usbInit();
sei();
config.led_method = 1;
setLeds(currLeds);
for(;;){
wdt_reset();
usbPoll();
currKeys = getKey();
if (config.led_method != rbi(PORTB, 5)) {
// Reset the leds when switcing to buttons
if (config.led_method == 0) currLeds = 1;
config.led_method = rbi(PORTB, 5);
}
if (config.led_method == 1) {
uint8_t pressed = getKey();
doButtons(pressed);
}
setLeds(currLeds);
}
return 0;
}
inline void setLeds(uint8_t leds) {
PORTB &= 0xE0;
PORTB |= (0x1F & (leds >> 3));
PORTD &= 0x1F;
PORTD |= (0xE0 & (leds << 5));
}
void doButtons(uint8_t pressed) {
// 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 == 0 && rbi(currLeds, 1) != 1) //Dont turn off com1 if no comm2
break;
if ( i == 1 && rbi(currLeds, 0) != 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 == 0 && rbi(currLeds, 1) == 1) //Turn on comm2, turn off comm1
cbi(currLeds,1);
if ( i == 1 && rbi(currLeds, 0) == 1) //Turn on comm1, turn off comm2
cbi(currLeds,0);
sbi(currLeds, i);
}
}
debounce.waitup = 1;
}
}
// Gnd = PC0, PC1
// Btn = PC2, PC3, PC4, PC5
uint8_t getKey() {
uint8_t key = 0;
cbi(PORTC, 1);
_delay_us(10); // Wait for the port change
if (rbi(PINC, 2) == 0) key = 1;
if (rbi(PINC, 3) == 0) key = 2;
if (rbi(PINC, 4) == 0) key = 4;
if (rbi(PINC, 5) == 0) key = 8;
sbi(PORTC, 1);
cbi(PORTC, 0);
_delay_us(10);
if (rbi(PINC, 2) == 0) key = 16;
if (rbi(PINC, 3) == 0) key = 32;
if (rbi(PINC, 4) == 0) key = 64;
if (rbi(PINC, 5) == 0) key = 128;
sbi(PORTC, 0);
return key;
}
ISR(TIMER0_OVF_vect) {
tmr0_ovf++;
// Clk/1 TCCR0B = (1<< CS00);
//20.0Mhz, 1ms = 78ovf
//16.5Mhz, 1ms = 64ovf
//12.0Mhz, 1ms = 46ovf
if (tmr0_ovf>=78) {
systime++;
tmr0_ovf = 0;
if (debounce.timer != 0)
debounce.timer--;
}
}