123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /* Name: main.c
- * Project: hid-data, example how to use HID for data transfer
- * Author: Christian Starkjohann
- * Creation Date: 2008-04-11
- * Tabsize: 4
- * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
- * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $
- */
- /*
- This example should run on most AVRs with only little changes. No special
- hardware resources except INT0 are used. You may have to change usbconfig.h for
- different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
- at least be connected to INT0 as well.
- */
- #include <avr/io.h>
- #include <avr/wdt.h>
- #include <avr/interrupt.h> /* for sei() */
- #include <util/delay.h> /* for _delay_ms() */
- #include <avr/eeprom.h>
- #include <avr/pgmspace.h> /* required by usbdrv.h */
- #include "usbdrv.h"
- #include "oddebug.h" /* This is also an example for using debug macros */
- /* ------------------------------------------------------------------------- */
- /* ----------------------------- USB interface ----------------------------- */
- /* ------------------------------------------------------------------------- */
- PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
- 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x01, // USAGE (Vendor Usage 1)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x80, // REPORT_COUNT (128)
- 0x09, 0x00, // USAGE (Undefined)
- 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
- 0xc0 // END_COLLECTION
- };
- /* Since we define only one feature report, we don't use report-IDs (which
- * would be the first byte of the report). The entire report consists of 128
- * opaque data bytes.
- */
- /* The following variables store the status of the current data transfer */
- static uchar currentAddress;
- static uchar bytesRemaining;
- /* ------------------------------------------------------------------------- */
- /* usbFunctionRead() is called when the host requests a chunk of data from
- * the device. For more information see the documentation in usbdrv/usbdrv.h.
- */
- uchar usbFunctionRead(uchar *data, uchar len)
- {
- if(len > bytesRemaining)
- len = bytesRemaining;
- eeprom_read_block(data, (uchar *)0 + currentAddress, len);
- currentAddress += len;
- bytesRemaining -= len;
- return len;
- }
- /* usbFunctionWrite() is called when the host sends a chunk of data to the
- * device. For more information see the documentation in usbdrv/usbdrv.h.
- */
- uchar usbFunctionWrite(uchar *data, uchar len)
- {
- if(bytesRemaining == 0)
- return 1; /* end of transfer */
- if(len > bytesRemaining)
- len = bytesRemaining;
- eeprom_write_block(data, (uchar *)0 + currentAddress, len);
- currentAddress += len;
- bytesRemaining -= len;
- return bytesRemaining == 0; /* return 1 if this was the last chunk */
- }
- /* ------------------------------------------------------------------------- */
- usbMsgLen_t usbFunctionSetup(uchar data[8])
- {
- usbRequest_t *rq = (void *)data;
- if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */
- if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
- /* since we have only one report type, we can ignore the report-ID */
- bytesRemaining = 128;
- currentAddress = 0;
- return USB_NO_MSG; /* use usbFunctionRead() to obtain data */
- }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
- /* since we have only one report type, we can ignore the report-ID */
- bytesRemaining = 128;
- currentAddress = 0;
- return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */
- }
- }else{
- /* ignore vendor type requests, we don't use any */
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
- int main(void)
- {
- uchar i;
- wdt_enable(WDTO_1S);
- /* Even if you don't use the watchdog, turn it off here. On newer devices,
- * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
- */
- DBG1(0x00, 0, 0); /* debug output: main starts */
- /* RESET status: all port bits are inputs without pull-up.
- * That's the way we need D+ and D-. Therefore we don't need any
- * additional hardware initialization.
- */
- odDebugInit();
- usbInit();
- usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
- i = 0;
- while(--i){ /* fake USB disconnect for > 250 ms */
- wdt_reset();
- _delay_ms(1);
- }
- usbDeviceConnect();
- sei();
- DBG1(0x01, 0, 0); /* debug output: main loop starts */
- for(;;){ /* main event loop */
- DBG1(0x02, 0, 0); /* debug output: main loop iterates */
- wdt_reset();
- usbPoll();
- }
- return 0;
- }
- /* ------------------------------------------------------------------------- */
|