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)
299 {
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
332 __bis_SR_register(bGIE); //restore interrupt status
333 return kUSB_succeed;
334 }
336 //----------------------------------------------------------------------------
337 // This function will be compiled only if
338 #if (USB_STR_INDEX_SERNUM != 0)
339 VOID USB_InitSerialStringDescriptor(VOID)
340 {
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 }
374 }
375 #endif
377 //----------------------------------------------------------------------------
379 BYTE USB_enable()
380 {
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 }
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
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
414 if (j++ > 10)
415 {
416 USBKEYPID = 0x9600; // access to configuration registers disabled
417 return kUSB_generalError;
418 }
419 }while (USBPLLIR != 0);
421 USBCNF |= USB_EN; // enable USB module
422 USBKEYPID = 0x9600; // access to configuration registers disabled
423 return kUSB_succeed;
424 }
426 /*
427 Disables the USB module and PLL.
428 */
429 BYTE USB_disable(VOID)
430 {
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;
438 }
440 /*
441 Enables/disables various USB events.
442 */
443 BYTE USB_setEnabledEvents(WORD events)
444 {
445 wUsbEventMask = events;
446 return kUSB_succeed;
447 }
449 /*
450 Returns which events are enabled and which are disabled.
451 */
452 WORD USB_getEnabledEvents()
453 {
454 return wUsbEventMask;
455 }
457 /*
458 Reset USB-SIE and global variables.
459 */
460 BYTE USB_reset()
461 {
462 int i;
463 USBKEYPID = 0x9628; // set KEY and PID to 0x9628 -> access to configuration registers enabled
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
469 bRemoteWakeup = DISABLE;
471 bConfigurationNumber = 0x00; // device unconfigured
472 bInterfaceNumber = 0x00;
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)
479 wBytesRemainingOnIEP0 = NO_MORE_DATA;
480 wBytesRemainingOnOEP0 = NO_MORE_DATA;
481 bStatusAction = STATUS_ACTION_NOTHING;
483 //The address reset normally will be done automatically during bus function reset
484 USBFUNADR = 0x00; // reset address of USB device (unconfigured)
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
493 USBOEPIE = USB_OUTEP_INT_EN;
494 USBIEPIE = USB_INEP_INT_EN;
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;
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;
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 }
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;
552 }
554 /*
555 Instruct USB module to make itself available to the PC for connection, by pulling PUR high.
556 */
557 BYTE USB_connect()
558 {
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;
574 }
576 /*
577 Force a disconnect from the PC by pulling PUR low.
578 */
579 BYTE USB_disconnect()
580 {
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;
588 }
590 /*
591 Force a remote wakeup of the USB host.
592 */
593 BYTE USB_forceRemoteWakeup()
594 {
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;
606 }
608 /*
609 Returns the status of the USB connection.
610 */
611 BYTE USB_connectionInfo()
612 {
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;
638 }
640 /*
641 Returns the state of the USB connection.
642 */
643 BYTE USB_connectionState()
644 {
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 }
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 }
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 }
688 return ST_ERROR;
689 }
691 //----------------------------------------------------------------------------
693 BYTE USB_suspend(VOID)
694 {
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;
720 }
722 //----------------------------------------------------------------------------
724 BYTE USB_resume(VOID)
725 {
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;
733 }
735 //----------------------------------------------------------------------------
737 VOID usbStallEndpoint0(VOID)
738 {
739 tEndPoint0DescriptorBlock.bIEPCNFG |= EPCNF_STALL;
740 tEndPoint0DescriptorBlock.bOEPCNFG |= EPCNF_STALL;
741 }
743 //----------------------------------------------------------------------------
745 VOID usbClearOEP0ByteCount(VOID)
746 {
747 tEndPoint0DescriptorBlock.bOEPBCNT = 0x00;
748 }
750 //----------------------------------------------------------------------------
752 VOID usbStallOEP0(VOID)
753 {
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;
758 }
760 //----------------------------------------------------------------------------
762 VOID usbSendNextPacketOnIEP0(VOID)
763 {
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 }
811 }
813 //----------------------------------------------------------------------------
815 VOID usbSendDataPacketOnEP0(PBYTE pbBuffer)
816 {
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();
834 }
836 //----------------------------------------------------------------------------
837 VOID usbReceiveNextPacketOnOEP0(VOID)
838 {
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 }
869 }
871 //----------------------------------------------------------------------------
873 VOID usbReceiveDataPacketOnEP0(PBYTE pbBuffer)
874 {
876 pbOEP0Buffer = pbBuffer;
878 wBytesRemainingOnOEP0 = tSetupPacket.wLength;
879 bStatusAction = STATUS_ACTION_DATA_OUT;
881 usbClearOEP0ByteCount();
882 }
884 //----------------------------------------------------------------------------
886 VOID usbSendZeroLengthPacketOnIEP0(VOID)
887 {
888 wBytesRemainingOnIEP0 = NO_MORE_DATA;
889 bStatusAction = STATUS_ACTION_NOTHING;
890 tEndPoint0DescriptorBlock.bIEPBCNT = 0x00;
891 }
893 //----------------------------------------------------------------------------
895 VOID usbClearEndpointFeature(VOID)
896 {
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 }
944 }
946 //----------------------------------------------------------------------------
948 VOID usbGetConfiguration(VOID)
949 {
950 usbClearOEP0ByteCount(); // for status stage
951 wBytesRemainingOnIEP0 = 1;
952 usbSendDataPacketOnEP0((PBYTE)&bConfigurationNumber);
953 }
955 //----------------------------------------------------------------------------
957 VOID usbGetDeviceDescriptor(VOID)
958 {
959 usbClearOEP0ByteCount();
960 wBytesRemainingOnIEP0 = SIZEOF_DEVICE_DESCRIPTOR;
961 usbSendDataPacketOnEP0((PBYTE) &abromDeviceDescriptor);
962 }
964 //----------------------------------------------------------------------------
966 VOID usbGetConfigurationDescriptor(VOID)
967 {
968 usbClearOEP0ByteCount();
969 wBytesRemainingOnIEP0 = sizeof(abromConfigurationDescriptorGroup);
970 usbSendDataPacketOnEP0((PBYTE)&abromConfigurationDescriptorGroup);
971 }
973 //----------------------------------------------------------------------------
975 VOID usbGetStringDescriptor(VOID)
976 {
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 }
996 }
998 //----------------------------------------------------------------------------
1000 VOID usbGetInterface(VOID)
1001 {
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]);
1009 }
1011 //----------------------------------------------------------------------------
1013 VOID usbGetDeviceStatus(VOID)
1014 {
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]);
1029 }
1031 //----------------------------------------------------------------------------
1033 VOID usbGetInterfaceStatus(VOID)
1034 {
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]);
1043 }
1045 //----------------------------------------------------------------------------
1047 VOID usbGetEndpointStatus(VOID)
1048 {
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 }
1092 }
1094 //----------------------------------------------------------------------------
1095 VOID usbSetAddress(VOID)
1096 {
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 }
1111 }
1113 //----------------------------------------------------------------------------
1115 VOID usbSetConfiguration(VOID)
1116 {
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 }
1132 }
1134 //----------------------------------------------------------------------------
1136 VOID usbClearDeviceFeature(VOID)
1137 {
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 }
1148 }
1150 //----------------------------------------------------------------------------
1152 VOID usbSetDeviceFeature(VOID)
1153 {
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 }
1164 }
1166 //----------------------------------------------------------------------------
1168 VOID usbSetEndpointFeature(VOID)
1169 {
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 }
1203 }
1205 //----------------------------------------------------------------------------
1207 VOID usbSetInterface(VOID)
1208 {
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();
1221 }
1223 //----------------------------------------------------------------------------
1225 VOID usbInvalidRequest(VOID)
1226 {
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 }
1235 }
1237 typedef VOID (*tpF)(VOID);
1239 BYTE usbDecodeAndProcessUsbRequest(VOID)
1240 {
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)();
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;
1318 }
1320 /*----------------------------------------------------------------------------+
1321 | End of source file |
1322 +----------------------------------------------------------------------------*/
1323 /*------------------------ Nothing Below This Line --------------------------*/