- Main Page
- Data Structures
- Files

- File List
- Globals

# usb.c

Go to the documentation of this file.

    00001 //******************************************************************************
    00002 //THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
    00003 //REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
    00004 //INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
    00005 //FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
    00006 //COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
    00007 //TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
    00008 //POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
    00009 //INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
    00010 //YOUR USE OF THE PROGRAM.
    00011 //
    00012 //IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
    00013 //CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
    00014 //THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
    00015 //OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
    00016 //OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
    00017 //EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
    00018 //REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
    00019 //OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
    00020 //USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
    00021 //AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
    00022 //YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
    00023 //(U.S.$500).
    00024 //
    00025 //Unless otherwise stated, the Program written and copyrighted
    00026 //by Texas Instruments is distributed as "freeware".  You may,
    00027 //only under TI's copyright in the Program, use and modify the
    00028 //Program without any charge or restriction.  You may
    00029 //distribute to third parties, provided that you transfer a
    00030 //copy of this license to the third party and the third party
    00031 //agrees to these terms by its first use of the Program. You
    00032 //must reproduce the copyright notice and any other legend of
    00033 //ownership on each copy or partial copy, of the Program.
    00034 //
    00035 //You acknowledge and agree that the Program contains
    00036 //copyrighted material, trade secrets and other TI proprietary
    00037 //information and is protected by copyright laws,
    00038 //international copyright treaties, and trade secret laws, as
    00039 //well as other intellectual property laws.  To protect TI's
    00040 //rights in the Program, you agree not to decompile, reverse
    00041 //engineer, disassemble or otherwise translate any object code
    00042 //versions of the Program to a human-readable form.  You agree
    00043 //that in no event will you alter, remove or destroy any
    00044 //copyright notice included in the Program.  TI reserves all
    00045 //rights not specifically granted under this license. Except
    00046 //as specifically provided herein, nothing in this agreement
    00047 //shall be construed as conferring by implication, estoppel,
    00048 //or otherwise, upon you, any license or other right under any
    00049 //TI patents, copyrights or trade secrets.
    00050 //
    00051 //You may not use the Program in non-TI devices.
    00063 // (c)2009 by Texas Instruments Incorporated, All Rights Reserved.
    00064 /*----------------------------------------------------------------------------+
    00065 |                                                                             |
    00066 |                              Texas Instruments                              |
    00067 |                                                                             |
    00068 |                          MSP430 USB-Example (CDC/HID Driver)                |
    00069 |                                                                             |
    00070 +-----------------------------------------------------------------------------+
    00071 |  Source: usb.c, v1.19 2009/11/18                                            |
    00072 |  Author: RSTO                                                               |
    00073 |                                                                             |
    00074 |  WHO          WHEN         WHAT                                             |
    00075 |  ---          ----------   ------------------------------------------------ |
    00076 |  RSTO         2008/09/03   born                                             |
    00077 |  RSTO         2008/12/23   enhancements of CDC API                          |
    00078 |  RSTO         2009/01/12   enhancements for USB serial number               |
    00079 |  RSTO         2009/05/15   added USB_connectionState()                      |
    00080 |  RSTO         2009/07/17   added __data16 qualifier for USB buffers         |
    00081 |  RSTO         2009/08/04   workaround for PLL start up problem              |
    00082 |  RSTO         2009/10/21   updated USB_InitSerialStringDescriptor()         |
    00083 |  RSTO         2009/11/05   updated USB_connectionState()                    |
    00084 |  RSTO         2009/11/18   updated USB_connectionState()                    |
    00085 +----------------------------------------------------------------------------*/
    00086 /*----------------------------------------------------------------------------+
    00087 | Include files                                                               |
    00088 +----------------------------------------------------------------------------*/
    00089
    00090 #include "MSP430.h"
    00091 #include "..\Common\types.h"              // Basic Type declarations
    00092 #include "..\USB_Common\defMSP430USB.h"
    00093 #include "..\USB_Common\descriptors.h"
    00094 #include "..\USB_Common\usb.h"            // USB-specific Data Structures
    00095 #include "..\USB_CDC_API\UsbCdc.h"
    00096 #include "..\Common\hal_UCS.h"
    00097 #include "..\Common\TLV_descriptors.h"
    00098
    00099 /*----------------------------------------------------------------------------+
    00100 | Internal Constant Definition                                                |
    00101 +----------------------------------------------------------------------------*/
    00102 #define NO_MORE_DATA 0xFFFF
    00103
    00104 /*----------------------------------------------------------------------------+
    00105 | Internal Variables                                                          |
    00106 +----------------------------------------------------------------------------*/
    00107
    00108 static BYTE bConfigurationNumber;      // Set to 1 when USB device has been
    00109                                 // configured, set to 0 when unconfigured
    00110
    00111 static BYTE bInterfaceNumber;   // interface number
    00112
    00113 WORD wBytesRemainingOnIEP0;     // For endpoint zero transmitter only
    00114                                 // Holds count of bytes remaining to be
    00115                                 // transmitted by endpoint 0.  A value
    00116                                 // of 0 means that a 0-length data packet
    00117                                 // A value of 0xFFFF means that transfer
    00118                                 // is complete.
    00119
    00120 WORD wBytesRemainingOnOEP0;     // For endpoint zero transmitter only
    00121                                 // Holds count of bytes remaining to be
    00122                                 // received by endpoint 0.  A value
    00123                                 // of 0 means that a 0-length data packet
    00124                                 // A value of 0xFFFF means that transfer
    00125                                 // is complete.
    00126
    00127 static PBYTE pbIEP0Buffer;      // A buffer pointer to input end point 0
    00128                                 // Data sent back to host is copied from
    00129                                 // this pointed memory location
    00130
    00131 static PBYTE pbOEP0Buffer;      // A buffer pointer to output end point 0
    00132                                 // Data sent from host is copied to
    00133                                 // this pointed memory location
    00134
    00135
    00136 static BYTE bHostAskMoreDataThanAvailable=0;
    00137
    00138 BYTE abUsbRequestReturnData[USB_RETURN_DATA_LENGTH];
    00139 BYTE abUsbRequestIncomingData[USB_RETURN_DATA_LENGTH];
    00140
    00141
    00142 __no_init BYTE abramSerialStringDescriptor[34];
    00143
    00144 BYTE bStatusAction;
    00145
    00146 BYTE bFunctionSuspended=FALSE;  // TRUE if function is suspended
    00147 BYTE bEnumerationStatus = 0;    //is 0 if not enumerated
    00148
    00149 static BYTE bRemoteWakeup;
    00150
    00151 WORD wUsbEventMask;             //used by USB_getEnabledEvents() and USB_setEnabledEvents()
    00152
    00153
    00154 /*----------------------------------------------------------------------------+
    00155 | Global Variables                                                            |
    00156 +----------------------------------------------------------------------------*/
    00157 /*----------------------------------------------------------------------------+
    00158 | Hardware Related Structure Definition                                       |
    00159 +----------------------------------------------------------------------------*/
    00160
    00161 #ifdef __IAR_SYSTEMS_ICC__
    00162
    00163 #pragma location = 0x2380
    00164 __no_init tDEVICE_REQUEST __data16 tSetupPacket;
    00165
    00166 #pragma location = 0x0920
    00167 __no_init tEDB0 __data16 tEndPoint0DescriptorBlock;
    00168
    00169 #pragma location = 0x23C8
    00170 __no_init tEDB __data16 tInputEndPointDescriptorBlock[7];
    00171
    00172 #pragma location = 0x2388
    00173 __no_init tEDB __data16 tOutputEndPointDescriptorBlock[7];
    00174
    00175 #pragma location = 0x2378
    00176 __no_init BYTE __data16 abIEP0Buffer[EP0_MAX_PACKET_SIZE];
    00177
    00178 #pragma location = 0x2370
    00179 __no_init BYTE __data16 abOEP0Buffer[EP0_MAX_PACKET_SIZE];
    00180
    00181 #pragma location = OEP1_X_BUFFER_ADDRESS
    00182  __no_init BYTE __data16 pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
    00183
    00184 #pragma location = OEP1_Y_BUFFER_ADDRESS
    00185  __no_init BYTE __data16 pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
    00186
    00187 #pragma location = IEP1_X_BUFFER_ADDRESS
    00188  __no_init BYTE __data16 pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
    00189
    00190 #pragma location = IEP1_Y_BUFFER_ADDRESS
    00191  __no_init BYTE __data16 pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
    00192
    00193 #pragma location = OEP2_X_BUFFER_ADDRESS
    00194  __no_init BYTE __data16 pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
    00195
    00196 #pragma location = OEP2_Y_BUFFER_ADDRESS
    00197  __no_init BYTE __data16 pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
    00198
    00199 #pragma location = IEP2_X_BUFFER_ADDRESS
    00200  __no_init BYTE __data16 pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
    00201
    00202 #pragma location = IEP2_Y_BUFFER_ADDRESS
    00203  __no_init BYTE __data16 pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
    00204
    00205 #pragma location = OEP3_X_BUFFER_ADDRESS
    00206 __no_init BYTE __data16 pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
    00207
    00208
    00209 #endif
    00210
    00211
    00212 #ifdef __TI_COMPILER_VERSION__
    00213 extern __no_init tDEVICE_REQUEST tSetupPacket;
    00214 extern __no_init tEDB0 tEndPoint0DescriptorBlock;
    00215 extern __no_init tEDB tInputEndPointDescriptorBlock[7];
    00216 extern __no_init tEDB tOutputEndPointDescriptorBlock[7];
    00217 extern __no_init BYTE abIEP0Buffer[EP0_MAX_PACKET_SIZE];
    00218 extern __no_init BYTE abOEP0Buffer[EP0_MAX_PACKET_SIZE];
    00219 extern __no_init BYTE pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
    00220 extern __no_init BYTE pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
    00221 extern __no_init BYTE pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
    00222 extern __no_init BYTE pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
    00223 extern __no_init BYTE pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
    00224 extern __no_init BYTE pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
    00225 extern __no_init BYTE pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
    00226 extern __no_init BYTE pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
    00227 extern __no_init BYTE pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
    00228 #endif
    00229
    00230 VOID CdcResetData();
    00231 VOID HidResetData();
    00232 VOID USB_InitSerialStringDescriptor(VOID);
    00233 VOID USB_initMemcpy(VOID);
    00234
    00235 //----------------------------------------------------------------------------
    00236
    00237
    00238 BYTE USB_init(VOID)
    00239 {
    00240     __disable_interrupt();               // Disable global interrupts
    00241
    00242     // configuration of USB module
    00243     USBKEYPID   =     0x9628;            // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00244
    00245     USBPHYCTL   =     PUSEL;             // use DP and DM as USB terminals
    00246
    00247     USBPWRCTL   =     VUSBEN + SLDOEN + SLDOAON; // enable primary and secondary LDO (3.3 and 1.8 V)
    00248     {
    00249         volatile unsigned int i;
    00250         for (i =0; i < 1000; i++);       // wait some time for LDOs
    00251     }
    00252
    00253     USBPWRCTL   =   VUSBEN + SLDOEN + SLDOAON + VBONIE;  // enable interrupt VBUSon
    00254     USBKEYPID   =    0x9600;            // access to configuration registers disabled
    00255
    00256     //reset events mask
    00257     wUsbEventMask = 0;
    00258
    00259     //init Serial Number
    00260 #if (USB_STR_INDEX_SERNUM != 0)
    00261     USB_InitSerialStringDescriptor();
    00262 #endif
    00263
    00264     // init memcpy() function: DMA or non-DMA
    00265     USB_initMemcpy();
    00266
    00267     __enable_interrupt();                // enable global interrupts
    00268     return kUSB_succeed;
    00269 }
    00270
    00271 //----------------------------------------------------------------------------
    00272 // This function will be compiled only if
    00273 #if (USB_STR_INDEX_SERNUM != 0)
    00274 VOID USB_InitSerialStringDescriptor(VOID)
    00275 {
    00276     BYTE i,j,hexValue;
    00277     PBYTE pbSerNum;
    00278     BYTE bBytes;
    00279
    00280     j=1;                   // we start with second byte, first byte (lenght) will be filled later
    00281     pbSerNum=0;
    00282     abramSerialStringDescriptor[j++] = DESC_TYPE_STRING;
    00283
    00284     // TLV access Function Call
    00285     Get_TLV_info(TLV_DIERECORD, &bBytes, (UINT*)&pbSerNum); //The die record used for serial number
    00286     if (bBytes == 0)    // no serial number available
    00287     {
    00288         // use 00 as serial number = no serial number available
    00289         abramSerialStringDescriptor[0] = 4;      //length
    00290         abramSerialStringDescriptor[j++] = 0;    // no serial number available
    00291         abramSerialStringDescriptor[j++] = 0;    // no serial number available
    00292     }
    00293     else
    00294     {
    00295         for(i=0; (i<bBytes)&&(i<8); i++,pbSerNum++)
    00296         {
    00297             hexValue = (*pbSerNum & 0xF0)>> 4;
    00298             if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
    00299             else abramSerialStringDescriptor[j++] = (hexValue + 55);
    00300             abramSerialStringDescriptor[j++] = 0x00;  // needed for UNI-Code
    00301
    00302             hexValue = (*pbSerNum & 0x0F);
    00303             if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
    00304             else abramSerialStringDescriptor[j++] = (hexValue + 55);
    00305             abramSerialStringDescriptor[j++] = 0x00;    // needed for UNI-Code
    00306         }
    00307         abramSerialStringDescriptor[0] = i*4 +2;        // calculate the length
    00308     }
    00309 }
    00310 #endif
    00311
    00312 //----------------------------------------------------------------------------
    00313
    00314 BYTE USB_enable()
    00315 {
    00316     volatile unsigned int i;
    00317     volatile unsigned int j = 0;
    00318
    00319     if (!(USBPWRCTL & USBBGVBV))            // check USB Bandgap and VBUS valid
    00320     {
    00321         return kUSB_generalError;
    00322     }
    00323
    00324     if ((USBCNF & USB_EN) &&
    00325         (USBPLLCTL & UPLLEN))
    00326     {
    00327         return kUSB_succeed;                // exit if PLL is already enalbed
    00328     }
    00329
    00330     USBKEYPID = 0x9628;                     // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00331     XT2_Start(0);
    00332     USBPLLDIVB = USB_XT_FREQ;               // Settings desired frequency
    00333
    00334     if (USB_PLL_XT == 2)
    00335     {
    00336         USBPLLCTL = UPCS0 + UPFDEN + UPLLEN;// Select XT2 as Ref / Select PLL for USB / Discrim. on, enable PLL
    00337     }
    00338     else
    00339     {
    00340         USBPLLCTL = UPFDEN + UPLLEN;        // Select XT1 as Ref / Select PLL for USB / Discrim. on, enable PLL
    00341     }
    00342
    00343     //Wait some time till PLL is settled
    00344     do {
    00345         USBPLLIR    =     0x0000;           // make sure no interrupts can occur on PLL-module
    00346
    00347         //wait 1/2 ms till enable USB
    00348         for (i =0; i < USB_MCLK_FREQ/1000* 1/2 /10; i++);
    00349
    00350         if (j++ > 10)
    00351         {
    00352             USBKEYPID   =    0x9600;        // access to configuration registers disabled
    00353             return kUSB_generalError;
    00354         }
    00355     }while (USBPLLIR != 0);
    00356
    00357     USBCNF     |=    USB_EN;                // enable USB module
    00358     USBKEYPID   =    0x9600;                // access to configuration registers disabled
    00359     return kUSB_succeed;
    00360 }
    00361
    00362 /*
    00363 Disables the USB module and PLL.
    00364 */
    00365 BYTE USB_disable(VOID)
    00366 {
    00367     USBKEYPID = 0x9628;        // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00368     USBCNF    = 0;             // disable USB module
    00369     USBPLLCTL &= ~UPLLEN;      // disable PLL
    00370     USBKEYPID = 0x9600;        // access to configuration registers disabled
    00371     bEnumerationStatus = 0x00; // device is not enumerated
    00372     bFunctionSuspended = FALSE;// device is not suspended
    00373     return kUSB_succeed;
    00374 }
    00375
    00376 /*
    00377 Enables/disables various USB events.
    00378 */
    00379 BYTE USB_setEnabledEvents(WORD events)
    00380 {
    00381     wUsbEventMask = events;
    00382     return kUSB_succeed;
    00383 }
    00384
    00385 /*
    00386 Returns which events are enabled and which are disabled.
    00387 */
    00388 WORD USB_getEnabledEvents()
    00389 {
    00390     return wUsbEventMask;
    00391 }
    00392
    00393 /*
    00394 Reset USB-SIE and global variables.
    00395 */
    00396 BYTE USB_reset()
    00397 {
    00398     USBKEYPID = 0x9628;                   // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00399
    00400     //reset should be on the bus after this!
    00401     bEnumerationStatus = 0x00;            // Device not enumerated yet
    00402     bFunctionSuspended = FALSE;           // Device is not in suspend mode
    00403
    00404     bRemoteWakeup = DISABLE;
    00405
    00406     bConfigurationNumber    = 0x00;       // device unconfigured
    00407     bInterfaceNumber        = 0x00;
    00408
    00409     // FRSTE Workaround:
    00410     // Clear FRSTE in the RESRIFG interrupt service routine before re-configuring USB control registers.
    00411     // Set FRSTE at the beginning of SUSRIFG, SETUP, IEPIFG.EP0 and OEPIFG.EP0 interrupt service routines.
    00412     USBCTL = 0;                           // Function Reset Connection disable (FRSTE)
    00413
    00414     wBytesRemainingOnIEP0   = NO_MORE_DATA;
    00415     wBytesRemainingOnOEP0   = NO_MORE_DATA;
    00416     bStatusAction           = STATUS_ACTION_NOTHING;
    00417
    00418     //The address reset normally will be done automatically during bus function reset
    00419     USBFUNADR   =     0x00;               // reset address of USB device (unconfigured)
    00420
    00421     /* Set settings for EP0 */
    00422     // NAK both 0 endpoints and enable endpoint 0 interrupt
    00423     tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
    00424     tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
    00425     tEndPoint0DescriptorBlock.bIEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet
    00426     tEndPoint0DescriptorBlock.bOEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet
    00427
    00428     USBOEPIE = BIT0 | BIT1 | BIT3;                // enable EP0, and EP3 output IRQ
    00429     USBIEPIE = BIT0 | BIT1 | BIT2 | BIT3;         // enable EP0, EP1, EP2 and EP3 input IRQ
    00430
    00431
    00432   #ifdef _HID_
    00433     /* Set settings for IEP1 */
    00434     // enable endpoint 1 interrupt, input
    00435     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
    00436     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBBAX  = (BYTE)(((IEP1_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00437     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBBAY  = (BYTE)(((IEP1_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00438     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX  = EPBCNT_NAK;
    00439     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY  = EPBCNT_NAK;
    00440     tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;
    00441
    00442     /* Set settings for OEP1 */
    00443     // enable endpoint 1 interrupt, output
    00444     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF ; //double buffering
    00445     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBBAX  = (BYTE)(((OEP1_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00446     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBBAY  = (BYTE)(((OEP1_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00447     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX  = 0x00;
    00448     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY  = 0x00; // EPBCT_NAK for one buffer (no double)
    00449     tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;
    00450
    00451     HidResetData();                     // reset CDC specific data structures
    00452   #endif // _HID_
    00453
    00454   #ifdef _CDC_
    00455     /* Set settings for IEP2 */
    00456     // enable endpoint 2 interrupt, input
    00457     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPCNF   = EPCNF_USBIE       // use Interrupt for this EP
    00458                                                 | EPCNF_UBME      // enable this EP
    00459                                                 | EPCNF_DBUF;     // use double buffering (X and Y buffers)
    00460     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBBAX  = (BYTE)(((IEP2_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00461     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBBAY  = (BYTE)(((IEP2_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00462     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBCTX  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    00463     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBCTY  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    00464     tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;
    00465
    00466     /* Set settings for IEP3 */
    00467     // enable endpoint 3 bulk, input
    00468     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPCNF   = EPCNF_USBIE       // use Interrupt for this EP
    00469                                                 | EPCNF_UBME      // enable this EP
    00470                                                 | EPCNF_DBUF;     // use double buffering (X and Y buffers)
    00471     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBBAX  = (BYTE)(((IEP3_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00472     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBBAY  = (BYTE)(((IEP3_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00473     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    00474     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    00475     tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;
    00476
    00477     /* Set settings for OEP3 */
    00478     // enable endpoint 3 bulk, output
    00479     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPCNF   = EPCNF_USBIE      // use Interrupt for this EP
    00480                                                  | EPCNF_UBME     // enable this EP
    00481                                                  | EPCNF_DBUF;    // use double buffering (X and Y buffers)
    00482     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBBAX  = (BYTE)(((OEP3_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00483     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBBAY  = (BYTE)(((OEP3_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    00484     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX  = 0x00;
    00485     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY  = 0x00;
    00486     tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;
    00487
    00488     CdcResetData();                     // reset CDC specific data structures
    00489
    00490   #endif // _CDC_
    00491
    00492     USBCTL |= FEN;                      // enable function
    00493     USBIFG = 0;                         // make sure no interrupts are pending
    00494
    00495     USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)
    00496     USBKEYPID = 0x9600;                 // access to configuration registers disabled
    00497     return kUSB_succeed;
    00498 }
    00499
    00500 /*
    00501 Instruct USB module to make itself available to the PC for connection, by pulling PUR high.
    00502 */
    00503 BYTE USB_connect()
    00504 {
    00505     USBKEYPID = 0x9628;   // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00506     USBCNF |= PUR_EN;     // generate rising edge on DP -> the host enumerates our device as full speed device
    00507     USBPWRCTL |= VBOFFIE; // enable interrupt VUSBoff
    00508     USBKEYPID = 0x9600;   // access to configuration registers disabled
    00509
    00510     // after this the enumeration may take place
    00511     __no_operation();
    00512     __no_operation();
    00513     __no_operation();
    00514     __no_operation();
    00515     __no_operation();
    00516     __no_operation();
    00517     __no_operation();
    00518
    00519     return kUSB_succeed;
    00520 }
    00521
    00522 /*
    00523 Force a disconnect from the PC by pulling PUR low.
    00524 */
    00525 BYTE USB_disconnect()
    00526 {
    00527     USBKEYPID = 0x9628;     // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00528     USBCNF &= ~PUR_EN;      // disconnect pull up resistor - logical disconnect from HOST
    00529     //USBCNF = 0;            // disable USB module
    00530     USBPWRCTL &= ~VBOFFIE;  // disable interrupt VUSBoff
    00531     USBKEYPID = 0x9600;     // access to configuration registers disabled
    00532     bEnumerationStatus = 0; // not enumerated
    00533     bFunctionSuspended = FALSE;     // device is not suspended
    00534     return kUSB_succeed;
    00535 }
    00536
    00537 /*
    00538 Force a remote wakeup of the USB host.
    00539 */
    00540 BYTE USB_forceRemoteWakeup()
    00541 {
    00542     if (bFunctionSuspended == FALSE) // device is not suspended
    00543     {
    00544         return kUSB_NotSuspended;
    00545     }
    00546     if(bRemoteWakeup == ENABLE)
    00547     {
    00548         volatile unsigned int i;
    00549         USBCTL |= RWUP;             // USB - Device Remote Wakeup Request - this bit is self-cleaned
    00550         return kUSB_succeed;
    00551     }
    00552     return kUSB_generalError;
    00553 }
    00554
    00555 /*
    00556 Returns the status of the USB connection.
    00557 */
    00558 BYTE USB_connectionInfo()
    00559 {
    00560     BYTE retVal = 0;
    00561     if (USBPWRCTL & USBBGVBV)
    00562     {
    00563         retVal |= kUSB_vbusPresent;
    00564     }
    00565
    00566     if (bEnumerationStatus == ENUMERATION_COMPLETE)
    00567     {
    00568         retVal |= kUSB_Enumerated;
    00569     }
    00570     /*
    00571     if () //sync frame are received
    00572     {
    00573         kUSB_busActive;
    00574     } */
    00575
    00576     if (USBCNF & PUR_EN)
    00577     {
    00578         retVal |= kUSB_purHigh;
    00579     }
    00580
    00581     if (bFunctionSuspended == TRUE)
    00582     {
    00583         retVal |= kUSB_suspended;
    00584     }
    00585     else
    00586     {
    00587         retVal |= kUSB_NotSuspended;
    00588     }
    00589     return retVal;
    00590 }
    00591
    00592 /*
    00593 Returns the state of the USB connection.
    00594 */
    00595 BYTE USB_connectionState()
    00596 {
    00597     // If no VBUS present
    00598     if (!(USBPWRCTL & USBBGVBV))
    00599     {
    00600         return ST_USB_DISCONNECTED;
    00601     }
    00602
    00603     // If VBUS present, but PUR is low
    00604     if ((USBPWRCTL & USBBGVBV)&&(!(USBCNF & PUR_EN)))
    00605     {
    00606         return ST_USB_CONNECTED_NO_ENUM;
    00607     }
    00608
    00609     // If VBUS present, PUR is high, and enumeration is complete, and not suspended
    00610     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
    00611         && (bEnumerationStatus == ENUMERATION_COMPLETE)
    00612         && (!(bFunctionSuspended == TRUE)))
    00613     {
    00614         return ST_ENUM_ACTIVE;
    00615     }
    00616
    00617     // If VBUS present, PUR is high, and enumeration is NOT complete, and  suspended
    00618     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
    00619         && (!(bEnumerationStatus == ENUMERATION_COMPLETE))
    00620         && (bFunctionSuspended == TRUE))
    00621     {
    00622         return ST_NOENUM_SUSPENDED;
    00623     }
    00624
    00625     // If VBUS present, PUR is high, and enumeration is complete, and  suspended
    00626     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
    00627         && (bEnumerationStatus == ENUMERATION_COMPLETE)
    00628         && (bFunctionSuspended == TRUE))
    00629     {
    00630         return ST_ENUM_SUSPENDED;
    00631     }
    00632
    00633     // If VBUS present, PUR is high, but no enumeration yet
    00634     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
    00635         && (!(bEnumerationStatus == ENUMERATION_COMPLETE)))
    00636     {
    00637         return ST_ENUM_IN_PROGRESS;
    00638     }
    00639
    00640     return ST_ERROR;
    00641 }
    00642
    00643 //----------------------------------------------------------------------------
    00644
    00645 BYTE USB_suspend(VOID)
    00646 {
    00647     bFunctionSuspended  = TRUE;
    00648     USBKEYPID = 0x9628;         // set KEY and PID to 0x9628 -> access to configuration registers enabled
    00649     USBCTL |= FRSTE;            // Function Reset Connection Enable
    00650     USBIFG &= ~SUSRIFG;         // clear interrupt flag
    00651
    00652     if(USB_DISABLE_XT_SUSPEND)
    00653     {
    00654         if (USB_PLL_XT == 2)
    00655         {
    00656             USBPLLCTL &= ~UPLLEN;         // disable PLL
    00657             UCSCTL6   |= XT2OFF;         // disable XT2
    00658         }
    00659         else
    00660         {
    00661             USBPLLCTL &= ~UPLLEN;           // disable PLL
    00662             UCSCTL6 |= XT1OFF;
    00663         }
    00664     }
    00665
    00666     USBIE = RESRIE;             // disable USB specific interrupts (setup, suspend, reset), enable resume.
    00667                                 // If the reset occured during device in suspend, the resume-interrupt will come, after - reset interrupt
    00668     USBKEYPID = 0x9600;         // access to configuration registers disabled
    00669     return kUSB_succeed;
    00670 }
    00671
    00672 //----------------------------------------------------------------------------
    00673
    00674 BYTE USB_resume(VOID)
    00675 {
    00676     USB_enable();                       // enable PLL
    00677
    00678     USBIFG &= ~(RESRIFG | SUSRIFG);     // clear interrupt flags
    00679     USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)
    00680
    00681     bFunctionSuspended  = FALSE;
    00682     return kUSB_succeed;
    00683 }
    00684
    00685 //----------------------------------------------------------------------------
    00686
    00687 VOID usbStallEndpoint0(VOID)
    00688 {
    00689     tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
    00690     tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
    00691 }
    00692
    00693 //----------------------------------------------------------------------------
    00694
    00695 VOID usbClearOEP0ByteCount(VOID)
    00696 {
    00697     tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
    00698 }
    00699
    00700 //----------------------------------------------------------------------------
    00701
    00702 VOID usbStallOEP0(VOID)
    00703 {
    00704     // in standard USB request, there is not control write request with data stage
    00705     // control write, stall output endpoint 0
    00706     // wLength should be 0 in all cases
    00707     tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
    00708 }
    00709
    00710 //----------------------------------------------------------------------------
    00711
    00712 VOID usbSendNextPacketOnIEP0(VOID)
    00713 {
    00714     BYTE bPacketSize,bIndex;
    00715
    00716     // First check if there are bytes remaining to be transferred
    00717     if(wBytesRemainingOnIEP0 != NO_MORE_DATA){
    00718         if(wBytesRemainingOnIEP0 > EP0_PACKET_SIZE){
    00719             // More bytes are remaining than will fit in one packet
    00720             // there will be More IN Stage
    00721             bPacketSize = EP0_PACKET_SIZE;
    00722             wBytesRemainingOnIEP0 -= EP0_PACKET_SIZE;
    00723             bStatusAction = STATUS_ACTION_DATA_IN;
    00724
    00725         }else if (wBytesRemainingOnIEP0 < EP0_PACKET_SIZE){
    00726             // The remaining data will fit in one packet.
    00727             // This case will properly handle wBytesRemainingOnIEP0 == 0
    00728             bPacketSize = (BYTE)wBytesRemainingOnIEP0;
    00729             wBytesRemainingOnIEP0 = NO_MORE_DATA;        // No more data need to be Txed
    00730             bStatusAction = STATUS_ACTION_NOTHING;
    00731
    00732         }else{
    00733             bPacketSize = EP0_PACKET_SIZE;
    00734             if(bHostAskMoreDataThanAvailable == TRUE){
    00735                 wBytesRemainingOnIEP0 = 0;
    00736                 bStatusAction = STATUS_ACTION_DATA_IN;
    00737             }else{
    00738                 wBytesRemainingOnIEP0 = NO_MORE_DATA;
    00739                 bStatusAction = STATUS_ACTION_NOTHING;
    00740             }
    00741         }
    00742
    00743         for(bIndex=0; bIndex<bPacketSize; bIndex++)
    00744         {
    00745             abIEP0Buffer[bIndex] = *pbIEP0Buffer;
    00746             pbIEP0Buffer++;
    00747         }
    00748         tEndPoint0DescriptorBlock.bIEPBCNT = bPacketSize;
    00749
    00750     }else bStatusAction = STATUS_ACTION_NOTHING;
    00751
    00752 }
    00753
    00754 //----------------------------------------------------------------------------
    00755
    00756 VOID usbSendDataPacketOnEP0(PBYTE pbBuffer)
    00757 {
    00758     WORD wTemp;
    00759
    00760     pbIEP0Buffer = pbBuffer;
    00761     wTemp = tSetupPacket.wLength;
    00762
    00763     // Limit transfer size to wLength if needed
    00764     // this prevent USB device sending 'more than require' data back to host
    00765     if(wBytesRemainingOnIEP0 >= wTemp){
    00766         wBytesRemainingOnIEP0 = wTemp;
    00767         bHostAskMoreDataThanAvailable = FALSE;
    00768     }else bHostAskMoreDataThanAvailable = TRUE;
    00769
    00770     usbSendNextPacketOnIEP0();
    00771 }
    00772
    00773 //----------------------------------------------------------------------------
    00774 VOID usbReceiveNextPacketOnOEP0(VOID)
    00775 {
    00776     BYTE bIndex,bByte;
    00777
    00778     bByte = tEndPoint0DescriptorBlock.bOEPBCNT & EPBCNT_BYTECNT_MASK;
    00779
    00780     if(wBytesRemainingOnOEP0 >= (WORD)bByte)
    00781     {
    00782         for(bIndex=0;bIndex<bByte;bIndex++)
    00783         {
    00784             *pbOEP0Buffer = abOEP0Buffer[bIndex];
    00785             pbOEP0Buffer++;
    00786         }
    00787         wBytesRemainingOnOEP0 -= (WORD)bByte;
    00788
    00789         // clear the NAK bit for next packet
    00790         if(wBytesRemainingOnOEP0 > 0)
    00791         {
    00792             usbClearOEP0ByteCount();
    00793             bStatusAction = STATUS_ACTION_DATA_OUT;
    00794         }
    00795         else
    00796         {
    00797             usbStallOEP0();
    00798             bStatusAction = STATUS_ACTION_NOTHING;
    00799         }
    00800     }
    00801     else
    00802     {
    00803         usbStallOEP0();
    00804         bStatusAction = STATUS_ACTION_NOTHING;
    00805     }
    00806 }
    00807
    00808 //----------------------------------------------------------------------------
    00809
    00810 VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
    00811 {
    00812
    00813     pbOEP0Buffer = pbBuffer;
    00814
    00815     wBytesRemainingOnOEP0 = tSetupPacket.wLength;
    00816     bStatusAction = STATUS_ACTION_DATA_OUT;
    00817
    00818     usbClearOEP0ByteCount();
    00819 }
    00820
    00821 //----------------------------------------------------------------------------
    00822
    00823 VOID usbSendZeroLengthPacketOnIEP0(VOID)
    00824 {
    00825     wBytesRemainingOnIEP0 = NO_MORE_DATA;
    00826     bStatusAction = STATUS_ACTION_NOTHING;
    00827     tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
    00828 }
    00829
    00830 //----------------------------------------------------------------------------
    00831
    00832 VOID usbClearEndpointFeature(VOID)
    00833 {
    00834     BYTE bEndpointNumber;
    00835
    00836     // EP is from EP1 to EP7 while C language start from 0
    00837     bEndpointNumber = (tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM);
    00838     if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();
    00839     else{
    00840         bEndpointNumber--;
    00841         if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
    00842             if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN){
    00843                 // input endpoint
    00844                 tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE);
    00845             }else{
    00846                 // output endpoint
    00847                 tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE);
    00848             }
    00849             usbSendZeroLengthPacketOnIEP0();
    00850         }
    00851     }
    00852 }
    00853
    00854 //----------------------------------------------------------------------------
    00855
    00856 VOID usbGetConfiguration(VOID)
    00857 {
    00858     usbClearOEP0ByteCount();                    // for status stage
    00859
    00860     wBytesRemainingOnIEP0 = 1;
    00861     usbSendDataPacketOnEP0((PBYTE)&bConfigurationNumber);
    00862 }
    00863
    00864 //----------------------------------------------------------------------------
    00865
    00866 VOID usbGetDeviceDescriptor(VOID)
    00867 {
    00868     usbClearOEP0ByteCount();
    00869     wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
    00870     usbSendDataPacketOnEP0((PBYTE) &abromDeviceDescriptor);
    00871 }
    00872
    00873 //----------------------------------------------------------------------------
    00874
    00875 VOID usbGetConfigurationDescriptor(VOID)
    00876 {
    00877     usbClearOEP0ByteCount();
    00878     wBytesRemainingOnIEP0 = sizeof(abromConfigurationDescriptorGroup);
    00879     usbSendDataPacketOnEP0((PBYTE)&abromConfigurationDescriptorGroup);
    00880 }
    00881
    00882 //----------------------------------------------------------------------------
    00883
    00884 VOID usbGetStringDescriptor(VOID)
    00885 {
    00886     WORD bIndex;
    00887     BYTE bVal = (BYTE)tSetupPacket.wValue;
    00888
    00889     usbClearOEP0ByteCount();                    // for status stage
    00890 #if (USB_STR_INDEX_SERNUM != 0)
    00891
    00892     if(bVal == 0x03)
    00893     {
    00894         wBytesRemainingOnIEP0 = abramSerialStringDescriptor[0];
    00895         usbSendDataPacketOnEP0((PBYTE)&abramSerialStringDescriptor);
    00896     }
    00897     else
    00898 #endif
    00899     {
    00900         bIndex = 0x00;
    00901         while(bVal-- >  0x00) bIndex += abromStringDescriptor[bIndex];
    00902         wBytesRemainingOnIEP0 = abromStringDescriptor[bIndex];
    00903         usbSendDataPacketOnEP0((PBYTE)&abromStringDescriptor[bIndex]);
    00904     }
    00905 }
    00906
    00907 //----------------------------------------------------------------------------
    00908
    00909 VOID usbGetInterface(VOID)
    00910 {
    00911
    00912     // not fully supported, return one byte, zero
    00913     usbClearOEP0ByteCount();                    // for status stage
    00914     wBytesRemainingOnIEP0 = 0x02;
    00915     abUsbRequestReturnData[0] = 0x00;           // changed to report alternative setting byte
    00916     abUsbRequestReturnData[1] = bInterfaceNumber;
    00917     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
    00918 }
    00919
    00920 //----------------------------------------------------------------------------
    00921
    00922 VOID usbGetDeviceStatus(VOID)
    00923 {
    00924
    00925     if((abromConfigurationDescriptorGroup[OFFSET_CONFIG_DESCRIPTOR_POWER] &
    00926         CFG_DESC_ATTR_SELF_POWERED) == CFG_DESC_ATTR_SELF_POWERED)
    00927         abUsbRequestReturnData[0] = DEVICE_STATUS_SELF_POWER;
    00928
    00929     if(bRemoteWakeup == ENABLE)
    00930         abUsbRequestReturnData[0] |= DEVICE_STATUS_REMOTE_WAKEUP;
    00931
    00932     usbClearOEP0ByteCount();                    // for status stage
    00933
    00934     // Return self power status and remote wakeup status
    00935     wBytesRemainingOnIEP0 = 2;
    00936     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
    00937 }
    00938
    00939 //----------------------------------------------------------------------------
    00940
    00941 VOID usbGetInterfaceStatus(VOID)
    00942 {
    00943
    00944     // check bIndexL for index number (not supported)
    00945     usbClearOEP0ByteCount();                    // for status stage
    00946
    00947     // Return two zero bytes
    00948     wBytesRemainingOnIEP0 = 2;
    00949     abUsbRequestReturnData[0] = 0x00;           // changed to support multiple interfaces
    00950     abUsbRequestReturnData[1] = bInterfaceNumber;
    00951     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
    00952 }
    00953
    00954 //----------------------------------------------------------------------------
    00955
    00956 VOID usbGetEndpointStatus(VOID)
    00957 {
    00958     BYTE bEndpointNumber;
    00959
    00960     // Endpoint number is bIndexL
    00961     bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
    00962     if(bEndpointNumber == 0x00){
    00963         if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN){
    00964             // input endpoint 0
    00965             abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bIEPCNFG & EPCNF_STALL);
    00966         }else{
    00967             // output endpoint 0
    00968             abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bOEPCNFG & EPCNF_STALL);
    00969         }
    00970         abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
    00971         usbClearOEP0ByteCount();                    // for status stage
    00972         wBytesRemainingOnIEP0 = 0x02;
    00973         usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
    00974     }else{
    00975         bEndpointNumber--;
    00976         // EP is from EP1 to EP7 while C language start from 0
    00977         // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
    00978         if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
    00979             if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN){
    00980                 // input endpoint
    00981                 abUsbRequestReturnData[0] = (BYTE)(tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
    00982             }else{
    00983                 // output endpoint
    00984                 abUsbRequestReturnData[0] = (BYTE)(tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
    00985             }
    00986         }   // no response if endpoint is not supported.
    00987         abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
    00988         usbClearOEP0ByteCount();
    00989         wBytesRemainingOnIEP0 = 0x02;
    00990         usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
    00991     }
    00992 }
    00993
    00994 //----------------------------------------------------------------------------
    00995 VOID usbSetAddress(VOID)
    00996 {
    00997     usbStallOEP0();                             // control write without data stage
    00998
    00999     // bValueL contains device address
    01000     if(tSetupPacket.wValue < 128){
    01001         // hardware will update the address after status stage
    01002         // therefore, firmware can set the address now.
    01003         USBFUNADR = tSetupPacket.wValue;
    01004         usbSendZeroLengthPacketOnIEP0();
    01005     }else usbStallEndpoint0();
    01006 }
    01007
    01008 //----------------------------------------------------------------------------
    01009
    01010 VOID usbSetConfiguration(VOID)
    01011 {
    01012     usbStallOEP0();                             // control write without data stage
    01013
    01014     // configuration number is in bValueL
    01015     // change the code if more than one configuration is supported
    01016     bConfigurationNumber = tSetupPacket.wValue;
    01017     usbSendZeroLengthPacketOnIEP0();
    01018
    01019     if (bConfigurationNumber == 1)
    01020     {
    01021         bEnumerationStatus = ENUMERATION_COMPLETE;      // set device as enumerated
    01022     }
    01023     else
    01024     {
    01025         bEnumerationStatus = 0; //device is not configured == config # is zero
    01026     }
    01027 }
    01028
    01029 //----------------------------------------------------------------------------
    01030
    01031 VOID usbClearDeviceFeature(VOID)
    01032 {
    01033     // bValueL contains feature selector
    01034     if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP){
    01035         bRemoteWakeup = DISABLE;
    01036         usbSendZeroLengthPacketOnIEP0();
    01037     }else usbStallEndpoint0();
    01038 }
    01039
    01040 //----------------------------------------------------------------------------
    01041
    01042 VOID usbSetDeviceFeature(VOID)
    01043 {
    01044     // bValueL contains feature selector
    01045     if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP){
    01046         bRemoteWakeup = ENABLE;
    01047         usbSendZeroLengthPacketOnIEP0();
    01048     }else usbStallEndpoint0();
    01049 }
    01050
    01051 //----------------------------------------------------------------------------
    01052
    01053 VOID usbSetEndpointFeature(VOID)
    01054 {
    01055     BYTE bEndpointNumber;
    01056
    01057     // wValue contains feature selector
    01058     // bIndexL contains endpoint number
    01059     // Endpoint number is in low byte of wIndex
    01060     if(tSetupPacket.wValue == FEATURE_ENDPOINT_STALL){
    01061         bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
    01062         if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();  // do nothing for endpoint 0
    01063         else{
    01064             bEndpointNumber--;
    01065             // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
    01066             if(bEndpointNumber < MAX_ENDPOINT_NUMBER){
    01067                 if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN){
    01068                     // input endpoint
    01069                     tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
    01070                 }else{
    01071                     // output endpoint
    01072                     tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
    01073                 }
    01074                 usbSendZeroLengthPacketOnIEP0();
    01075             } // no response if endpoint is not supported.
    01076         }
    01077     }else usbStallEndpoint0();
    01078 }
    01079
    01080 //----------------------------------------------------------------------------
    01081
    01082 VOID usbSetInterface(VOID)
    01083 {
    01084     // bValueL contains alternative setting
    01085     // bIndexL contains interface number
    01086     // change code if more than one interface is supported
    01087     usbStallOEP0();                             // control write without data stage
    01088     bInterfaceNumber = tSetupPacket.wIndex;
    01089     usbSendZeroLengthPacketOnIEP0();
    01090 }
    01091
    01092 //----------------------------------------------------------------------------
    01093
    01094 VOID usbInvalidRequest(VOID)
    01095 {
    01096     // check if setup overwrite is set
    01097     // if set, do nothing since we might decode it wrong
    01098     // setup packet buffer could be modified by hardware if another setup packet
    01099     // was sent while we are deocding setup packet
    01100     if((USBIFG & STPOWIFG) == 0x00){
    01101       usbStallEndpoint0();
    01102     }
    01103 }
    01104
    01105 //----------------------------------------------------------------------------
    01106
    01107 static const tDEVICE_REQUEST_COMPARE tUsbRequestList[] =
    01108 {
    01109   #ifdef _CDC_
    01110     //---- CDC Class Requests -----//
    01111     // GET LINE CODING
    01112     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
    01113     USB_CDC_GET_LINE_CODING,
    01114     0x00,0x00,                          // always zero
    01115     INTERFACE_NUMBER_CDC,0x00,          // CDC interface is 0
    01116     0x07,0x00,                          // Size of Structure (data length)
    01117     0xff,&usbGetLineCoding,
    01118
    01119     // SET LINE CODING
    01120     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
    01121     USB_CDC_SET_LINE_CODING,
    01122     0x00,0x00,                          // always zero
    01123     INTERFACE_NUMBER_CDC,0x00,          // CDC interface is 0
    01124     0x07,0x00,                          // Size of Structure (data length)
    01125     0xff,&usbSetLineCoding,
    01126
    01127     // SET CONTROL LINE STATE
    01128     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
    01129     USB_CDC_SET_CONTROL_LINE_STATE,
    01130     0xff,0xff,                          // Contains data
    01131     INTERFACE_NUMBER_CDC,0x00,          // CDC interface is 0
    01132     0x00,0x00,                          // No further data
    01133     0xcf,&usbSetControlLineState,
    01134   #endif // _CDC
    01135
    01136
    01137     //---- USB Standard Requests -----//
    01138     // clear device feature
    01139     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01140     USB_REQ_CLEAR_FEATURE,
    01141     FEATURE_REMOTE_WAKEUP,0x00,         // feature selector
    01142     0x00,0x00,
    01143     0x00,0x00,
    01144     0xff,&usbClearDeviceFeature,
    01145
    01146     // clear endpoint feature
    01147     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
    01148     USB_REQ_CLEAR_FEATURE,
    01149     FEATURE_ENDPOINT_STALL,0x00,
    01150     0xff,0x00,
    01151     0x00,0x00,
    01152     0xf7,&usbClearEndpointFeature,
    01153
    01154     // get configuration
    01155     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01156     USB_REQ_GET_CONFIGURATION,
    01157     0x00,0x00,
    01158     0x00,0x00,
    01159     0x01,0x00,
    01160     0xff,&usbGetConfiguration,
    01161
    01162     // get device descriptor
    01163     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01164     USB_REQ_GET_DESCRIPTOR,
    01165     0xff,DESC_TYPE_DEVICE,              // bValueL is index and bValueH is type
    01166     0xff,0xff,
    01167     0xff,0xff,
    01168     0xd0,&usbGetDeviceDescriptor,
    01169
    01170     // get configuration descriptor
    01171     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01172     USB_REQ_GET_DESCRIPTOR,
    01173     0xff,DESC_TYPE_CONFIG,              // bValueL is index and bValueH is type
    01174     0xff,0xff,
    01175     0xff,0xff,
    01176     0xd0,&usbGetConfigurationDescriptor,
    01177
    01178     // get string descriptor
    01179     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01180     USB_REQ_GET_DESCRIPTOR,
    01181     0xff,DESC_TYPE_STRING,              // bValueL is index and bValueH is type
    01182     0xff,0xff,
    01183     0xff,0xff,
    01184     0xd0,&usbGetStringDescriptor,
    01185
    01186     // get interface
    01187     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
    01188     USB_REQ_GET_INTERFACE,
    01189     0x00,0x00,
    01190     0xff,0xff,
    01191     0x01,0x00,
    01192     0xf3,&usbGetInterface,
    01193
    01194     // get device status
    01195     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01196     USB_REQ_GET_STATUS,
    01197     0x00,0x00,
    01198     0x00,0x00,
    01199     0x02,0x00,
    01200     0xff,&usbGetDeviceStatus,
    01201
    01202     // get interface status
    01203     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
    01204     USB_REQ_GET_STATUS,
    01205     0x00,0x00,
    01206     0xff,0x00,
    01207     0x02,0x00,
    01208     0xf7,&usbGetInterfaceStatus,
    01209
    01210     // get endpoint status
    01211     USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
    01212     USB_REQ_GET_STATUS,
    01213     0x00,0x00,
    01214     0xff,0x00,
    01215     0x02,0x00,
    01216     0xf7,&usbGetEndpointStatus,
    01217
    01218     // set address
    01219     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01220     USB_REQ_SET_ADDRESS,
    01221     0xff,0x00,
    01222     0x00,0x00,
    01223     0x00,0x00,
    01224     0xdf,&usbSetAddress,
    01225
    01226     // set configuration
    01227     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01228     USB_REQ_SET_CONFIGURATION,
    01229     0xff,0x00,
    01230     0x00,0x00,
    01231     0x00,0x00,
    01232     0xdf,&usbSetConfiguration,
    01233
    01234     // set device feature
    01235     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE,
    01236     USB_REQ_SET_FEATURE,
    01237     0xff,0x00,                      // feature selector
    01238     0x00,0x00,
    01239     0x00,0x00,
    01240     0xdf,&usbSetDeviceFeature,
    01241
    01242     // set endpoint feature
    01243     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT,
    01244     USB_REQ_SET_FEATURE,
    01245     0xff,0x00,                      // feature selector
    01246     0xff,0x00,                      // endpoint number <= 127
    01247     0x00,0x00,
    01248     0xd7,&usbSetEndpointFeature,
    01249
    01250     // set interface
    01251     USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
    01252     USB_REQ_SET_INTERFACE,
    01253     0xff,0x00,                      // feature selector
    01254     0xff,0x00,                      // interface number
    01255     0x00,0x00,
    01256     0xd7,&usbSetInterface,
    01257
    01258     // end of usb descriptor -- this one will be matched to any USB request
    01259     //                          since bCompareMask is 0x00.
    01260     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    01261     0x00,&usbInvalidRequest     // end of list
    01262 };
    01263
    01264 typedef VOID (*tpF)(VOID);
    01265
    01266 BYTE usbDecodeAndProcessUsbRequest(VOID)
    01267 {
    01268     BYTE  bMask,bResult,bTemp;
    01269     const BYTE* pbUsbRequestList;
    01270     BYTE bWakeUp = FALSE;
    01271     ptDEVICE_REQUEST ptSetupPacket = &tSetupPacket;
    01272     BYTE  bRequestType,bRequest;
    01273     DWORD lAddrOfFunction;
    01274
    01275     // point to beginning of the matrix
    01276     pbUsbRequestList = (PBYTE)&tUsbRequestList[0];
    01277
    01278     while(1){
    01279
    01280         bRequestType = *pbUsbRequestList++;
    01281         bRequest     = *pbUsbRequestList++;
    01282
    01283         if(((bRequestType == 0xff) && (bRequest == 0xff)) ||
    01284             (tSetupPacket.bmRequestType == (USB_REQ_TYPE_INPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) ||
    01285             (tSetupPacket.bmRequestType == (USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)))
    01286         {
    01287             pbUsbRequestList -= 2;
    01288             break;
    01289         }
    01290
    01291         if((bRequestType == tSetupPacket.bmRequestType) && (bRequest == tSetupPacket.bRequest))
    01292         {
    01293             // compare the first two
    01294             bResult = 0xc0;
    01295             bMask   = 0x20;
    01296             // first two bytes matched, compare the rest
    01297             for(bTemp = 2; bTemp < 8; bTemp++)
    01298             {
    01299                 if (*((BYTE*)ptSetupPacket + bTemp) == *pbUsbRequestList)
    01300                 {
    01301                     bResult |= bMask;
    01302                 }
    01303                 pbUsbRequestList++;
    01304                 bMask = bMask >> 1;
    01305             }
    01306             // now we have the result
    01307             if((*pbUsbRequestList & bResult) == *pbUsbRequestList)
    01308             {
    01309                 pbUsbRequestList -= 8;
    01310                 break;
    01311             }
    01312             else
    01313             {
    01314                 pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-8);
    01315             }
    01316         }
    01317         else
    01318         {
    01319             pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-2);
    01320         }
    01321     }
    01322
    01323     // if another setup packet comes before we have the chance to process current
    01324     // setup request, we return here without processing the request
    01325     // this check is not necessary but still kept here to reduce response(or simulation) time
    01326
    01327     if((USBIFG & STPOWIFG) != 0x00)
    01328     {
    01329         return bWakeUp;
    01330     }
    01331
    01332     // now we found the match and jump to the function accordingly.
    01333     // tDEVICE_REQUEST_COMPARE  -->  member of structure
    01334     // VOID(*pUsbFunction)(VOID) --> function pointer in the structure we want to call
    01335     lAddrOfFunction = *((PDWORD)((pbUsbRequestList) + 10));
    01336
    01337     // call function
    01338     ((tpF)lAddrOfFunction)();
    01339
    01340     // perform enumeration complete event:
    01341     // when SetAddress was called and USBADDR is not zero
    01342     if (((tpF)lAddrOfFunction == &usbSetAddress) && (USBFUNADR != 0))
    01343     {
    01344         bWakeUp = USB_handleEnumCompleteEvent();
    01345     }
    01346     return bWakeUp;
    01347 }
    01348
    01349 /*----------------------------------------------------------------------------+
    01350 | End of source file                                                          |
    01351 +----------------------------------------------------------------------------*/
    01352 /*------------------------ Nothing Below This Line --------------------------*/