Rev 81 | Rev 85 | 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/eeprom.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);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 -327680x26, 0xff, 0x7f, // Log max 327680x75, 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_COLLECTION0xc0 // END_COLLECTION};uchar usbFunctionSetup(uchar data[8]){usbRequest_t *rq = (void *)data;//usbMsgPtr = reportBuffer;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;}static void calibrateOscillator(void) {uchar step = 128;uchar trialValue = 0, optimumValue;int x, optimumDev;int targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);/* do a binary search: */do {OSCCAL = trialValue + step;x = usbMeasureFrameLength(); /* proportional to current real frequency */if(x < targetValue) /* frequency still too low */trialValue += step;step >>= 1;} while(step > 0);/* We have a precision of +/- 1 for optimum OSCCAL here *//* now do a neighborhood search for optimum value */optimumValue = trialValue;optimumDev = x; /* this is certainly far away from optimum */for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){x = usbMeasureFrameLength() - targetValue;if(x < 0)x = -x;if(x < optimumDev){optimumDev = x;optimumValue = OSCCAL;}}OSCCAL = optimumValue;}void usbEventResetReady(void) {cli();calibrateOscillator();sei();eeprom_write_byte(0, OSCCAL); /* store the calibrated value in EEPROM */}void usbSendHidReport(uchar * data, uchar len) {usbSetInterrupt(data, len);}int main(void) {uchar i;uchar calibrationValue;calibrationValue = eeprom_read_byte(0); /* calibration value from last time */if(calibrationValue != 0xff){OSCCAL = calibrationValue;}/*DDR : 1 = Output, 0 = InputPORT: 1 = Pullup for Input, otherwise set outputPIN : Read input pin*//*PA0 - Input, Pullup - ButtonPad 1PA1 - Input, Pullup - ButtonPad 0PA2 - Output - Reset*/DDRD = 0B00000000;PORTD = 0B00000011;/*PB0 - Output - LED 0PB1 - Output - LED 1PB2 - Output - LED 2PB3 - Output - LED 3PB4 - Output - LED 4PB5 - Output - LED 5PB6 - Output - LED 6PB7 - Output - LED 7*/DDRB = 0B11111111;PORTB = 0B00000000;/*PD0 - Output - ButtonPad Gnd1PD1 - Output - ButtonPad Gnd2PD2 - Output - USB D+PD3 - Output - USB D-PD4 - Input, Pullup - ButtonPad 2PD5 - Input, Pullup - ButtonPad 3PD6 - Input, Pullup - Select Switch*/DDRD = 0B00000011;PORTD = 0B01110011;PORTB = 255;_delay_ms(20);PORTB = currleds;//odDebugInit();usbDeviceDisconnect();for(i=0;i<20;i++){ /* 300 ms disconnect */_delay_ms(15);}usbDeviceConnect();wdt_enable(WDTO_1S);TIMSK = (1<<TOIE0); // Enable timer overflowTCNT0 = 0x00; // Set Timer0 initial value to 0TCCR0B = (1<< CS01) ; // /1 prescalerusbInit();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;}void doButtons() {uint8_t pressed = getKey();// 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 == 6 && rbi(currleds, 7) != 1) //Dont turn off com1 if no comm2break;if ( i == 7 && rbi(currleds, 6) != 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 == 6 && rbi(currleds, 7) == 1) //Turn on comm2, turn off comm1cbi(currleds,7);if ( i == 7 && rbi(currleds, 6) == 1) //Turn on comm1, turn off comm2cbi(currleds,6);sbi(currleds, i);}}PORTB = currleds;reportBuffer.buttons = debounce.buttons;// Set debounce to wait to button updebounce.waitup = 1;}}// Gnd = PD0, PD1// Btn = PA1, PA0, PD4, PD5uint8_t getKey() {uint8_t key = 0;cbi(PORTD, 0);_delay_us(10); // Wait for the port changeif (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;}ISR(TIMER0_OVF_vect) {tmr0_ovf++;//16.5Mhz, 1ms = 50ovfif (tmr0_ovf>=50) {systime++;tmr0_ovf = 0;if (debounce.timer != 0)debounce.timer--;}}