• 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 --------------------------*/

Generated on Fri Dec 17 2010 12:09:22 for Multi-cell Lithium-Ion Battery Manager System using MSP430 and BQ76PL536 by  doxygen 1.7.1