]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - msp430-bsl/msp430-bsl.git/blob - USB_API/USB_Common/usb.c
Adding IAR Embedded Workbench files for IAR EW 5.56.5.
[msp430-bsl/msp430-bsl.git] / USB_API / USB_Common / usb.c
1 /*
2  * usb.c
3  *
4  * Common USB functions
5  *
6  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
7  * 
8  * 
9  *  Redistribution and use in source and binary forms, with or without 
10  *  modification, are permitted provided that the following conditions 
11  *  are met:
12  *
13  *    Redistributions of source code must retain the above copyright 
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  *    Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the 
18  *    documentation and/or other materials provided with the   
19  *    distribution.
20  *
21  *    Neither the name of Texas Instruments Incorporated nor the names of
22  *    its contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
26  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
27  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
29  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
30  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
31  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
34  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
35  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  */
39 /*----------------------------------------------------------------------------+
40 |                                                                             |
41 |                              Texas Instruments                              |
42 |                                                                             |
43 |                          MSP430 USB-Example (CDC/HID Driver)                |
44 |                                                                             |
45 +-----------------------------------------------------------------------------+
46 |  Source: usb.c, File Version 1.02 2010/06/17                                |
47 |  Author: RSTO                                                               |
48 |                                                                             |
49 |  WHO          WHEN         WHAT                                             |
50 |  ---          ----------   ------------------------------------------------ |
51 |  RSTO         2008/09/03   born                                             |
52 |  RSTO         2008/12/23   enhancements of CDC API                          |
53 |  RSTO         2009/01/12   enhancements for USB serial number               |
54 |  RSTO         2009/05/15   added USB_connectionState()                      |
55 |  RSTO         2009/07/17   added __data16 qualifier for USB buffers         |
56 |  RSTO         2009/08/04   workaround for PLL start up problem              |
57 |  MSP,Biju     2009/10/20   Changes for composite support                    |
58 |  RSTO         2009/10/21   updated USB_InitSerialStringDescriptor()         |
59 |  RSTO         2009/11/05   updated USB_connectionState()                    |
60 |  MSP,Biju     2010/07/15   Updated for MSC                                  |
61 +----------------------------------------------------------------------------*/
62 /*----------------------------------------------------------------------------+
63 | Include files                                                               |
64 +----------------------------------------------------------------------------*/
66 #include "../USB_Common/device.h"
67 #include "../USB_Common/types.h"              // Basic Type declarations
68 #include "../USB_Common/defMSP430USB.h"
69 #include "../USB_Common/usb.h"  // USB-specific Data Structures
70 #include "../USB_CDC_API/UsbCdc.h"
71 #include "../USB_HID_API/UsbHidReq.h"
72 #include "../USB_MSC_API/UsbMscScsi.h"
73 #include <descriptors.h>
75 #include <HAL_UCS.h>
76 #include <HAL_TLV.h>
77 #include <string.h>
79 /*----------------------------------------------------------------------------+
80  | Internal Constant Definition                                               |
81  +----------------------------------------------------------------------------*/
82 #define NO_MORE_DATA    0xFFFF
83 #define EPBCT_NAK       0x80 
84 #define EPCNF_TOGLE     0x20
86 #define DIRECTION_IN    0x80
87 #define DIRECTION_OUT   0x00
89 /*----------------------------------------------------------------------------+
90 | Internal Variables                                                          |
91 +----------------------------------------------------------------------------*/
93 static BYTE bConfigurationNumber;      // Set to 1 when USB device has been
94                                 // configured, set to 0 when unconfigured
96 static BYTE bInterfaceNumber;   // interface number
98 WORD wBytesRemainingOnIEP0;     // For endpoint zero transmitter only
99                                 // Holds count of bytes remaining to be
100                                 // transmitted by endpoint 0.  A value
101                                 // of 0 means that a 0-length data packet
102                                 // A value of 0xFFFF means that transfer
103                                 // is complete.
105 WORD wBytesRemainingOnOEP0;     // For endpoint zero transmitter only
106                                 // Holds count of bytes remaining to be
107                                 // received by endpoint 0.  A value
108                                 // of 0 means that a 0-length data packet
109                                 // A value of 0xFFFF means that transfer
110                                 // is complete.
112 static PBYTE pbIEP0Buffer;      // A buffer pointer to input end point 0
113                                 // Data sent back to host is copied from
114                                 // this pointed memory location
116 static PBYTE pbOEP0Buffer;      // A buffer pointer to output end point 0
117                                 // Data sent from host is copied to
118                                 // this pointed memory location
120 static BYTE bHostAskMoreDataThanAvailable=0;
122 BYTE abUsbRequestReturnData[USB_RETURN_DATA_LENGTH];
123 BYTE abUsbRequestIncomingData[USB_RETURN_DATA_LENGTH];
125 __no_init BYTE abramSerialStringDescriptor[34];
127 BYTE bStatusAction;
128 BYTE bFunctionSuspended=FALSE;  // TRUE if function is suspended
129 BYTE bEnumerationStatus = 0;    //is 0 if not enumerated
131 static BYTE bRemoteWakeup;
133 WORD wUsbEventMask;             //used by USB_getEnabledEvents() and USB_setEnabledEvents()
135 #ifdef _MSC_
136 extern void USBMSC_reset(void);
137 void MscResetData();
138 extern BOOL bMcsCommandSupported;  
139 extern BOOL isMSCConfigured;
141 extern BYTE bMscResetRequired;
142 #endif
144 /*----------------------------------------------------------------------------+
145 | Global Variables                                                            |
146 +----------------------------------------------------------------------------*/
147 /*----------------------------------------------------------------------------+
148 | Hardware Related Structure Definition                                       |
149 +----------------------------------------------------------------------------*/
151 #ifdef __IAR_SYSTEMS_ICC__
153 #pragma location = 0x2380
154 __no_init tDEVICE_REQUEST __data16 tSetupPacket;
156 #pragma location = 0x0920
157 __no_init tEDB0 __data16 tEndPoint0DescriptorBlock;
159 #pragma location = 0x23C8
160 __no_init tEDB __data16 tInputEndPointDescriptorBlock[7];
162 #pragma location = 0x2388
163 __no_init tEDB __data16 tOutputEndPointDescriptorBlock[7];
165 #pragma location = 0x2378
166 __no_init BYTE __data16 abIEP0Buffer[EP0_MAX_PACKET_SIZE];
168 #pragma location = 0x2370
169 __no_init BYTE __data16 abOEP0Buffer[EP0_MAX_PACKET_SIZE];
171 #pragma location = OEP1_X_BUFFER_ADDRESS
172  __no_init BYTE __data16 pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
174 #pragma location = OEP1_Y_BUFFER_ADDRESS
175  __no_init BYTE __data16 pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
177 #pragma location = IEP1_X_BUFFER_ADDRESS
178  __no_init BYTE __data16 pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
180 #pragma location = IEP1_Y_BUFFER_ADDRESS
181  __no_init BYTE __data16 pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
183 #pragma location = OEP2_X_BUFFER_ADDRESS
184  __no_init BYTE __data16 pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
186 #pragma location = OEP2_Y_BUFFER_ADDRESS
187  __no_init BYTE __data16 pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
189 #pragma location = IEP2_X_BUFFER_ADDRESS
190  __no_init BYTE __data16 pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
192 #pragma location = IEP2_Y_BUFFER_ADDRESS
193  __no_init BYTE __data16 pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
195 #pragma location = OEP3_X_BUFFER_ADDRESS
196 __no_init BYTE __data16 pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
198 #pragma location = OEP3_Y_BUFFER_ADDRESS
199 __no_init BYTE __data16 pbYBufferAddressEp3[EP_MAX_PACKET_SIZE];
201 #pragma location = IEP3_X_BUFFER_ADDRESS
202 __no_init BYTE __data16 pbXBufferAddressEp83[EP_MAX_PACKET_SIZE];
204 #pragma location = IEP3_Y_BUFFER_ADDRESS
205 __no_init BYTE __data16 pbYBufferAddressEp83[EP_MAX_PACKET_SIZE];
207 #pragma location = OEP4_X_BUFFER_ADDRESS
208 __no_init BYTE __data16 pbXBufferAddressEp4[EP_MAX_PACKET_SIZE];
210 #pragma location = OEP4_Y_BUFFER_ADDRESS
211 __no_init BYTE __data16 pbYBufferAddressEp4[EP_MAX_PACKET_SIZE];
213 #pragma location = IEP4_X_BUFFER_ADDRESS
214 __no_init BYTE __data16 pbXBufferAddressEp84[EP_MAX_PACKET_SIZE];
216 #pragma location = IEP4_Y_BUFFER_ADDRESS
217 __no_init BYTE __data16 pbYBufferAddressEp84[EP_MAX_PACKET_SIZE];
219 #pragma location = OEP5_X_BUFFER_ADDRESS
220 __no_init BYTE __data16 pbXBufferAddressEp5[EP_MAX_PACKET_SIZE];
222 #pragma location = OEP5_Y_BUFFER_ADDRESS
223 __no_init BYTE __data16 pbYBufferAddressEp5[EP_MAX_PACKET_SIZE];
225 #pragma location = IEP5_X_BUFFER_ADDRESS
226 __no_init BYTE __data16 pbXBufferAddressEp85[EP_MAX_PACKET_SIZE];
228 #pragma location = IEP5_Y_BUFFER_ADDRESS
229 __no_init BYTE __data16 pbYBufferAddressEp85[EP_MAX_PACKET_SIZE];
231 #pragma location = OEP6_X_BUFFER_ADDRESS
232 __no_init BYTE __data16 pbXBufferAddressEp6[EP_MAX_PACKET_SIZE];
234 #pragma location = OEP6_Y_BUFFER_ADDRESS
235 __no_init BYTE __data16 pbYBufferAddressEp6[EP_MAX_PACKET_SIZE];
237 #pragma location = IEP6_X_BUFFER_ADDRESS
238 __no_init BYTE __data16 pbXBufferAddressEp86[EP_MAX_PACKET_SIZE];
240 #pragma location = IEP6_Y_BUFFER_ADDRESS
241 __no_init BYTE __data16 pbYBufferAddressEp86[EP_MAX_PACKET_SIZE];
243 #pragma location = OEP7_X_BUFFER_ADDRESS
244 __no_init BYTE __data16 pbXBufferAddressEp7[EP_MAX_PACKET_SIZE];
246 #pragma location = OEP7_Y_BUFFER_ADDRESS
247 __no_init BYTE __data16 pbYBufferAddressEp7[EP_MAX_PACKET_SIZE];
249 #pragma location = IEP7_X_BUFFER_ADDRESS
250 __no_init BYTE __data16 pbXBufferAddressEp87[EP_MAX_PACKET_SIZE];
252 #pragma location = IEP7_Y_BUFFER_ADDRESS
253 __no_init BYTE __data16 pbYBufferAddressEp87[EP_MAX_PACKET_SIZE];
257 #endif
259 #ifdef __TI_COMPILER_VERSION__
260 extern __no_init tDEVICE_REQUEST tSetupPacket;
261 extern __no_init tEDB0 tEndPoint0DescriptorBlock;
262 extern __no_init tEDB tInputEndPointDescriptorBlock[7];
263 extern __no_init tEDB tOutputEndPointDescriptorBlock[7];
264 extern __no_init BYTE abIEP0Buffer[EP0_MAX_PACKET_SIZE];
265 extern __no_init BYTE abOEP0Buffer[EP0_MAX_PACKET_SIZE];
266 extern __no_init BYTE pbXBufferAddressEp1[EP_MAX_PACKET_SIZE];
267 extern __no_init BYTE pbYBufferAddressEp1[EP_MAX_PACKET_SIZE];
268 extern __no_init BYTE pbXBufferAddressEp81[EP_MAX_PACKET_SIZE];
269 extern __no_init BYTE pbYBufferAddressEp81[EP_MAX_PACKET_SIZE];
270 extern __no_init BYTE pbXBufferAddressEp2[EP_MAX_PACKET_SIZE];
271 extern __no_init BYTE pbYBufferAddressEp2[EP_MAX_PACKET_SIZE];
272 extern __no_init BYTE pbXBufferAddressEp82[EP_MAX_PACKET_SIZE];
273 extern __no_init BYTE pbYBufferAddressEp82[EP_MAX_PACKET_SIZE];
274 extern __no_init BYTE pbXBufferAddressEp3[EP_MAX_PACKET_SIZE];
275 extern __no_init BYTE pbYBufferAddressEp3[EP_MAX_PACKET_SIZE];
276 extern __no_init BYTE pbXBufferAddressEp83[EP_MAX_PACKET_SIZE];
277 extern __no_init BYTE pbYBufferAddressEp83[EP_MAX_PACKET_SIZE];
279 extern __no_init BYTE pbXBufferAddressEp4[EP_MAX_PACKET_SIZE];
280 extern __no_init BYTE pbYBufferAddressEp4[EP_MAX_PACKET_SIZE];
281 extern __no_init BYTE pbXBufferAddressEp84[EP_MAX_PACKET_SIZE];
282 extern __no_init BYTE pbYBufferAddressEp84[EP_MAX_PACKET_SIZE];
284 extern __no_init BYTE pbXBufferAddressEp5[EP_MAX_PACKET_SIZE];
285 extern __no_init BYTE pbYBufferAddressEp5[EP_MAX_PACKET_SIZE];
286 extern __no_init BYTE pbXBufferAddressEp85[EP_MAX_PACKET_SIZE];
287 extern __no_init BYTE pbYBufferAddressEp85[EP_MAX_PACKET_SIZE];
289 #endif
291 VOID CdcResetData();
292 VOID HidResetData();
294 VOID USB_InitSerialStringDescriptor(VOID);
295 VOID USB_initMemcpy(VOID);
297 //----------------------------------------------------------------------------
298 BYTE USB_init(VOID)
300     WORD bGIE  = __get_SR_register() &GIE;  //save interrupt status
301     // atomic operation - disable interrupts
302     __disable_interrupt();               // Disable global interrupts
304     // configuration of USB module
305     USBKEYPID   =     0x9628;            // set KEY and PID to 0x9628 -> access to configuration registers enabled
307     USBPHYCTL   =     PUSEL;             // use DP and DM as USB terminals (not needed because an external PHY is connected to port 9)
309     USBPWRCTL   =     VUSBEN + SLDOAON; // enable primary and secondary LDO (3.3 and 1.8 V)
310     {
311         volatile unsigned int i;
312         for (i =0; i < USB_MCLK_FREQ/1000*2/10; i++);      // wait some time for LDOs (1ms delay)
313     }
315     USBPWRCTL   =   VUSBEN + SLDOAON + VBONIE;  // enable interrupt VBUSon
316     USBKEYPID   =    0x9600;            // access to configuration registers disabled
318     //reset events mask
319     wUsbEventMask = 0;
321     //init Serial Number
322 #if (USB_STR_INDEX_SERNUM != 0)
323     USB_InitSerialStringDescriptor();
324 #endif
326     // init memcpy() function: DMA or non-DMA
327     USB_initMemcpy();
328 #ifdef _MSC_
329     MscResetCtrlLun();
330 #endif
331     
332     __bis_SR_register(bGIE); //restore interrupt status
333     return kUSB_succeed;
336 //----------------------------------------------------------------------------
337 // This function will be compiled only if
338 #if (USB_STR_INDEX_SERNUM != 0)
339 VOID USB_InitSerialStringDescriptor(VOID)
341     BYTE i,j,hexValue;
342     PBYTE pbSerNum;
343     BYTE bBytes;
345     j=1;                   // we start with second byte, first byte (lenght) will be filled later
346     pbSerNum=0;
347     abramSerialStringDescriptor[j++] = DESC_TYPE_STRING;
349     // TLV access Function Call
350     Get_TLV_Info(TLV_DIERECORD, 0, (uint8_t *)&bBytes, (uint16_t **)&pbSerNum); //The die record used for serial number
351     if (bBytes == 0)    // no serial number available
352     {
353         // use 00 as serial number = no serial number available
354         abramSerialStringDescriptor[0] = 4;      //length
355         abramSerialStringDescriptor[j++] = 0;    // no serial number available
356         abramSerialStringDescriptor[j++] = 0;    // no serial number available
357     }
358     else
359     {
360         for(i=0; (i<bBytes)&&(i<8); i++,pbSerNum++)
361         {
362             hexValue = (*pbSerNum & 0xF0)>> 4;
363             if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
364             else abramSerialStringDescriptor[j++] = (hexValue + 55);
365             abramSerialStringDescriptor[j++] = 0x00;  // needed for UNI-Code
367             hexValue = (*pbSerNum & 0x0F);
368             if(hexValue < 10 ) abramSerialStringDescriptor[j++] = (hexValue + '0');
369             else abramSerialStringDescriptor[j++] = (hexValue + 55);
370             abramSerialStringDescriptor[j++] = 0x00;    // needed for UNI-Code
371         }
372         abramSerialStringDescriptor[0] = i*4 +2;        // calculate the length
373     }
375 #endif
377 //----------------------------------------------------------------------------
379 BYTE USB_enable()
381     volatile unsigned int i;
382     volatile unsigned int j = 0;
384     if (!(USBPWRCTL & USBBGVBV))            // check USB Bandgap and VBUS valid
385     {
386         return kUSB_generalError;
387     }
389     if ((USBCNF & USB_EN) &&
390         (USBPLLCTL & UPLLEN))
391     {
392         return kUSB_succeed;                // exit if PLL is already enalbed
393     }    
394     
395     USBKEYPID = 0x9628;                     // set KEY and PID to 0x9628 -> access to configuration registers enabled
396     XT2_Start(XT2DRIVE_3); 
397     USBPLLDIVB = USB_XT_FREQ;               // Settings desired frequency
399     USBPLLCTL = UPFDEN + UPLLEN;        // Select XT1 as Ref / Select PLL for USB / Discrim. on, enable PLL
400   
401     //Wait some time till PLL is settled
402     do 
403     {
404         USBPLLIR    =     0x0000;           // make sure no interrupts can occur on PLL-module
406 #ifdef __MSP430F6638 
407         //wait 1 ms till enable USB
408         for (i =0; i < USB_MCLK_FREQ/1000*1/10; i++);
409 #else
410         //wait 1/2 ms till enable USB
411         for (i =0; i < USB_MCLK_FREQ/1000* 1/2 /10; i++);
412 #endif
413         
414         if (j++ > 10)
415         {
416             USBKEYPID   =    0x9600;        // access to configuration registers disabled
417             return kUSB_generalError;
418         }
419     }while (USBPLLIR != 0);
420          
421     USBCNF     |=    USB_EN;                // enable USB module
422     USBKEYPID   =    0x9600;                // access to configuration registers disabled
423     return kUSB_succeed;
426 /*
427 Disables the USB module and PLL.
428 */
429 BYTE USB_disable(VOID)
431     USBKEYPID = 0x9628;        // set KEY and PID to 0x9628 -> access to configuration registers enabled
432     USBCNF    = 0;             // disable USB module
433     USBPLLCTL &= ~UPLLEN;      // disable PLL
434     USBKEYPID = 0x9600;        // access to configuration registers disabled
435     bEnumerationStatus = 0x00; // device is not enumerated
436     bFunctionSuspended = FALSE;// device is not suspended
437     return kUSB_succeed;
440 /*
441 Enables/disables various USB events.
442 */
443 BYTE USB_setEnabledEvents(WORD events)
445     wUsbEventMask = events;
446     return kUSB_succeed;
449 /*
450 Returns which events are enabled and which are disabled.
451 */
452 WORD USB_getEnabledEvents()
454     return wUsbEventMask;
457 /*
458 Reset USB-SIE and global variables.
459 */
460 BYTE USB_reset()
462     int i;
463     USBKEYPID = 0x9628;                   // set KEY and PID to 0x9628 -> access to configuration registers enabled
464     
465     //reset should be on the bus after this!
466     bEnumerationStatus = 0x00;            // Device not enumerated yet
467     bFunctionSuspended = FALSE;           // Device is not in suspend mode
468     
469     bRemoteWakeup = DISABLE;
470     
471     bConfigurationNumber    = 0x00;       // device unconfigured
472     bInterfaceNumber        = 0x00;
473     
474     // FRSTE handling:
475     // Clear FRSTE in the RESRIFG interrupt service routine before re-configuring USB control registers.
476     // Set FRSTE at the beginning of SUSRIFG, SETUP, IEPIFG.EP0 and OEPIFG.EP0 interrupt service routines. 
477     USBCTL = 0;                           // Function Reset Connection disable (FRSTE)
478     
479     wBytesRemainingOnIEP0   = NO_MORE_DATA;
480     wBytesRemainingOnOEP0   = NO_MORE_DATA;
481     bStatusAction           = STATUS_ACTION_NOTHING;
482     
483     //The address reset normally will be done automatically during bus function reset
484     USBFUNADR   =     0x00;               // reset address of USB device (unconfigured)
485     
486     /* Set settings for EP0 */
487     // NAK both 0 endpoints and enable endpoint 0 interrupt
488     tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
489     tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
490     tEndPoint0DescriptorBlock.bIEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet
491     tEndPoint0DescriptorBlock.bOEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet
492     
493     USBOEPIE = USB_OUTEP_INT_EN;
494     USBIEPIE = USB_INEP_INT_EN;    
495         
496     // loop for initialization all of used enpoints
497     for(i=0; i < (CDC_NUM_INTERFACES + HID_NUM_INTERFACES + MSC_NUM_INTERFACES); i++)
498     {               
499         BYTE edbIndex = stUsbHandle[i].edb_Index;
501         /* Set settings for IEPx */
502         tInputEndPointDescriptorBlock[edbIndex].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
503         tInputEndPointDescriptorBlock[edbIndex].bEPBBAX  = (BYTE)(((stUsbHandle[i].iep_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
504         tInputEndPointDescriptorBlock[edbIndex].bEPBBAY  = (BYTE)(((stUsbHandle[i].iep_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
505         tInputEndPointDescriptorBlock[edbIndex].bEPBCTX  = EPBCNT_NAK;
506         tInputEndPointDescriptorBlock[edbIndex].bEPBCTY  = EPBCNT_NAK;
507         tInputEndPointDescriptorBlock[edbIndex].bEPSIZXY = MAX_PACKET_SIZE;
508         
509         /* Set settings for OEPx */
510         tOutputEndPointDescriptorBlock[edbIndex].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF ; //double buffering
511         tOutputEndPointDescriptorBlock[edbIndex].bEPBBAX  = (BYTE)(((stUsbHandle[i].oep_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
512         tOutputEndPointDescriptorBlock[edbIndex].bEPBBAY  = (BYTE)(((stUsbHandle[i].oep_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
513         tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX  = 0x00;
514         tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY  = 0x00; 
515         tOutputEndPointDescriptorBlock[edbIndex].bEPSIZXY = MAX_PACKET_SIZE; 
516         
517 #       ifdef _CDC_        
518         /* Additional interrupt end point for CDC */
519         if(stUsbHandle[i].dev_Class == CDC_CLASS)
520         {
521             // The decriptor tool always generates the managemnet endpoint before the data endpoint  
522             tInputEndPointDescriptorBlock[edbIndex-1].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
523             tInputEndPointDescriptorBlock[edbIndex-1].bEPBBAX  = (BYTE)(((stUsbHandle[i].intepEP_X_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
524             tInputEndPointDescriptorBlock[edbIndex-1].bEPBBAY  = (BYTE)(((stUsbHandle[i].intepEP_Y_Buffer - START_OF_USB_BUFFER) >> 3) & 0x00ff);
525             tInputEndPointDescriptorBlock[edbIndex-1].bEPBCTX  = EPBCNT_NAK;
526             tInputEndPointDescriptorBlock[edbIndex-1].bEPBCTY  = EPBCNT_NAK;
527             tInputEndPointDescriptorBlock[edbIndex-1].bEPSIZXY = MAX_PACKET_SIZE;
528         }
529 #       endif        
530     }
531     
532 #   ifdef _HID_
533         HidResetData();                     // reset HID specific data structures
534 #   endif // _HID_
536 #   ifdef _MSC_
537         isMSCConfigured = FALSE;
538         USBMSC_reset();
539         MscResetData();
540 #   endif
542 #   ifdef _CDC_
543         CdcResetData();                     // reset CDC specific data structures
544 #   endif // _CDC_
546     USBCTL = FEN;                       // enable function
547     USBIFG = 0;                         // make sure no interrupts are pending
549     USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)
550     USBKEYPID = 0x9600;                 // access to configuration registers disabled
551     return kUSB_succeed;
554 /*
555 Instruct USB module to make itself available to the PC for connection, by pulling PUR high.
556 */
557 BYTE USB_connect()
559     USBKEYPID = 0x9628;   // set KEY and PID to 0x9628 -> access to configuration registers enabled
560     USBCNF |= PUR_EN;     // generate rising edge on DP -> the host enumerates our device as full speed device
561     USBPWRCTL |= VBOFFIE; // enable interrupt VUSBoff
562     USBKEYPID = 0x9600;   // access to configuration registers disabled
564     // after this the enumeration may take place
565     __no_operation();
566     __no_operation();
567     __no_operation();
568     __no_operation();
569     __no_operation();
570     __no_operation();
571     __no_operation();
573     return kUSB_succeed;
576 /*
577 Force a disconnect from the PC by pulling PUR low.
578 */
579 BYTE USB_disconnect()
581     USBKEYPID = 0x9628;     // set KEY and PID to 0x9628 -> access to configuration registers enabled
582     USBCNF &= ~PUR_EN;      // disconnect pull up resistor - logical disconnect from HOST
583     USBPWRCTL &= ~VBOFFIE;  // disable interrupt VUSBoff
584     USBKEYPID = 0x9600;     // access to configuration registers disabled
585     bEnumerationStatus = 0; // not enumerated
586     bFunctionSuspended = FALSE;     // device is not suspended
587     return kUSB_succeed;
590 /*
591 Force a remote wakeup of the USB host.
592 */
593 BYTE USB_forceRemoteWakeup()
595     if (bFunctionSuspended == FALSE) // device is not suspended
596     {
597         return kUSB_NotSuspended;
598     }
599     if(bRemoteWakeup == ENABLE)
600     {
601         volatile unsigned int i;
602         USBCTL |= RWUP;             // USB - Device Remote Wakeup Request - this bit is self-cleaned
603         return kUSB_succeed;
604     }
605     return kUSB_generalError;
608 /*
609 Returns the status of the USB connection.
610 */
611 BYTE USB_connectionInfo()
613     BYTE retVal = 0;
614     if (USBPWRCTL & USBBGVBV)
615     {
616         retVal |= kUSB_vbusPresent;
617     }
619     if (bEnumerationStatus == ENUMERATION_COMPLETE)
620     {
621         retVal |= kUSB_Enumerated;
622     }
624     if (USBCNF & PUR_EN)
625     {
626         retVal |= kUSB_purHigh;
627     }
629     if (bFunctionSuspended == TRUE)
630     {
631         retVal |= kUSB_suspended;
632     }
633     else
634     {
635         retVal |= kUSB_NotSuspended;
636     }
637     return retVal;
640 /*
641 Returns the state of the USB connection.
642 */
643 BYTE USB_connectionState()
645     // If no VBUS present
646     if (!(USBPWRCTL & USBBGVBV))
647     {
648         return ST_USB_DISCONNECTED;
649     }
651     // If VBUS present, but PUR is low
652     if ((USBPWRCTL & USBBGVBV)&&(!(USBCNF & PUR_EN)))
653     {
654         return ST_USB_CONNECTED_NO_ENUM;
655     }
657     // If VBUS present, PUR is high, and enumeration is complete, and not suspended
658     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
659         && (bEnumerationStatus == ENUMERATION_COMPLETE)
660         && (!(bFunctionSuspended == TRUE)))
661     {
662         return ST_ENUM_ACTIVE;
663     }
665     // If VBUS present, PUR is high, and enumeration is NOT complete, and  suspended
666     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
667         && (!(bEnumerationStatus == ENUMERATION_COMPLETE))
668         && (bFunctionSuspended == TRUE))
669     {
670         return ST_NOENUM_SUSPENDED;
671     }
672         
673     // If VBUS present, PUR is high, and enumeration is complete, and  suspended
674     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
675         && (bEnumerationStatus == ENUMERATION_COMPLETE)
676         && (bFunctionSuspended == TRUE))
677     {
678         return ST_ENUM_SUSPENDED;
679     }
680     
681     // If VBUS present, PUR is high, but no enumeration yet
682     if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN)
683         && (!(bEnumerationStatus == ENUMERATION_COMPLETE)))
684     {
685         return ST_ENUM_IN_PROGRESS;
686     }
687     
688     return ST_ERROR;
691 //----------------------------------------------------------------------------
693 BYTE USB_suspend(VOID)
696     bFunctionSuspended  = TRUE;
697     USBKEYPID = 0x9628;         // set KEY and PID to 0x9628 -> access to configuration registers enabled
698     USBCTL |= FRSTE;            // Function Reset Connection Enable
699     USBIFG &= ~SUSRIFG;         // clear interrupt flag
701     if(USB_DISABLE_XT_SUSPEND)
702     {
703         if (USB_PLL_XT == 2)
704         {
705             USBPLLCTL &= ~UPLLEN;         // disable PLL
706             UCSCTL6   |= XT2OFF;         // disable XT2
707         }
708         else
709         {
710             USBPLLCTL &= ~UPLLEN;           // disable PLL
711             UCSCTL6 |= XT1OFF;
712         }
713     }
715     USBIE = RESRIE;             // disable USB specific interrupts (setup, suspend, reset), enable resume.
716                                 // If the reset occured during device in suspend, the resume-interrupt will come, after - reset interrupt
717     USBKEYPID = 0x9600;         // access to configuration registers disabled
719     return kUSB_succeed;
722 //----------------------------------------------------------------------------
724 BYTE USB_resume(VOID)
726     USB_enable();                       // enable PLL
728     USBIFG &= ~(RESRIFG | SUSRIFG);     // clear interrupt flags
729     USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)
731     bFunctionSuspended  = FALSE;
732     return kUSB_succeed;
735 //----------------------------------------------------------------------------
737 VOID usbStallEndpoint0(VOID)
739     tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
740     tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
743 //----------------------------------------------------------------------------
745 VOID usbClearOEP0ByteCount(VOID)
747     tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
750 //----------------------------------------------------------------------------
752 VOID usbStallOEP0(VOID)
754     // in standard USB request, there is not control write request with data stage
755     // control write, stall output endpoint 0
756     // wLength should be 0 in all cases
757     tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
760 //----------------------------------------------------------------------------
762 VOID usbSendNextPacketOnIEP0(VOID)
764     BYTE bPacketSize,bIndex;
766     // First check if there are bytes remaining to be transferred
767     if(wBytesRemainingOnIEP0 != NO_MORE_DATA)
768     {
769         if(wBytesRemainingOnIEP0 > EP0_PACKET_SIZE)
770         {
771             // More bytes are remaining than will fit in one packet
772             // there will be More IN Stage
773             bPacketSize = EP0_PACKET_SIZE;
774             wBytesRemainingOnIEP0 -= EP0_PACKET_SIZE;
775             bStatusAction = STATUS_ACTION_DATA_IN;
776         }
777         else if (wBytesRemainingOnIEP0 < EP0_PACKET_SIZE)
778         {
779             // The remaining data will fit in one packet.
780             // This case will properly handle wBytesRemainingOnIEP0 == 0
781             bPacketSize = (BYTE)wBytesRemainingOnIEP0;
782             wBytesRemainingOnIEP0 = NO_MORE_DATA;        // No more data need to be Txed
783             bStatusAction = STATUS_ACTION_NOTHING;
784         }
785         else
786         {
787             bPacketSize = EP0_PACKET_SIZE;
788             if(bHostAskMoreDataThanAvailable == TRUE)
789             {
790                 wBytesRemainingOnIEP0 = 0;
791                 bStatusAction = STATUS_ACTION_DATA_IN;
792             }
793             else
794             {
795                 wBytesRemainingOnIEP0 = NO_MORE_DATA;
796                 bStatusAction = STATUS_ACTION_NOTHING;
797             }
798         }
800         for(bIndex=0; bIndex<bPacketSize; bIndex++)
801         {
802             abIEP0Buffer[bIndex] = *pbIEP0Buffer;
803             pbIEP0Buffer++;
804         }
805         tEndPoint0DescriptorBlock.bIEPBCNT = bPacketSize;
806     }
807     else 
808     {
809         bStatusAction = STATUS_ACTION_NOTHING;
810     }
813 //----------------------------------------------------------------------------
815 VOID usbSendDataPacketOnEP0(PBYTE pbBuffer)
817     WORD wTemp;
819     pbIEP0Buffer = pbBuffer;
820     wTemp = tSetupPacket.wLength;
822     // Limit transfer size to wLength if needed
823     // this prevent USB device sending 'more than require' data back to host
824     if(wBytesRemainingOnIEP0 >= wTemp)
825     {
826         wBytesRemainingOnIEP0 = wTemp;
827         bHostAskMoreDataThanAvailable = FALSE;
828     }
829     else 
830     {
831         bHostAskMoreDataThanAvailable = TRUE;
832     }
833     usbSendNextPacketOnIEP0();
836 //----------------------------------------------------------------------------
837 VOID usbReceiveNextPacketOnOEP0(VOID)
839     BYTE bIndex,bByte;
841     bByte = tEndPoint0DescriptorBlock.bOEPBCNT & EPBCNT_BYTECNT_MASK;
843     if(wBytesRemainingOnOEP0 >= (WORD)bByte)
844     {
845         for(bIndex=0;bIndex<bByte;bIndex++)
846         {
847             *pbOEP0Buffer = abOEP0Buffer[bIndex];
848             pbOEP0Buffer++;
849         }
850         wBytesRemainingOnOEP0 -= (WORD)bByte;
852         // clear the NAK bit for next packet
853         if(wBytesRemainingOnOEP0 > 0)
854         {
855             usbClearOEP0ByteCount();
856             bStatusAction = STATUS_ACTION_DATA_OUT;
857         }
858         else
859         {
860             usbStallOEP0();
861             bStatusAction = STATUS_ACTION_NOTHING;
862         }
863     }
864     else
865     {
866         usbStallOEP0();
867         bStatusAction = STATUS_ACTION_NOTHING;
868     }
871 //----------------------------------------------------------------------------
873 VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
876     pbOEP0Buffer = pbBuffer;
878     wBytesRemainingOnOEP0 = tSetupPacket.wLength;
879     bStatusAction = STATUS_ACTION_DATA_OUT;
881     usbClearOEP0ByteCount();
884 //----------------------------------------------------------------------------
886 VOID usbSendZeroLengthPacketOnIEP0(VOID)
888     wBytesRemainingOnIEP0 = NO_MORE_DATA;
889     bStatusAction = STATUS_ACTION_NOTHING;
890     tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
893 //----------------------------------------------------------------------------
895 VOID usbClearEndpointFeature(VOID)
897     BYTE bEndpointNumber;
899     // EP is from EP1 to EP7 while C language start from 0
900     bEndpointNumber = (tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM);
901     if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();
902     else
903     {
904         bEndpointNumber--;   
905         if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
906         {
907             if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN)
908             {
909 #ifdef _MSC_ 
910                 if (!bMscResetRequired) {
911 #endif                  
912                   tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE ); 
913 #ifdef _MSC_                  
914                 }
915 #endif                
916 #               ifdef _MSC_                
917                     if (stUsbHandle[MSC0_INTFNUM].edb_Index == bEndpointNumber)
918                     {
919                         MscReadControl.bCurrentBufferXY = 0; //Set current buffer to X
920                         bMcsCommandSupported = TRUE;
921                     }
922 #               endif
923             }
924             else
925             {
926 #ifdef _MSC_    
927                 if (!bMscResetRequired) {
928 #endif              
929                     tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF &= ~(EPCNF_STALL | EPCNF_TOGGLE );
930 #ifdef _MSC_                  
931                 }
932 #endif 
933 #               ifdef _MSC_                                
934                     if (stUsbHandle[MSC0_INTFNUM].edb_Index == bEndpointNumber)
935                     {    
936                         MscWriteControl.bCurrentBufferXY = 0; //Set current buffer to X
937                         bMcsCommandSupported = TRUE;
938                     }
939 #               endif                
940             }
941             usbSendZeroLengthPacketOnIEP0();
942         }
943     }
946 //----------------------------------------------------------------------------
948 VOID usbGetConfiguration(VOID)
950     usbClearOEP0ByteCount();                    // for status stage
951     wBytesRemainingOnIEP0 = 1;
952     usbSendDataPacketOnEP0((PBYTE)&bConfigurationNumber);
955 //----------------------------------------------------------------------------
957 VOID usbGetDeviceDescriptor(VOID)
959     usbClearOEP0ByteCount();
960     wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
961     usbSendDataPacketOnEP0((PBYTE) &abromDeviceDescriptor);
964 //----------------------------------------------------------------------------
966 VOID usbGetConfigurationDescriptor(VOID)
968     usbClearOEP0ByteCount();
969     wBytesRemainingOnIEP0 = sizeof(abromConfigurationDescriptorGroup);
970     usbSendDataPacketOnEP0((PBYTE)&abromConfigurationDescriptorGroup);
973 //----------------------------------------------------------------------------
975 VOID usbGetStringDescriptor(VOID)
977     WORD bIndex;
978     BYTE bVal = (BYTE)tSetupPacket.wValue;
980     usbClearOEP0ByteCount();                    // for status stage
981 #if (USB_STR_INDEX_SERNUM != 0)
983     if(bVal == 0x03)
984     {
985         wBytesRemainingOnIEP0 = abramSerialStringDescriptor[0];
986         usbSendDataPacketOnEP0((PBYTE)&abramSerialStringDescriptor);
987     }
988     else
989 #endif
990     {
991         bIndex = 0x00;
992         while(bVal-- >  0x00) bIndex += abromStringDescriptor[bIndex];
993         wBytesRemainingOnIEP0 = abromStringDescriptor[bIndex];
994         usbSendDataPacketOnEP0((PBYTE)&abromStringDescriptor[bIndex]);
995     }
998 //----------------------------------------------------------------------------
1000 VOID usbGetInterface(VOID)
1003     // not fully supported, return one byte, zero
1004     usbClearOEP0ByteCount();                    // for status stage
1005     wBytesRemainingOnIEP0 = 0x02;
1006     abUsbRequestReturnData[0] = 0x00;           // changed to report alternative setting byte
1007     abUsbRequestReturnData[1] = bInterfaceNumber;
1008     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
1011 //----------------------------------------------------------------------------
1013 VOID usbGetDeviceStatus(VOID)
1015     if((abromConfigurationDescriptorGroup.abromConfigurationDescriptorGenric.mattributes &
1016         CFG_DESC_ATTR_SELF_POWERED) == CFG_DESC_ATTR_SELF_POWERED)
1017     {
1018         abUsbRequestReturnData[0] = DEVICE_STATUS_SELF_POWER;
1019     }
1020     if(bRemoteWakeup == ENABLE)
1021     {
1022         abUsbRequestReturnData[0] |= DEVICE_STATUS_REMOTE_WAKEUP;
1023     }
1024     usbClearOEP0ByteCount();                    // for status stage
1026     // Return self power status and remote wakeup status
1027     wBytesRemainingOnIEP0 = 2;
1028     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
1031 //----------------------------------------------------------------------------
1033 VOID usbGetInterfaceStatus(VOID)
1035     // check bIndexL for index number (not supported)
1036     usbClearOEP0ByteCount();                    // for status stage
1038     // Return two zero bytes
1039     wBytesRemainingOnIEP0 = 2;
1040     abUsbRequestReturnData[0] = 0x00;           // changed to support multiple interfaces
1041     abUsbRequestReturnData[1] = bInterfaceNumber;
1042     usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
1045 //----------------------------------------------------------------------------
1047 VOID usbGetEndpointStatus(VOID)
1049     BYTE bEndpointNumber;
1051     // Endpoint number is bIndexL
1052     bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
1053     if(bEndpointNumber == 0x00)
1054     {
1055         if((tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN) == EP_DESC_ADDR_DIR_IN)
1056         {
1057             // input endpoint 0
1058             abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bIEPCNFG & EPCNF_STALL);
1059         }
1060         else
1061         {
1062             // output endpoint 0
1063             abUsbRequestReturnData[0] = (BYTE)(tEndPoint0DescriptorBlock.bOEPCNFG & EPCNF_STALL);
1064         }
1065         abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
1066         usbClearOEP0ByteCount();                    // for status stage
1067         wBytesRemainingOnIEP0 = 0x02;
1068         usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
1069     }
1070     else
1071     {
1072         bEndpointNumber--;
1073         // EP is from EP1 to EP7 while C language start from 0
1074         // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
1075         if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
1076         {
1077             if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN)
1078             {
1079                 // input endpoint
1080                 abUsbRequestReturnData[0] = (BYTE)(tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
1081             }else
1082             {
1083                 // output endpoint
1084                 abUsbRequestReturnData[0] = (BYTE)(tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF & EPCNF_STALL);
1085             }
1086         }   // no response if endpoint is not supported.
1087         abUsbRequestReturnData[0] = abUsbRequestReturnData[0] >> 3; // STALL is on bit 3
1088         usbClearOEP0ByteCount();
1089         wBytesRemainingOnIEP0 = 0x02;
1090         usbSendDataPacketOnEP0((PBYTE)&abUsbRequestReturnData[0]);
1091     }
1094 //----------------------------------------------------------------------------
1095 VOID usbSetAddress(VOID)
1097     usbStallOEP0();                             // control write without data stage
1099     // bValueL contains device address
1100     if(tSetupPacket.wValue < 128)
1101     {
1102         // hardware will update the address after status stage
1103         // therefore, firmware can set the address now.
1104         USBFUNADR = tSetupPacket.wValue;
1105         usbSendZeroLengthPacketOnIEP0();
1106     }
1107     else 
1108     {
1109         usbStallEndpoint0();
1110     }
1113 //----------------------------------------------------------------------------
1115 VOID usbSetConfiguration(VOID)
1117     usbStallOEP0();                             // control write without data stage
1119     // configuration number is in bValueL
1120     // change the code if more than one configuration is supported
1121     bConfigurationNumber = tSetupPacket.wValue;
1122     usbSendZeroLengthPacketOnIEP0();
1124     if (bConfigurationNumber == 1)
1125     {
1126         bEnumerationStatus = ENUMERATION_COMPLETE;      // set device as enumerated
1127     }
1128     else
1129     {
1130         bEnumerationStatus = 0; //device is not configured == config # is zero
1131     }
1134 //----------------------------------------------------------------------------
1136 VOID usbClearDeviceFeature(VOID)
1138     // bValueL contains feature selector
1139     if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP)
1140     {
1141         bRemoteWakeup = DISABLE;
1142         usbSendZeroLengthPacketOnIEP0();
1143     }
1144     else 
1145     {
1146         usbStallEndpoint0();
1147     }
1150 //----------------------------------------------------------------------------
1152 VOID usbSetDeviceFeature(VOID)
1154     // bValueL contains feature selector
1155     if(tSetupPacket.wValue == FEATURE_REMOTE_WAKEUP)
1156     {
1157         bRemoteWakeup = ENABLE;
1158         usbSendZeroLengthPacketOnIEP0();
1159     }
1160     else 
1161     {
1162         usbStallEndpoint0();
1163     }
1166 //----------------------------------------------------------------------------
1168 VOID usbSetEndpointFeature(VOID)
1170     BYTE bEndpointNumber;
1172     // wValue contains feature selector
1173     // bIndexL contains endpoint number
1174     // Endpoint number is in low byte of wIndex
1175     if(tSetupPacket.wValue == FEATURE_ENDPOINT_STALL)
1176     {
1177         bEndpointNumber = tSetupPacket.wIndex & EP_DESC_ADDR_EP_NUM;
1178         if(bEndpointNumber == 0x00) usbSendZeroLengthPacketOnIEP0();  // do nothing for endpoint 0
1179         else
1180         {
1181             bEndpointNumber--;
1182             // Firmware should NOT response if specified endpoint is not supported. (charpter 8)
1183             if(bEndpointNumber < MAX_ENDPOINT_NUMBER)
1184             {
1185                 if(tSetupPacket.wIndex & EP_DESC_ADDR_DIR_IN)
1186                 {
1187                     // input endpoint
1188                     tInputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
1189                 }
1190                 else
1191                 {
1192                     // output endpoint
1193                     tOutputEndPointDescriptorBlock[bEndpointNumber].bEPCNF |= EPCNF_STALL;
1194                 }
1195                 usbSendZeroLengthPacketOnIEP0();
1196             } // no response if endpoint is not supported.
1197         }
1198     }
1199     else 
1200     {
1201         usbStallEndpoint0();
1202     }
1205 //----------------------------------------------------------------------------
1207 VOID usbSetInterface(VOID)
1209     // bValueL contains alternative setting
1210     // bIndexL contains interface number
1211     // change code if more than one interface is supported
1212     usbStallOEP0();                             // control write without data stage
1213     bInterfaceNumber = tSetupPacket.wIndex;
1214 #ifdef _MSC_
1215     tInputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF &= ~(EPCNF_TOGGLE);
1216     tOutputEndPointDescriptorBlock[stUsbHandle[MSC0_INTFNUM].edb_Index].bEPCNF &= ~(EPCNF_TOGGLE);
1217     MscReadControl.bCurrentBufferXY = 0; //Set current buffer to X
1218     MscWriteControl.bCurrentBufferXY = 0; //Set current buffer to X
1219 #endif
1220     usbSendZeroLengthPacketOnIEP0();
1223 //----------------------------------------------------------------------------
1225 VOID usbInvalidRequest(VOID)
1227     // check if setup overwrite is set
1228     // if set, do nothing since we might decode it wrong
1229     // setup packet buffer could be modified by hardware if another setup packet
1230     // was sent while we are deocding setup packet
1231     if ((USBIFG & STPOWIFG) == 0x00)
1232     {
1233       usbStallEndpoint0();
1234     }
1237 typedef VOID (*tpF)(VOID);
1239 BYTE usbDecodeAndProcessUsbRequest(VOID)
1241     BYTE  bMask,bResult,bTemp;
1242     const BYTE* pbUsbRequestList;
1243     BYTE bWakeUp = FALSE;
1244     ptDEVICE_REQUEST ptSetupPacket = &tSetupPacket;
1245     BYTE  bRequestType,bRequest;
1246     tpF lAddrOfFunction;
1248     // point to beginning of the matrix
1249     pbUsbRequestList = (PBYTE)&tUsbRequestList[0];
1251     while(1)
1252     {
1253         bRequestType = *pbUsbRequestList++;
1254         bRequest     = *pbUsbRequestList++;
1256         if(((bRequestType == 0xff) && (bRequest == 0xff)) ||
1257             (tSetupPacket.bmRequestType == (USB_REQ_TYPE_INPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) ||
1258             (tSetupPacket.bmRequestType == (USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)))
1259         {
1260             pbUsbRequestList -= 2;
1261             break;
1262         }
1264         if((bRequestType == tSetupPacket.bmRequestType) && (bRequest == tSetupPacket.bRequest))
1265         {
1266             // compare the first two
1267             bResult = 0xc0;
1268             bMask   = 0x20;
1269             // first two bytes matched, compare the rest
1270             for(bTemp = 2; bTemp < 8; bTemp++)
1271             {
1272                 if (*((BYTE*)ptSetupPacket + bTemp) == *pbUsbRequestList)
1273                 {
1274                     bResult |= bMask;
1275                 }
1276                 pbUsbRequestList++;
1277                 bMask = bMask >> 1;
1278             }
1279             // now we have the result
1280             if((*pbUsbRequestList & bResult) == *pbUsbRequestList)
1281             {
1282                 pbUsbRequestList -= 8;
1283                 break;
1284             }
1285             else
1286             {
1287                 pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-8);
1288             }
1289         }
1290         else
1291         {
1292             pbUsbRequestList += (sizeof(tDEVICE_REQUEST_COMPARE)-2);
1293         }
1294     }
1296     // if another setup packet comes before we have the chance to process current
1297     // setup request, we return here without processing the request
1298     // this check is not necessary but still kept here to reduce response(or simulation) time
1300     if((USBIFG & STPOWIFG) != 0x00)
1301     {
1302         return bWakeUp;
1303     }
1305     // now we found the match and jump to the function accordingly.
1306     lAddrOfFunction = ((tDEVICE_REQUEST_COMPARE*)pbUsbRequestList)->pUsbFunction;
1308     // call function
1309     (*lAddrOfFunction)();
1310     
1311     // perform enumeration complete event:
1312     // when SetAddress was called and USBADDR is not zero
1313     if ((lAddrOfFunction == &usbSetAddress) && (USBFUNADR != 0))
1314     {
1315         bWakeUp = USB_handleEnumCompleteEvent();
1316     }
1317     return bWakeUp;
1320 /*----------------------------------------------------------------------------+
1321 | End of source file                                                          |
1322 +----------------------------------------------------------------------------*/
1323 /*------------------------ Nothing Below This Line --------------------------*/