📄 main.c
字号:
/* Name: main.c * Project: Thermostat based on AVR USB driver * 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: main.c 362 2007-06-25 14:38:21Z cs $ */#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"/*Pin assignment:PB0, PB2 = USB data lines*/#define BIT_LED 4#define BIT_KEY 1#define UTIL_BIN4(x) (uchar)((0##x & 01000)/64 + (0##x & 0100)/16 + (0##x & 010)/4 + (0##x & 1))#define UTIL_BIN8(hi, lo) (uchar)(UTIL_BIN4(hi) * 16 + UTIL_BIN4(lo))#ifndef NULL#define NULL ((void *)0)#endif/* ------------------------------------------------------------------------- */static uchar reportBuffer[1]; /* buffer for HID reports */static uchar idleRate; /* in 4 ms units */static uchar FlagKey;/* ------------------------------------------------------------------------- */PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x09, 0x04, // USAGE (Joystick) 0xa1, 0x01, // COLLECTION (Application) 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 (8) 0x55, 0x00, // UNIT_EXPONENT (0) 0x65, 0x00, // UNIT (None) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0 // END_COLLECTION};/* ------------------------------------------------------------------------- */static void timerPoll(void){static uchar timerCnt;static uchar i; if(TIFR & (1 << TOV1)){ TIFR = (1 << TOV1); /* clear overflow */ if(++timerCnt >= 63){ /* ~ 1 second interval */ timerCnt = 0; if (!FlagKey) { FlagKey = 1; if (++i > 3) i=0; switch (i) { case 0: reportBuffer[0] = 1; /* no modifiers */ break; case 1: reportBuffer[0] = 2; /* no modifiers */ break; case 2: reportBuffer[0] = 8; /* no modifiers */ break; case 3: reportBuffer[0] = 64; /* no modifiers */ break; } } } }}/* ------------------------------------------------------------------------- */static void timerInit(void){ TCCR1 = 0x0b; /* select clock: 16.5M/1k -> overflow rate = 16.5M/256k = 62.94 Hz */}/* ------------------------------------------------------------------------- *//* ------------------------ interface to USB driver ------------------------ *//* ------------------------------------------------------------------------- */uchar usbFunctionSetup(uchar data[8]){usbRequest_t *rq = (void *)data; usbMsgPtr = reportBuffer; if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */ /* we only have one report type, so don't look at wValue */ reportBuffer[0] = 0; /* no modifiers */ 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{ /* no vendor specific requests implemented */ } return 0;}/* ------------------------------------------------------------------------- *//* --------------------------------- main ---------------------------------- *//* ------------------------------------------------------------------------- */int main(void){uchar i;/* Calibrate the RC oscillator to 8.25 MHz. The core clock of 16.5 MHz is * derived from the 66 MHz peripheral clock by dividing. We assume that the * EEPROM contains a calibration value in location 0. If no calibration value * has been stored during programming, we offset Atmel's 8 MHz calibration * value according to the clock vs OSCCAL diagram in the data sheet. This * seems to be sufficiently precise (<= 1%). */ uchar calibrationValue = eeprom_read_byte(0); if(calibrationValue != 0xff){ OSCCAL = calibrationValue; /* a calibration value is supplied */ }else{ /* we have no calibration value, assume 8 MHz calibration and adjust from there */ if(OSCCAL < 125){ OSCCAL += 3; /* should be 3.5 */ }else if(OSCCAL >= 128){ OSCCAL += 7; /* should be 7 */ }else{ /* must be between 125 and 128 */ OSCCAL = 127; /* maximum possible avoiding discontinuity */ } } odDebugInit(); DDRB = (1 << USB_CFG_DMINUS_BIT) | (1 << USB_CFG_DPLUS_BIT); PORTB = 0; /* indicate USB disconnect to host */ for(i=0;i<20;i++){ /* 300 ms disconnect, also allows our oscillator to stabilize */ _delay_ms(15); } DDRB = 1 << BIT_LED; /* output for LED */ PORTB = 1 << BIT_KEY; /* pull-up on key input */ wdt_enable(WDTO_1S); timerInit(); usbInit(); sei(); for(;;){ /* main event loop */ wdt_reset(); usbPoll(); if(usbInterruptIsReady() ){ /* we can send another key */ usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); FlagKey = 0; } timerPoll(); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -