From db7c8614462889f3d25b911c44757161f28169f0 Mon Sep 17 00:00:00 2001 From: claudiol Date: Wed, 8 Nov 2017 19:05:06 -0500 Subject: [PATCH] More progress on USB driver --- firmware/sys/target_50g/usbdriver.c | 840 ++++++++++++++++++++++++ firmware/sys/usb/usb_rawhid.c | 954 ---------------------------- firmware/sys/usb/usb_rawhid.h | 54 +- newrpl-fw.pro | 2 +- 4 files changed, 843 insertions(+), 1007 deletions(-) create mode 100644 firmware/sys/target_50g/usbdriver.c delete mode 100644 firmware/sys/usb/usb_rawhid.c diff --git a/firmware/sys/target_50g/usbdriver.c b/firmware/sys/target_50g/usbdriver.c new file mode 100644 index 0000000..fbed86c --- /dev/null +++ b/firmware/sys/target_50g/usbdriver.c @@ -0,0 +1,840 @@ +/* +* Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team +* All rights reserved. +* This file is released under the 3-clause BSD license. +* See the file LICENSE.txt that shipped with this distribution. +*/ + +#include +#include + +// HARDWARE PORTS FOR S3C2410 - USB DEVICE + + +#define CLKCON HWREG(CLK_REGS,0xc) + +#define FUNC_ADDR_REG HWREG(USBD_REGS,0x140) +#define PWR_REG HWREG(USBD_REGS,0x144) +#define EP_INT_REG HWREG(USBD_REGS,0x148) +#define USB_INT_REG HWREG(USBD_REGS,0x158) +#define EP_INT_EN_REG HWREG(USBD_REGS,0x15c) +#define USB_INT_EN_REG HWREG(USBD_REGS,0x16c) +#define INDEX_REG HWREG(USBD_REGS,0x178) +#define EP0_FIFO HWREG(USBD_REGS,0x1c0) +#define EP1_FIFO HWREG(USBD_REGS,0x1c4) +#define EP2_FIFO HWREG(USBD_REGS,0x1c8) +#define EP3_FIFO HWREG(USBD_REGS,0x1cc) +#define EP4_FIFO HWREG(USBD_REGS,0x1d0) + +// INDEXED REGISTERS +#define EP0_CSR HWREG(USBD_REGS,0x184) +#define IN_CSR1_REG HWREG(USBD_REGS,0x184) +#define IN_CSR2_REG HWREG(USBD_REGS,0x188) +#define MAXP_REG HWREG(USBD_REGS,0x18c) +#define OUT_CSR1_REG HWREG(USBD_REGS,0x190) +#define OUT_CSR2_REG HWREG(USBD_REGS,0x194) +#define OUT_FIFO_CNT1_REG HWREG(USBD_REGS,0x198) +#define OUT_FIFO_CNT2_REG HWREG(USBD_REGS,0x19c) + + + +// MISCELLANEOUS REGISTERS +#define MISCCR HWREG(IO_REGS,0x80) +#define UPLLCON HWREG(CLK_REGS,0x8) +#define CLKCON HWREG(CLK_REGS,0xc) +#define CLKSLOW HWREG(CLK_REGS,0x10) + + + +// VARIOUS STATES AND PIN CONSTANTS +#define USBSUSPND1 (1<<13) +#define USBSUSPND0 (1<<13) +#define USBPAD (1<<3) + + +// CONTROL ENDPOINT CSR +#define EP0_OUT_PKT_RDY 1 +#define EP0_IN_PKT_RDY 2 +#define EP0_SENT_STALL 4 +#define EP0_DATA_END 8 +#define EP0_SETUP_END 16 +#define EP0_SEND_STALL 32 +#define EP0_SERVICED_OUT_PKT_RDY 64 +#define EP0_SERVICED_SETUP_END 128 + +// OTHER ENDPOINTS CSR +#define EPn_IN_SEND_STALL 0x10 +#define EPn_OUT_SEND_STALL 0x20 + +#define EP0_FIFO_SIZE 8 + +//******************************************************************** +// THE DESCRIPTOR DATA BELOW WAS COPIED AND PORTED FROM THE Teensy rawHID +// EXAMPLE IN AGREEMENT WITH THE LICENSE BELOW: + +/* Teensy RawHID example + * http://www.pjrc.com/teensy/rawhid.html + * Copyright (c) 2009 PJRC.COM, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above description, website URL and copyright notice and this permission + * notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +/************************************************************************** + * + * Configurable Options + * + **************************************************************************/ + +// You can change these to give your code its own name. +#define STR_MANUFACTURER L"newRPL Team" +#define STR_PRODUCT L"Calculator with newRPL" + +// These 4 numbers identify your device. Set these to +// something that is (hopefully) not used by any others! +#define VENDOR_ID 0x3f0 +#define PRODUCT_ID 0x121 // ORIGINAL VID/PID OF THE 50g/39gs/40g TARGET HARDWARE +//#define PRODUCT_ID 0x441 // ORIGINAL VID/PID OF THE Prime TARGET HARDWARE +#define RAWHID_USAGE_PAGE 0xFFAB // recommended: 0xFF00 to 0xFFFF +#define RAWHID_USAGE 0x0200 // recommended: 0x0100 to 0xFFFF + +// These determine the bandwidth that will be allocated +// for your communication. You do not need to use it +// all, but allocating more than necessary means reserved +// bandwidth is no longer available to other USB devices. +#define RAWHID_TX_SIZE 64 // transmit packet size +#define RAWHID_TX_INTERVAL 2 // max # of ms between transmit packets +#define RAWHID_RX_SIZE 64 // receive packet size +#define RAWHID_RX_INTERVAL 8 // max # of ms between receive packets + + +/************************************************************************** + * + * Endpoint Buffer Configuration + * + **************************************************************************/ + +#define ENDPOINT0_SIZE 8 +#define RAWHID_INTERFACE 0 +#define RAWHID_TX_ENDPOINT 1 +#define RAWHID_RX_ENDPOINT 2 + +/************************************************************************** + * + * Descriptor Data + * + **************************************************************************/ + +// standard control endpoint request types +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 +// HID (human interface device) +#define HID_GET_REPORT 1 +#define HID_GET_IDLE 2 +#define HID_GET_PROTOCOL 3 +#define HID_SET_REPORT 9 +#define HID_SET_IDLE 10 +#define HID_SET_PROTOCOL 11 + +// other control definitions +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +#define EP_SINGLE_BUFFER 0x02 +#define EP_DOUBLE_BUFFER 0x06 + +#define EP_SIZE(s) ((s) > 32 ? 0x30 : \ + ((s) > 16 ? 0x20 : \ + ((s) > 8 ? 0x10 : \ + 0x00))) + +#define MAX_ENDPOINT 4 + +#define LSB(n) (n & 255) +#define MSB(n) ((n >> 8) & 255) + + +// Descriptors are the data that your computer reads when it auto-detects +// this USB device (called "enumeration" in USB lingo). The most commonly +// changed items are editable at the top of this file. Changing things +// in here should only be done by those who've read chapter 9 of the USB +// spec and relevant portions of any USB class specifications! + + +const BYTE const device_descriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x00, 0x02, // bcdUSB + 0, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + ENDPOINT0_SIZE, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 0, // iSerialNumber + 1 // bNumConfigurations +}; + +const BYTE const rawhid_hid_report_desc[] = { + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + 0xA1, 0x01, // Collection 0x01 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, RAWHID_TX_SIZE, // report count + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + 0x95, RAWHID_RX_SIZE, // report count + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +}; + + +#define CONFIG1_DESC_SIZE (9+9+9+7+7) +#define RAWHID_HID_DESC_OFFSET (9+9) +const BYTE const config1_descriptor[CONFIG1_DESC_SIZE] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG1_DESC_SIZE), // wTotalLength + MSB(CONFIG1_DESC_SIZE), + 1, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xC0, // bmAttributes + 50, // bMaxPower + + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + RAWHID_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass (0x01 = Boot) + 0x00, // bInterfaceProtocol (0x01 = Keyboard) + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(rawhid_hid_report_desc), // wDescriptorLength + 0, + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + RAWHID_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + RAWHID_TX_SIZE, 0, // wMaxPacketSize + RAWHID_TX_INTERVAL, // bInterval + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + RAWHID_RX_ENDPOINT, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + RAWHID_RX_SIZE, 0, // wMaxPacketSize + RAWHID_RX_INTERVAL // bInterval +}; + +// If you're desperate for a little extra code memory, these strings +// can be completely removed if iManufacturer, iProduct, iSerialNumber +// in the device desciptor are changed to zeros. + +typedef const uint16_t wchar_t; + +struct usb_string_descriptor_struct { + BYTE bLength; + BYTE bDescriptorType; + wchar_t const wString[]; +}; +const struct usb_string_descriptor_struct const _usb_string0 = { + 4, + 3, + {0x0409} +}; +const struct usb_string_descriptor_struct const _usb_string1 = { + sizeof(STR_MANUFACTURER), + 3, + STR_MANUFACTURER +}; +const struct usb_string_descriptor_struct const _usb_string2 = { + sizeof(STR_PRODUCT), + 3, + STR_PRODUCT +}; + +// This table defines which descriptor data is sent for each specific +// request from the host (in wValue and wIndex). +const struct descriptor_list_struct { + HALFWORD wValue; + HALFWORD wIndex; + const BYTE *addr; + BYTE length; +} const descriptor_list[] = { + {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, + {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, + {0x2200, RAWHID_INTERFACE, rawhid_hid_report_desc, sizeof(rawhid_hid_report_desc)}, + {0x2100, RAWHID_INTERFACE, config1_descriptor+RAWHID_HID_DESC_OFFSET, 9}, + {0x0300, 0x0000, (const BYTEPTR )&_usb_string0, 4}, + {0x0301, 0x0409, (const BYTEPTR )&_usb_string1, sizeof(STR_MANUFACTURER)}, + {0x0302, 0x0409, (const BYTEPTR )&_usb_string2, sizeof(STR_PRODUCT)} +}; + +#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct)) + + + + +//******************************************************************** +// END OF DEFINITIONS BORROWED FROM Teensy rawHID project. +// EVERYTHING BELOW WAS WRITTEN FROM SCRATCH BY THE newRPL Team + +// INITIALIZE USB SUBSYSTEM, POWER, PINS +#define USB_STATUS_INIT 1 +#define USB_STATUS_EP0TX 2 +#define USB_STATUS_EP0RX 4 +#define USB_STATUS_EP1TX 8 +#define USB_STATUS_EP1RX 16 +#define USB_STATUS_EP2TX 32 +#define USB_STATUS_EP2RX 64 +#define USB_STATUS_CONNECTED 128 +#define USB_STATUS_CONFIGURED 256 +#define USB_STATUS_SUSPEND 512 +#define USB_STATUS_WAKEUPENABLED 1024 +#define USB_STATUS_TESTMODE 2048 + + +// GLOBAL VARIABLES OF THE USB SUBSYSTEM +BINT __usb_drvstatus __SYSTEM_GLOBAL__; // FLAGS TO INDICATE IF INITIALIZED, CONNECTED, SENDING/RECEIVING, ETC. +BYTE *__usb_bufptr[3]; __SYSTEM_GLOBAL__; // POINTERS TO BUFFERS FOR EACH ENDPOINT (0/1/2) +BINT __usb_count[3]; __SYSTEM_GLOBAL__; // REMAINING BYTES TO TRANSFER ON EACH ENDPOINT (0/1/2) +BYTE __usb_tmpbuffer[RAWHID_TX_SIZE] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER FOR NON-BLOCKING CONTROL TRANSFERS + + +void usb_hwsetup() +{ + *CLKCON&=~0xc0; // POWER DOWN BOTH USB DEVICE AND HOST TO MAKE SURE HOST AND DEVICE AREN'T WORKING AT ONCE + *CLKCON|=0x80; // POWER UP USB DEVICE + + *UPLLCON=0x78023; // 48 MHZ CLOCK + *CLKSLOW&=~0x80; // MAKE SURE UPLL IS ON + + *MISCCR&=~(USBSUSPND0|USBSUSPND1|USBPAD); // SET DEVICE MODE, CHANGE TO NORMAL MODE + + *PWR_REG=1; // ALLOW THE DEVICE TO ENTER SUSPEND MODE + + // SET WHICH INTERRUPTS WE WANT + *USB_INT_EN_REG=0x7; // ENABLE RESET, RESUME AND SUSPEND INTERRUPTS + *EP_INT_EN_REG=0x7; // ENABLE ONLY EP0, EP1 AND EP2 INTERRUPTS + *USB_INT_REG=0x7; // CLEAR ALL PENDING INTERRUPTS + *EP_INT_REG=0x1f; // CLEAR ALL PENDING INTERRUPTS + + *INDEX_REG=0; // SETUP ENDPOINT0 + *MAXP_REG=1; // USE 8-BYTE PACKETS + + *INDEX_REG=1; + *MAXP_REG=8; // USE 64-BYTE PACKETS ON EP1 + *INDEX_REG=2; + *MAXP_REG=8; // USE 64-BYTE PACKETS ON EP2 + +} + +void usb_hwsuspend() +{ + + *MISCCR|=(USBSUSPND0|USBSUSPND1); // CHANGE TO SUSPEND MODE + + *CLKSLOW|=~0x80; // TURN OFF UPLL + + +} + +void usb_hwresume() +{ + *UPLLCON=0x78023; // 48 MHZ CLOCK + *CLKSLOW&=~0x80; // MAKE SURE UPLL IS ON + + *MISCCR&=~(USBSUSPND0|USBSUSPND1); // CHANGE TO NORMAL MODE + +} + +void usb_init() +{ + + if(__usb_drvstatus&USB_STATUS_INIT) return; + + __usb_drvstatus=USB_STATUS_INIT; + + usb_hwsetup(); + + // SET INTERRUPT HANDLER + __irq_mask(25); + + __irq_addhook(25,&usb_irqservice); + + __irq_unmask(25); + + // TODO: SETUP COMMUNICATIONS BUFFERS + +} + +void usb_shutdown() +{ + + if(!__usb_drvstatus&USB_STATUS_INIT) return; + // MASK INTERRUPT AND REMOVE HANDLER + __irq_mask(25); + __irq_releasehook(25); + + // CLEANUP INTERRUPT SYSTEM + *USB_INT_EN_REG=0x0; // DISABLE INTERRUPTS + *EP_INT_EN_REG=0x0; // DISABLE INTERRUPTS + *USB_INT_REG=0x7; // CLEAR ALL PENDING INTERRUPTS + *EP_INT_REG=0x1f; // CLEAR ALL PENDING INTERRUPTS + + // STOP THE CLOCK + *CLKSLOW|=0x80; // SHUT DOWN UPLL + + *CLKCON&=~0xc0; // POWER DOWN BOTH USB DEVICE AND HOST + + __usb_drvstatus=0; // MARK UNCONFIGURED + + // TODO: RELEASE COMMUNICATIONS BUFFERS + +} + + +// TRANSMIT BYTES TO THE HOST IN EP0 ENDPOINT +// STARTS A NEW TRANSMISSION IF newtransmission IS TRUE, EVEN IF +// THERE ARE ZERO BYTES IN THE BUFFER +// FOR USE WITHIN ISR + +void usb_ep0_transmit(int newtransmission) +{ + + if(!__usb_drvstatus&USB_STATUS_CONNECTED) return; + + if(newtransmission || (__usb_drvstatus&USB_STATUS_EP0TX)) { + + *INDEX_REG=0; + + if(*EP0_CSR&EP0_IN_PKT_RDY) { + // PREVIOUS PACKET IS STILL BEING SENT, DON'T PUSH IT + __usb_drvstatus|=USB_STATUS_EP0TX; // AND KEEP TRANSMITTING + return; + } + + int cnt=0; + while(__usb_count[0] && (cnt= 64) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 63) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 62) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 61) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 60) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 59) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 58) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 57) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 56) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 55) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 54) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 53) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 52) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 51) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 50) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 49) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 48) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 47) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 46) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 45) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 44) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 43) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 42) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 41) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 40) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 39) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 38) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 37) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 36) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 35) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 34) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 33) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 32) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 31) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 30) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 29) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 28) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 27) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 26) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 25) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 24) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 23) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 22) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 21) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 20) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 19) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 18) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 17) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 16) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 15) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 14) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 13) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 12) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 11) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 10) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 9) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 8) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 7) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 6) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 5) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 4) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 3) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 2) - *buffer++ = UEDATX; - #endif - #if (RAWHID_RX_SIZE >= 1) - *buffer++ = UEDATX; - #endif - // release the buffer - UEINTX = 0x6B; - SREG = intr_state; - return RAWHID_RX_SIZE; -} - -// send a packet, with timeout -int8_t usb_rawhid_send(const BYTEPTR buffer, BYTE timeout) -{ - BYTE intr_state; - - // if we're not online (enumerated and configured), error - if (!usb_configuration) return -1; - intr_state = SREG; - cli(); - tx_timeout_count = timeout; - UENUM = RAWHID_TX_ENDPOINT; - // wait for the FIFO to be ready to accept data - while (1) { - if (UEINTX & (1<= 64) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 63) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 62) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 61) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 60) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 59) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 58) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 57) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 56) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 55) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 54) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 53) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 52) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 51) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 50) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 49) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 48) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 47) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 46) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 45) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 44) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 43) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 42) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 41) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 40) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 39) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 38) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 37) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 36) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 35) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 34) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 33) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 32) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 31) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 30) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 29) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 28) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 27) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 26) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 25) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 24) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 23) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 22) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 21) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 20) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 19) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 18) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 17) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 16) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 15) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 14) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 13) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 12) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 11) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 10) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 9) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 8) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 7) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 6) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 5) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 4) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 3) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 2) - UEDATX = *buffer++; - #endif - #if (RAWHID_TX_SIZE >= 1) - UEDATX = *buffer++; - #endif - // transmit it now - UEINTX = 0x3A; - SREG = intr_state; - return RAWHID_TX_SIZE; -} - - - - -/************************************************************************** - * - * Private Functions - not intended for general user consumption.... - * - **************************************************************************/ - - -#if (GCC_VERSION >= 40300) && (GCC_VERSION < 40302) -#error "Buggy GCC 4.3.0 compiler, please upgrade!" -#endif - - -// USB Device Interrupt - handle all device-level events -// the transmit buffer flushing is triggered by the start of frame -// -ISR(USB_GEN_vect) -{ - BYTE intbits, t; - - intbits = UDINT; - UDINT = 0; - if (intbits & (1<= NUM_DESC_LIST) { - UECONX = (1< desc_length) len = desc_length; - do { - // wait for host ready for IN packet - do { - i = UEINTX; - } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { - usb_send_in(); - UENUM = i; - if (bRequest == SET_FEATURE) { - UECONX = (1< -#include -#include - -#define EP_TYPE_CONTROL 0x00 -#define EP_TYPE_BULK_IN 0x81 -#define EP_TYPE_BULK_OUT 0x80 -#define EP_TYPE_INTERRUPT_IN 0xC1 -#define EP_TYPE_INTERRUPT_OUT 0xC0 -#define EP_TYPE_ISOCHRONOUS_IN 0x41 -#define EP_TYPE_ISOCHRONOUS_OUT 0x40 - -#define EP_SINGLE_BUFFER 0x02 -#define EP_DOUBLE_BUFFER 0x06 - -#define EP_SIZE(s) ((s) > 32 ? 0x30 : \ - ((s) > 16 ? 0x20 : \ - ((s) > 8 ? 0x10 : \ - 0x00))) - -#define MAX_ENDPOINT 4 - -#define LSB(n) (n & 255) -#define MSB(n) ((n >> 8) & 255) - -#if defined(__AVR_AT90USB162__) -#define HW_CONFIG() -#define PLL_CONFIG() (PLLCSR = ((1<