Rev 84 | Rev 86 | Go to most recent revision | Blame | Compare with Previous | 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/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "usbdrv.h"
//#include "oddebug.h"
#include "config.h"
#ifndef NULL
#define NULL ((void *)0)
#endif
/* ------------------------------------------------------------------------- */
uint8_t getKey(void);
void doButtons(void);
inline void setLeds(uint8_t);
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 buttons;
uint8_t waitup;
uint8_t timer;
} debounce;
uint8_t currleds = 128;
static uchar idleRate; /* in 4 ms units */
volatile uint8_t tmr0_ovf = 0;
volatile uint32_t systime = 0;
/* ------------------------------------------------------------------------- */
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x05, // USAGE (Game Pad)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x16, 0x00, 0x80, // Log Min -32768
0x26, 0xff, 0x7f, // Log max 32768
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
void usbEventResetReady(void) {
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){
if(rq->bRequest == USBRQ_HID_GET_REPORT){
return sizeof(reportBuffer);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
usbMsgPtr = &idleRate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
}else{
}
return 0;
}
void usbSendHidReport(uchar * data, uchar len) {
usbSetInterrupt(data, len);
}
int main(void) {
/*
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
*/
DDRD = 0B00000011;
PORTD = 0B00111111;
/*
PD0 -
PD1 -
PD2 -
PD3 -
PD4 -
PD5 - Output - LED 0
PD6 - Output - LED 1
PD7 - Output - LED 2
*/
DDRD = 0B11100000;
PORTD = 0B00000000;
setLeds(255);
_delay_ms(20);
setLeds(currleds);
usbDeviceDisconnect();
_delay_ms(500);
usbDeviceConnect();
wdt_enable(WDTO_1S);
TIMSK0 = (1<<TOIE0); // Enable timer overflow
TCNT0 = 0x00; // Set Timer0 initial value to 0
TCCR0B = (1<< CS00) ; // /1 prescaler
usbInit();
sei();
reportBuffer.axis0 = 0;
reportBuffer.axis1 = 0;
reportBuffer.buttons = 0;
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
doButtons();
if(usbInterruptIsReady()){
usbSendHidReport(&reportBuffer, sizeof(reportBuffer));
}
_delay_ms(1);
}
return 0;
}
inline void setLeds(uint8_t leds) {
PORTB |= (0x1F & (leds >> 3));
PORTD |= (0xE0 & (leds << 5));
}
void doButtons() {
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);
}
}
setLeds(currleds);
reportBuffer.buttons = debounce.buttons;
// Set debounce to wait to button up
debounce.waitup = 1;
}
}
// Gnd = PC0, PC1
// Btn = PC2, PC3, PC4, PC5
uint8_t getKey() {
uint8_t key = 0;
cbi(PORTC, 0);
_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, 0);
cbi(PORTC, 1);
_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, 1);
return key;
}
ISR(TIMER0_OVF_vect) {
tmr0_ovf++;
//16.5Mhz, 1ms = 50ovf
//12.0Mhz, 1ms = 46ovf
if (tmr0_ovf>=46) {
systime++;
tmr0_ovf = 0;
if (debounce.timer != 0)
debounce.timer--;
}
}