Rev 134 | Blame | Last modification | View Log | RSS feed
#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 "config.h"#include "avrutil.h"#include "usbdrv.h"#include "i2cbb.h"#ifndef NULL#define NULL ((void *)0)#endifstatic void calibrateOscillator(void);void usbEventResetReady(void);static void updateDisplays();#define DIS_COM_ACTIVE#define DIS_COM_STANDBY#define DIS_NAV_ACTIVE#define DIS_NAV_STANDBY// Hold the chars for the display panelsvolatile uint8_t displays[5][6] = {{ 0, 0, 0, 0, 0}, // DIS_COM_ACTIVE{ 0, 0, 0, 0, 0}, // DIS_COM_STANDBY{ 0, 0, 0, 0, 0}, // DIS_NAV_ACTIVE{ 0, 0, 0, 0, 0}, // DIS_NAV_STANDBY};//static uchar usbReplyBuf[16];volatile static uint8_t bytesRemaining;volatile static uint8_t* writeIdx;volatile uint8_t tmr0_ovf = 0;volatile uint8_t update = 1;int main(void) {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 pinPB0 -PB1 - - USB D- Low SpeedPB2 - - USB D+PB3 - - SCL i2c bbPB4 - - SDA i2c bbPB5 -*/DDRB = 0B00000001;PORTB = 0B00000001;usbDeviceDisconnect();_delay_ms(300);usbDeviceConnect();systime = 0;sysclockInit();wdt_enable(WDTO_1S); // Watchdog for 1 secusbInit();sei(); // Enable interrupts/*cbi(PORTB, PB0);i2cbb_Init();i2cbb_Start();i2cbb_Write(0x4c);i2cbb_Write(0x05);i2cbb_Write(0x08);i2cbb_Stop();sbi(PORTB, PB0);*/for(;;){wdt_reset();usbPoll();if (update) {updateDisplays();}}return 0;}static void updateDisplays() {cbi(PORTB, PB0);i2cbb_Init();i2cbb_Start();i2cbb_Write(0x4c);i2cbb_Write(0x05);i2cbb_Write(0x00 | displays[0][0]);i2cbb_Write(0x10 | displays[0][1]);i2cbb_Write(0x20 | displays[0][2]);i2cbb_Write(0x30 | displays[0][3]);i2cbb_Write(0x40 | displays[0][4]);i2cbb_Stop();sbi(PORTB, PB0);cbi(PORTB, PB0);i2cbb_Init();i2cbb_Start();i2cbb_Write(0x4c);i2cbb_Write(0x05);i2cbb_Write(0x50 | displays[1][0]);i2cbb_Write(0x60 | displays[1][1]);i2cbb_Write(0x70 | displays[1][2]);i2cbb_Write(0x80 | displays[1][3]);i2cbb_Write(0x90 | displays[1][4]);i2cbb_Stop();sbi(PORTB, PB0);update = 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;}#define USB_GET_CONT_VER 10 // Send the controller version data#define USB_GET_COMM_VER 11 // Send the comm display version data#define USB_GET_NAV_VER 12 // Send the nav display version data#define USB_SET_COMM_ACTIVE 20 // Set the comm active freq#define USB_SET_COMM_STANDBY 21 // Set the comm standby freq#define USB_SET_NAV_ACTIVE 22 // Set the nav active freq#define USB_SET_NAV_STANDBY 23 // Set the nav standby freq#define USB_BLANK_ALL 24 // Blank all displays#define USB_SET_ALL 25 // Blank all displays#define USB_GET_COMM_ENC 30 // Send the comm rotary encoder position#define USB_RESET_COMM_ENC 31 // Reset the comm encoder to 0#define USB_GET_NAV_ENC 32 // Send the nav rotary encoder position#define USB_RESET_NAV_ENC 33 // Reset the nav encoder to 0#define USB_GET_BUTTONS 32 // Send the status of all the buttonsusbMsgLen_t usbFunctionSetup(uchar data[8]){usbRequest_t *rq = (void *)data;switch (rq->bRequest ) {case 20: {uint8_t dis = rq->wValue.bytes[0];uint8_t dig = rq->wValue.bytes[1];uint8_t val = rq->wIndex.bytes[0];displays[dis][dig] = val;update = 1;break;}}return 0;}/*uchar usbFunctionWrite(uchar *data, uchar len) {uint8_t i;if (len > bytesRemaining)len = bytesRemaining;bytesRemaining -= len;for (i=0; i<len; i++) {*writeIdx++ = data[i];}displays[0][3] = 2;displays[0][4] = 2;update = 1;return (bytesRemaining == 0);}*/void usbEventResetReady(void) {cli();calibrateOscillator();sei();eeprom_write_byte(0, OSCCAL); /* store the calibrated value in EEPROM */}ISR(TIM0_OVF_vect) {tmr0_ovf++;// Clk/1 TCCR0B = (1<< CS00);//20.0Mhz, 1ms = 78ovf//16.5Mhz, 1ms = 64ovf//16.0Mhz, 1ms = 62ovf//12.0Mhz, 1ms = 46ovf// 8.0Mhz, 1ms = 31ovf// 8.0Mhz, .5ms = 15ovf, 160rif (tmr0_ovf>=64) {systime++;tmr0_ovf = 0;}}