Rev 20 | 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#define USB_GET_ANALOG 102#define USB_SET_POWER_LED 103/* ------------------------------------------------------------------------- */uint8_t getKey(void);inline void setLeds();void analogInit();uint8_t analogRead(uint8_t channel);/*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 pwrLed = 0;volatile uint8_t currLeds = 0;volatile uint8_t currKeys = 0;volatile uint8_t analogPin = 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;case USB_GET_ANALOG:usbReplyBuf[0] = (analogPin);usbMsgPtr = usbReplyBuf;return sizeof(usbReplyBuf);case USB_SET_POWER_LED:pwrLed = rq->wValue.bytes[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 - Input - Config Switch 1PB6 - OscPB7 - Osc*/DDRB = 0B00011111;PORTB = 0B00000000;/*PC0 - Input, ADC - PotentiometerPC1 - Output - Power LEDPC2 - Input, Pullup - ButtonPad 0PC3 - Input, Pullup - ButtonPad 1PC4 - Input, Pullup - ButtonPad 2PC5 - Input, Pullup - ButtonPad 3PC6 - Reset*/DDRC = 0B00000010;PORTC = 0B00111100;/*PD0 - Output - ButtonPad Gnd0PD1 - Output - ButtonPad Gnd1PD2 - USB D+PD3 - USB D-PD4 - Input - Config Switch 2PD5 - Output - LED 0PD6 - Output - LED 1PD7 - Output - LED 2*/DDRD = 0B11100011;PORTD = 0B00000011;// The USB connect stuff, flash the power ledsbi(PORTC, PC1);usbDeviceDisconnect();_delay_ms(500);usbDeviceConnect();cbi(PORTC, PC1);// @TODO: Don't really need the system time anymore, remove?TIMSK0 = (1<<TOIE0); // Enable timer overflowTCNT0 = 0x00; // Set Timer0 initial value to 0TCCR0B = (1<< CS00) ; // /1 prescalerwdt_enable(WDTO_1S); // WatchDog at 1susbInit(); // Init the USB portsei(); // Enable interruptssetLeds(); // Set default LED statusanalogInit(); // Init the ADC for PC0 (ADC0)/** @TODO: PowerSave - Only read ADC every 100ms* @TODO: PowerSave - Only set leds on change* @TODO: PowerSave - Sleep for a few us each cycle*/for(;;){wdt_reset();usbPoll(); // Poll USB port (Every ~10ms!)currKeys = getKey(); // Check the button pressesanalogPin = analogRead(0); // Read the pot (VolControl)setLeds(); // Set the leds// @TODO: Only do this on change}return 0;}inline void setLeds() {// Set the status leds.// @TODO: Verify that this doesn't mess with other port functionsPORTB &= 0xE0;PORTB |= (0x1F & (currLeds >> 3));PORTD &= 0x1F;PORTD |= (0xE0 & (currLeds << 5));// Set the power led stateif (pwrLed)sbi(PORTC, PC1);elsecbi(PORTC, PC1);}// Gnd = PD0, PD1// Btn = PC2, PC3, PC4, PC5uint8_t getKey() {uint8_t key = 0;cbi(PORTD, PD1); // Read the first row of buttons_delay_us(10); // Wait for the port changeif (rbi(PINC, PC2) == 0) key = 1;if (rbi(PINC, PC3) == 0) key = 2;if (rbi(PINC, PC4) == 0) key = 4;if (rbi(PINC, PC5) == 0) key = 8;sbi(PORTD, PD1);cbi(PORTD, PD0); // Read the second row of buttons_delay_us(10);if (rbi(PINC, PC2) == 0) key = 16;if (rbi(PINC, PC3) == 0) key = 32;if (rbi(PINC, PC4) == 0) key = 64;if (rbi(PINC, PC5) == 0) key = 128;sbi(PORTD, PD0);return key;}uint8_t analogRead(uint8_t channel) {ADMUX = (1<<ADLAR) | (1<<REFS0) | (0<<REFS1) | (channel & 0x0f);ADCSRA |= (1<<ADSC); // Start convertingwhile (((ADCSRA >> ADSC) & 1)) {} //Wait until conversion finisheduint8_t result = ADCH;//ADCSRA |= (0<<ADSC); // Stop convertingreturn result;}void analogInit() {ACSR |= (1<<ACD); // Disable analog comparator/*Setup ADCADMUX: 8 bit mode, Avcc refADCSRA: Enable, 128 prescale*/ADMUX = (1<<ADLAR) | (0<<REFS0) | (1<<REFS1);ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) ;}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;}}