Rev 18 | Go to most recent revision | 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 = InputPORT: 1 = Pullup for Input, otherwise set outputPIN : Read input pin*//*PB0 - Output - LED 3PB1 - Output - LED 4PB2 - Output - LED 5PB3 - Output - LED 6PB4 - Output - LED 7PB5 -PB6 -PB7 -*/DDRB = 0B00011111;PORTB = 0B00000000;/*PC0 - Output - ButtonPad Gnd0PC1 - Output - ButtonPad Gnd1PC2 - Input, Pullup - ButtonPad 0PC3 - Input, Pullup - ButtonPad 1PC4 - Input, Pullup - ButtonPad 2PC5 - Input, Pullup - ButtonPad 3*/DDRC = 0B00000011;PORTC = 0B00111111;/*PD0 -PD1 -PD2 -PD3 -PD4 -PD5 - Output - LED 0PD6 - Output - LED 1PD7 - Output - LED 2*/DDRD = 0B11100000;PORTD = 0B00000000;setLeds(0xff);usbDeviceDisconnect();_delay_ms(500);usbDeviceConnect();TIMSK0 = (1<<TOIE0); // Enable timer overflowTCNT0 = 0x00; // Set Timer0 initial value to 0TCCR0B = (1<< CS00) ; // /1 prescalerwdt_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 buttonsif (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 downif (pressed && debounce.buttons == 0 && debounce.timer == 0) {debounce.buttons = pressed;debounce.timer = 5;}// The key has come upif (pressed != debounce.buttons) {debounce.buttons = 0;debounce.timer = 0;debounce.waitup = 0;}// Debounce timer is up, process our buttonif (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 onif ( rbi(debounce.buttons, i) == 1 && rbi(currLeds, i) == 1 ) {if ( i == 0 && rbi(currLeds, 1) != 1) //Dont turn off com1 if no comm2break;if ( i == 1 && rbi(currLeds, 0) != 1) //Dont turn off com2 if no comm1break;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 comm1cbi(currLeds,1);if ( i == 1 && rbi(currLeds, 0) == 1) //Turn on comm1, turn off comm2cbi(currLeds,0);sbi(currLeds, i);}}debounce.waitup = 1;}}// Gnd = PC0, PC1// Btn = PC2, PC3, PC4, PC5uint8_t getKey() {uint8_t key = 0;cbi(PORTC, 1);_delay_us(10); // Wait for the port changeif (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 = 46ovfif (tmr0_ovf>=78) {systime++;tmr0_ovf = 0;if (debounce.timer != 0)debounce.timer--;}}