Source file: /~heha/Mikrocontroller/LEDs/u-wire.zip/usbdrv/usbdrv.c

/* Name: usbdrv.c
 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
 * Author: Christian Starkjohann
 * Creation Date: 2004-12-29
 * Tabsize: 4
 * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
 */

#include "usbdrv.h"

/*
General Description:
This module implements the C-part of the USB driver. See usbdrv.h for a
documentation of the entire driver.
*/

/* ------------------------------------------------------------------------- */

/* raw USB registers / interface to assembler code: */
//uchar usbRxBuf[2*USB_BUFSIZE];  /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */
uchar	usbRxBuf[USB_BUFSIZE];  /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */ //<- only use half the rx buf
uchar	usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen contains handshake token */
//uchar	usbInputBufOffset;  /* offset in usbRxBuf used for low level receiving */
uchar	usbDeviceAddr;      /* assigned during enumeration, defaults to 0 */
uchar	usbNewDeviceAddr;   /* device ID which should be set after status phase */
//uchar	usbConfiguration;   /* currently selected configuration. Administered by driver, but not used */
volatile schar usbRxLen;        /* = 0; number of bytes in usbRxBuf; 0 means free, -1 for flow control */
uchar	usbCurrentTok;      /* last token received or endpoint number for last OUT token if != 0 */
uchar	usbRxToken;         /* token for data we received; or endpont number for last OUT */
volatile uchar usbTxLen;   /* number of bytes to transmit with next IN token or handshake token */

#define USB_FLG_MSGPTR_IS_ROM   (1<<6)
#define USB_FLG_USE_USER_RW     (1<<7)

/*
optimizing hints:
- do not post/pre inc/dec integer values in operations
- assign value of USB_READ_FLASH() to register variables and don't use side effects in arg
- use narrow scope for variables which should be in X/Y/Z register
- assign char sized expressions to variables to force 8 bit arithmetics
*/

#define W(x) (x)&0xFF,(x)>>8
/* -------------------------- String Descriptors --------------------------- */
#if USB_CFG_DESCR_PROPS_STRINGS == 0

#if 0   // No DecriptorSting0
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
#undef USB_CFG_DESCR_PROPS_STRING_0
#define USB_CFG_DESCR_PROPS_STRING_0    sizeof(usbDescriptorString0)
PROGMEM const char usbDescriptorString0[] = { /* language descriptor */
 4,		/* sizeof(usbDescriptorString0): length of descriptor in bytes */
 3,		/* descriptor type */
 W(0x0409),	/* language index (0x0409 = US-English) */
};
#endif
#endif

#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
#define USB_CFG_DESCR_PROPS_STRING_VENDOR   sizeof(usbDescriptorStringVendor)
PROGMEM const int  usbDescriptorStringVendor[] = {
 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
 USB_CFG_VENDOR_NAME
};
#endif

#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT   sizeof(usbDescriptorStringDevice)
PROGMEM const int  usbDescriptorStringDevice[] = {
 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
 USB_CFG_DEVICE_NAME
};
#endif

#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    sizeof(usbDescriptorStringSerialNumber)
PROGMEM const int usbDescriptorStringSerialNumber[] = {
 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
 USB_CFG_SERIAL_NUMBER
};
#endif

#endif  /* USB_CFG_DESCR_PROPS_STRINGS == 0 */

/* --------------------------- Device Descriptor --------------------------- */

#if USB_CFG_DESCR_PROPS_DEVICE == 0
#undef USB_CFG_DESCR_PROPS_DEVICE
#define USB_CFG_DESCR_PROPS_DEVICE  sizeof(usbDescriptorDevice)
PROGMEM const char usbDescriptorDevice[] = {    /* USB device descriptor */
 18,         /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
 USBDESCR_DEVICE,	/* descriptor type */
 W(0x0110),		/* USB version supported */
 USB_CFG_DEVICE_CLASS,
 USB_CFG_DEVICE_SUBCLASS,
 0,                      /* protocol */
 8,                      /* max packet size */
    /* the following two casts affect the first byte of the constant only, but
     * that's sufficient to avoid a warning with the default values.
     */
 W(USB_CFG_VENDOR_ID),/* 2 bytes */
 W(USB_CFG_DEVICE_ID),/* 2 bytes */
 W(USB_CFG_DEVICE_VERSION), /* 2 bytes */
 USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0,         /* manufacturer string index */
 USB_CFG_DESCR_PROPS_STRING_PRODUCT != 0 ? 2 : 0,        /* product string index */
 USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0,  /* serial number string index */
 1,          /* number of configurations */
};
#endif

/* ----------------------- Configuration Descriptor ------------------------ */

#if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0
#undef USB_CFG_DESCR_PROPS_HID
#define USB_CFG_DESCR_PROPS_HID     9   /* length of HID descriptor in config descriptor below */
#endif

#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
#undef USB_CFG_DESCR_PROPS_CONFIGURATION
#define USB_CFG_DESCR_PROPS_CONFIGURATION   sizeof(usbDescriptorConfiguration)
PROGMEM const char usbDescriptorConfiguration[] = {    /* USB configuration descriptor */
 9,          /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
 USBDESCR_CONFIG,    /* descriptor type */
 W(18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
                (USB_CFG_DESCR_PROPS_HID & 0xff)),
                /* total length of data returned (including inlined descriptors) */
 1,          /* number of interfaces in this configuration */
 1,          /* index of this configuration */
 0,          /* configuration name string index */
#if USB_CFG_IS_SELF_POWERED
 (1 << 7) | USBATTR_SELFPOWER,       /* attributes */
#else
 (1 << 7),                           /* attributes */
#endif
 USB_CFG_MAX_BUS_POWER/2,            /* max USB current in 2mA units */
/* interface descriptor follows inline: */
 9,		/* sizeof(usbDescrInterface): length of descriptor in bytes */
 USBDESCR_INTERFACE, /* descriptor type */
 0,		/* index of this interface */
 0,		/* alternate setting for this interface */
 USB_CFG_HAVE_INTRIN_ENDPOINT + USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */
 USB_CFG_INTERFACE_CLASS,
 USB_CFG_INTERFACE_SUBCLASS,
 USB_CFG_INTERFACE_PROTOCOL,
 0,          /* string index for interface */
#if (USB_CFG_DESCR_PROPS_HID & 0xff)    /* HID descriptor */
 9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
 USBDESCR_HID,   /* descriptor type: HID */
 W(0x0101),	/* BCD representation of HID version */
 0x00,		/* target country code */
 0x01,		/* number of HID Report (or other HID class) Descriptor infos to follow */
 0x22,		/* descriptor type: report */
 USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,  /* total length of report descriptor */
#endif
#if USB_CFG_HAVE_INTRIN_ENDPOINT    /* endpoint descriptor for endpoint 1 */
 7,		/* sizeof(usbDescrEndpoint) */
 USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
 (char)0x81,	/* IN endpoint number 1 */
 0x03,		/* attrib: Interrupt endpoint */
 W(8),		/* maximum packet size */
 USB_CFG_INTR_POLL_INTERVAL, /* in ms */
#endif
#if USB_CFG_HAVE_INTRIN_ENDPOINT3   /* endpoint descriptor for endpoint 3 */
 7,          /* sizeof(usbDescrEndpoint) */
 USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
 (char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
 0x03,		/* attrib: Interrupt endpoint */
 W(8),		/* maximum packet size */
 USB_CFG_INTR_POLL_INTERVAL, /* in ms */
#endif
};
#endif
/* ------------------------------------------------------------------------- */


/* ------------------ utilities for code following below ------------------- */

/* Use defines for the switch statement so that we can choose between an
 * if()else if() and a switch/case based implementation. switch() is more
 * efficient for a LARGE set of sequential choices, if() is better in all other
 * cases.
 */
#if USB_CFG_USE_SWITCH_STATEMENT
#   define SWITCH_START(cmd)       switch(cmd){{
#   define SWITCH_CASE(value)      }break; case (value):{
#   define SWITCH_CASE2(v1,v2)     }break; case (v1): case(v2):{
#   define SWITCH_CASE3(v1,v2,v3)  }break; case (v1): case(v2): case(v3):{
#   define SWITCH_DEFAULT          }break; default:{
#   define SWITCH_END              }}
#else
#   define SWITCH_START(cmd)       {uchar _cmd = cmd; if(0){
#   define SWITCH_CASE(value)      }else if(_cmd == (value)){
#   define SWITCH_CASE2(v1,v2)     }else if(_cmd == (v1) || _cmd == (v2)){
#   define SWITCH_CASE3(v1,v2,v3)  }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){
#   define SWITCH_DEFAULT          }else{
#   define SWITCH_END              }}
#endif

#ifndef USB_RX_USER_HOOK
#define USB_RX_USER_HOOK(data, len)
#endif
#ifndef USB_SET_ADDRESS_HOOK
#define USB_SET_ADDRESS_HOOK()
#endif
Detected encoding: ASCII (7 bit)2