Rev 79 | Rev 81 | 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/* ------------------------------------------------------------------------- */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 button;uint8_t timer;} buttons;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 2)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 - Output - ButtonPad 1PA1 - Output - ButtonPad 0PA2 - Output - Reset*/DDRD = 0B00000000;PORTD = 0B00000000;/*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 = 0B00000000;PORTB = 0B00000000;/*PD0 - Output - ButtonPad Gnd1PD1 - Output - ButtonPad Gnd2PD2 - Output - USB D+PD3 - Output - USB D-PD4 - Output - ButtonPad 2PD5 - Output - ButtonPad 3PD6 - Output - Select Switch*/DDRD = 0B01000000;PORTD = 0B00000000;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;PORTB = 0xaa;for(;;){ /* main event loop */wdt_reset();usbPoll();if(usbInterruptIsReady()){// ReportBuffer logic hereusbSendHidReport(&reportBuffer, sizeof(reportBuffer));}}return 0;}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 itpcInt[pcint].mask = 0;}ISR(PCINT_vect) {pcInterrupt(0);}ISR(TIMER0_OVF_vect) {tmr0_ovf++;if (tmr0_ovf>=50) {systime++;tmr0_ovf = 0;}}