LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Endpoint_LPC18xx.c
Go to the documentation of this file.
1 /*
2  * @brief USB Endpoint definitions for the LPC18xx microcontrollers
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #define __INCLUDE_FROM_USB_DRIVER
33 #include "../../../USBMode.h"
34 
35 #if (defined(__LPC18XX__) || defined(__LPC43XX__)) && defined(USB_CAN_BE_DEVICE)
36 #include "../../../Endpoint.h"
37 #include <string.h>
38 
39 #if defined(USB_DEVICE_ROM_DRIVER)
41 uint8_t usb_RomDriver_buffer[ROMDRIVER_MEM_SIZE] ATTR_ALIGNED(2048) __DATA(USBRAM_SECTION);
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
45 uint8_t usb_RomDriver_CDC_buffer[ROMDRIVER_CDC_MEM_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
48 uint8_t UsbdCdc_EPIN_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
51 uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4) __DATA(USBRAM_SECTION);
54 
55 #endif
56 
57 #define STREAM_TDs 16
58 
60 volatile DeviceQueueHead dQueueHead[USED_PHYSICAL_ENDPOINTS] ATTR_ALIGNED(2048) __DATA(USBRAM_SECTION);
62 DeviceTransferDescriptor dTransferDescriptor[USED_PHYSICAL_ENDPOINTS] ATTR_ALIGNED(32) __DATA(USBRAM_SECTION);
64 DeviceTransferDescriptor dStreamTD[STREAM_TDs] ATTR_ALIGNED(32) __DATA(USBRAM_SECTION);
66 uint8_t iso_buffer[512] ATTR_ALIGNED(4);
67 
68 PRAGMA_WEAK(CALLBACK_HAL_GetISOBufferAddress, Dummy_EPGetISOAddress)
69 uint32_t CALLBACK_HAL_GetISOBufferAddress(const uint32_t EPNum, uint32_t *last_packet_size) ATTR_WEAK ATTR_ALIAS(
70  Dummy_EPGetISOAddress);
71 
72 /* Device transfer completed event
73  * Event is required for using the device stack with any RTOS
74  */
75 PRAGMA_WEAK(EVENT_USB_Device_TransferComplete,Dummy_EVENT_USB_Device_TransferComplete)
76 void EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in) ATTR_WEAK ATTR_ALIAS(Dummy_EVENT_USB_Device_TransferComplete);
77 
78 void DcdInsertTD(uint32_t head, uint32_t newtd);
79 
80 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC);
81 
82 uint32_t stream_buffer_address, stream_dummy_buffer_address, stream_remain_packets,
83  stream_dummy_packets, stream_packet_size, stream_total_packets;
84 
85 void HAL_Reset(void)
86 {
87  uint32_t i;
88 
89  /* disable all EPs */
90  USB_REG(USBPortNum)->ENDPTCTRL[0] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
91  USB_REG(USBPortNum)->ENDPTCTRL[1] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
92  USB_REG(USBPortNum)->ENDPTCTRL[2] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
93  USB_REG(USBPortNum)->ENDPTCTRL[3] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
94  if (USB_REG(USBPortNum) == LPC_USB0) {
95  USB_REG(USBPortNum)->ENDPTCTRL[4] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
96  USB_REG(USBPortNum)->ENDPTCTRL[5] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
97  }
98 
99  /* Clear all pending interrupts */
100  USB_REG(USBPortNum)->ENDPTNAK = 0xFFFFFFFF;
101  USB_REG(USBPortNum)->ENDPTNAKEN = 0;
102  USB_REG(USBPortNum)->USBSTS_D = 0xFFFFFFFF;
103  USB_REG(USBPortNum)->ENDPTSETUPSTAT = USB_REG(USBPortNum)->ENDPTSETUPSTAT;
104  USB_REG(USBPortNum)->ENDPTCOMPLETE = USB_REG(USBPortNum)->ENDPTCOMPLETE;
105  while (USB_REG(USBPortNum)->ENDPTPRIME) ; /* Wait until all bits are 0 */
106  USB_REG(USBPortNum)->ENDPTFLUSH = 0xFFFFFFFF;
107  while (USB_REG(USBPortNum)->ENDPTFLUSH) ; /* Wait until all bits are 0 */
108 
109  /* Set the interrupt Threshold control interval to 0 */
110  USB_REG(USBPortNum)->USBCMD_D &= ~0x00FF0000;
111 
112  /* Configure the Endpoint List Address */
113  /* make sure it in on 64 byte boundary !!! */
114  /* init list address */
115  USB_REG(USBPortNum)->ENDPOINTLISTADDR = (uint32_t) dQueueHead;
116 
117  /* Enable interrupts: USB interrupt, error, port change, reset, suspend, NAK interrupt */
118  USB_REG(USBPortNum)->USBINTR_D = USBINTR_D_UsbIntEnable | USBINTR_D_UsbErrorIntEnable |
119  USBINTR_D_PortChangeIntEnable | USBINTR_D_UsbResetEnable |
120  USBINTR_D_SuspendEnable | USBINTR_D_NAKEnable | USBINTR_D_SofReceivedEnable;
121 
122  USB_Device_SetDeviceAddress(0);
123 
124  endpointselected = 0;
125  for (i = 0; i < ENDPOINT_TOTAL_ENDPOINTS; i++)
126  endpointhandle[i] = 0;
127 
130 
133 
134  // usb_data_buffer_IN_size = 0;
136  stream_total_packets = 0;
137 }
138 
139 bool Endpoint_ConfigureEndpoint(const uint8_t Number, const uint8_t Type,
140  const uint8_t Direction, const uint16_t Size, const uint8_t Banks)
141 {
142  uint8_t *ISO_Address;
143  uint32_t PhyEP = 2 * Number + (Direction == ENDPOINT_DIR_OUT ? 0 : 1);
144  uint32_t EndPtCtrl = ENDPTCTRL_REG(Number);
145 
146  memset((void *) &dQueueHead[PhyEP], 0, sizeof(DeviceQueueHead) );
147 
148  dQueueHead[PhyEP].MaxPacketSize = Size & 0x3ff;
149  dQueueHead[PhyEP].IntOnSetup = 1;
150  dQueueHead[PhyEP].ZeroLengthTermination = 1;
151  dQueueHead[PhyEP].overlay.NextTD = LINK_TERMINATE;
152 
153  if (Direction == ENDPOINT_DIR_OUT) {
154  EndPtCtrl &= ~0x0000FFFF;
155  EndPtCtrl |= ((Type << 2) & ENDPTCTRL_RxType) | ENDPTCTRL_RxEnable | ENDPTCTRL_RxToggleReset;
156  if (Type == EP_TYPE_ISOCHRONOUS) {
157  uint32_t size = 0;
158  ENDPTCTRL_REG(Number) = (Type << 2); // TODO dummy to let DcdDataTransfer() knows iso transfer
159  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
160  DcdDataTransfer(PhyEP, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
161  }
162  else {
163  USB_REG(USBPortNum)->ENDPTNAKEN |= (1 << EP_Physical2BitPosition(PhyEP));
164  }
165  }
166  else { /* ENDPOINT_DIR_IN */
167  EndPtCtrl &= ~0xFFFF0000;
168  EndPtCtrl |= ((Type << 18) & ENDPTCTRL_TxType) | ENDPTCTRL_TxEnable | ENDPTCTRL_TxToggleReset;
169  if (Type == EP_TYPE_ISOCHRONOUS) {
170  uint32_t size = 0;
171  ENDPTCTRL_REG(Number) = (Type << 18); // TODO dummy to let DcdDataTransfer() knows iso transfer
172  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
173  DcdDataTransfer(PhyEP, ISO_Address, size);
174  }
175  }
176  ENDPTCTRL_REG(Number) = EndPtCtrl;
177 
178  endpointhandle[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;
179  return true;
180 }
181 
182 void Endpoint_Streaming(uint8_t *buffer, uint16_t packetsize,
183  uint16_t totalpackets, uint16_t dummypackets)
184 {
185  uint8_t PhyEP = endpointhandle[endpointselected];
186  uint16_t i;
187 #if 0
188  for (i = 0; i < totalpackets; i++) {
189  DcdDataTransfer(PhyEP, (uint8_t *) (buffer + i * packetsize), packetsize);
190  while (!(
191  (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
192  && (dQueueHead[PhyEP].overlay.Active == 0)
193  )
194  ) ;
195  }
196  for (i = 0; i < dummypackets; i++) {
197  DcdDataTransfer(PhyEP, buffer, packetsize);
198  while (!(
199  (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
200  && (dQueueHead[PhyEP].overlay.Active == 0)
201  )
202  ) ;
203  }
204 #else
205  uint16_t cnt = 0;
206  dummypackets = dummypackets;
207  while ( USB_REG(USBPortNum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
208  }
209 
210  for (i = 0; i < totalpackets; i++) {
211  uint8_t ioc;
212  if (i == STREAM_TDs) {
213  break;
214  }
215  if ((i == totalpackets - 1) || (i == STREAM_TDs - 1)) {
216  ioc = 1;
217  }
218  else {
219  ioc = 0;
220  }
221 
222  DcdPrepareTD(&dStreamTD[i], (uint8_t *) (buffer + i * packetsize), packetsize, ioc);
223  if (i > 0) {
224  DcdInsertTD((uint32_t) dStreamTD, (uint32_t) &dStreamTD[i]);
225  }
226  cnt++;
227  }
228 
229  if (STREAM_TDs < totalpackets) {
230  stream_remain_packets = totalpackets - STREAM_TDs;
231  stream_buffer_address = (uint32_t) buffer + STREAM_TDs * packetsize;
232  stream_packet_size = packetsize;
233  }
234  else {
235  stream_remain_packets = stream_buffer_address = stream_packet_size = 0;
236  }
237  stream_total_packets = totalpackets;
238 
239  dQueueHead[PhyEP].overlay.Halted = 0; /* this should be in USBInt */
240  dQueueHead[PhyEP].overlay.Active = 0; /* this should be in USBInt */
241  dQueueHead[PhyEP].overlay.NextTD = (uint32_t) dStreamTD;
242  dQueueHead[PhyEP].TransferCount = totalpackets * packetsize;
243  dQueueHead[PhyEP].IsOutReceived = 0;
244 
245  USB_REG(USBPortNum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
246 #endif
247 }
248 
249 void DcdInsertTD(uint32_t head, uint32_t newtd)
250 {
251  DeviceTransferDescriptor *pTD = (DeviceTransferDescriptor *) head;
252  while (!(pTD->NextTD & LINK_TERMINATE)) pTD = (DeviceTransferDescriptor *) pTD->NextTD;
253  pTD->NextTD = newtd;
254 }
255 
256 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC)
257 {
258  /* Zero out the device transfer descriptors */
259  memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
260 
261  pDTD->NextTD = LINK_TERMINATE;
262  pDTD->TotalBytes = length;
263  pDTD->IntOnComplete = IOC;
264  pDTD->Active = 1;
265  pDTD->BufferPage[0] = (uint32_t) pData;
266  pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
267  // pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
268  // pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
269  // pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
270 }
271 
272 void DcdDataTransfer(uint8_t PhyEP, uint8_t *pData, uint32_t length)
273 {
274  DeviceTransferDescriptor *pDTD = (DeviceTransferDescriptor *) &dTransferDescriptor[PhyEP];
275 
276  while ( USB_REG(USBPortNum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
277  }
278 
279  /* Zero out the device transfer descriptors */
280  memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
281 
282  if (((ENDPTCTRL_REG(PhyEP / 2) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
283  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
284  pDTD->NextTD = LINK_TERMINATE;
285  dQueueHead[PhyEP].Mult = mult;
286  }
287  else if (((ENDPTCTRL_REG(PhyEP / 2) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) {// iso in endpoint
288  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
289  pDTD->NextTD = LINK_TERMINATE;
290  dQueueHead[PhyEP].Mult = mult;
291  }
292  else { // other endpoint types
293  pDTD->NextTD = LINK_TERMINATE; /* The next DTD pointer is INVALID */
294  }
295  pDTD->TotalBytes = length;
296  pDTD->IntOnComplete = 1;
297  pDTD->Active = 1;
298 
299  pDTD->BufferPage[0] = (uint32_t) pData;
300  pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
301  pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
302  pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
303  pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
304 
305  dQueueHead[PhyEP].overlay.Halted = 0; /* this should be in USBInt */
306  dQueueHead[PhyEP].overlay.Active = 0; /* this should be in USBInt */
307  dQueueHead[PhyEP].overlay.NextTD = (uint32_t) &dTransferDescriptor[PhyEP];
308  dQueueHead[PhyEP].TransferCount = length;
309 
310  /* prime the endpoint for transmit */
311  USB_REG(USBPortNum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
312 }
313 
314 void TransferCompleteISR(void)
315 {
316  uint8_t *ISO_Address;
317  uint32_t ENDPTCOMPLETE = USB_REG(USBPortNum)->ENDPTCOMPLETE;
318  USB_REG(USBPortNum)->ENDPTCOMPLETE = ENDPTCOMPLETE;
319 
320  if (ENDPTCOMPLETE) {
321  uint8_t n;
322  for (n = 0; n < USED_PHYSICAL_ENDPOINTS / 2; n++) { /* LOGICAL */
323  if ( ENDPTCOMPLETE & _BIT(n) ) {/* OUT */
324  if (((ENDPTCTRL_REG(n) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
325  uint32_t size = dQueueHead[2 * n].TransferCount;
326  size -= dQueueHead[2 * n].overlay.TotalBytes;
327  // copy to share buffer
328  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
329  DcdDataTransfer(2 * n, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
330  }
331  else {
332  uint32_t tem = dQueueHead[2 * n].overlay.TotalBytes;
333  dQueueHead[2 * n].TransferCount -= tem;
334 
335  if (stream_total_packets > 0) {
336  if (stream_remain_packets > 0) {
337  uint32_t cnt = dQueueHead[2 * n].TransferCount;
338  Endpoint_Streaming((uint8_t *) stream_buffer_address,
339  stream_packet_size,
340  stream_remain_packets,
341  0);
342  dQueueHead[2 * n].TransferCount = cnt;
343  }
344  else {
345  stream_total_packets = 0;
346  }
347  }
348  else {
349  stream_total_packets = 0;
350  dQueueHead[2 * n].IsOutReceived = 1;
351  }
352  if (n == 0) {
353  usb_data_buffer_size = dQueueHead[2 * n].TransferCount;
354  }
355  else {
356  usb_data_buffer_OUT_size = dQueueHead[2 * n].TransferCount;
357  }
358  }
360  }
361  if ( ENDPTCOMPLETE & _BIT( (n + 16) ) ) { /* IN */
362  if (((ENDPTCTRL_REG(n) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso in endpoint
363  uint32_t size;
364  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
365  DcdDataTransfer(2 * n + 1, ISO_Address, size);
366  }
367  else {
368  if (stream_remain_packets > 0) {
369  uint32_t cnt = dQueueHead[2 * n].TransferCount;
370  Endpoint_Streaming((uint8_t *) stream_buffer_address,
371  stream_packet_size,
372  stream_remain_packets,
373  0);
374  dQueueHead[2 * n].TransferCount = cnt;
375  }
376  else {
377  stream_total_packets = 0;
378  }
379  }
381  }
382  }
383  }
384 }
385 
386 void Endpoint_GetSetupPackage(uint8_t *pData)
387 {
388  USB_Request_Header_t *ctrlrq = (USB_Request_Header_t *) pData;
389  memcpy(pData, (void *) dQueueHead[0].SetupPackage, 8);
390  /* Below fix is to prevent Endpoint_Read_Control_Stream_LE()
391  * from getting wrong data*/
392 
393  if (
394  (ctrlrq->wLength != 0)
395  ) {
396  dQueueHead[0].IsOutReceived = 0;
397  }
398 }
399 
400 void DcdIrqHandler(uint8_t HostID)
401 {
402  uint32_t USBSTS_D;
403  uint32_t t = USB_REG(USBPortNum)->USBINTR_D;
404 
405  USBSTS_D = USB_REG(USBPortNum)->USBSTS_D & t; /* Device Interrupt Status */
406  if (USBSTS_D == 0) {/* avoid to clear disabled interrupt source */
407  return;
408  }
409 
410  USB_REG(USBPortNum)->USBSTS_D = USBSTS_D; /* Acknowledge Interrupt */
411 
412  /* Process Interrupt Sources */
413  if (USBSTS_D & USBSTS_D_UsbInt) {
414  if (USB_REG(USBPortNum)->ENDPTSETUPSTAT) {
415  // memcpy(SetupPackage, dQueueHead[0].SetupPackage, 8);
416  /* Will be cleared by Endpoint_ClearSETUP */
417  }
418 
419  if (USB_REG(USBPortNum)->ENDPTCOMPLETE) {
420  TransferCompleteISR();
421  }
422  }
423 
424  if (USBSTS_D & USBSTS_D_NAK) { /* NAK */
425  uint32_t ENDPTNAK = USB_REG(USBPortNum)->ENDPTNAK;
426  uint32_t en = USB_REG(USBPortNum)->ENDPTNAKEN;
427  ENDPTNAK &= en;
428  USB_REG(USBPortNum)->ENDPTNAK = ENDPTNAK;
429 
430  if (ENDPTNAK) { /* handle NAK interrupts */
431  uint8_t LogicalEP;
432  for (LogicalEP = 0; LogicalEP < USED_PHYSICAL_ENDPOINTS / 2; LogicalEP++)
433  if (ENDPTNAK & _BIT(LogicalEP)) { /* Only OUT Endpoint is NAK enable */
434  uint8_t PhyEP = 2 * LogicalEP;
435  if ( !(USB_REG(USBPortNum)->ENDPTSTAT & _BIT(LogicalEP)) ) {/* Is In ready */
436  /* Check read OUT flag */
437  if (!dQueueHead[PhyEP].IsOutReceived) {
438 
439  if (PhyEP == 0) {
441  USB_REG(USBPortNum)->ENDPTNAKEN &= ~(1 << 0);
442  DcdDataTransfer(PhyEP, usb_data_buffer, 512);
443  }
444  else {
445  if (stream_total_packets == 0) {
447  /* Clear NAK */
448  USB_REG(USBPortNum)->ENDPTNAKEN &= ~(1 << LogicalEP);
449  DcdDataTransfer(PhyEP, usb_data_buffer_OUT, 512 /*512*/);
450  }
451  }
452  }
453  }
454  }
455  }
456  }
457 
458  if (USBSTS_D & USBSTS_D_SofReceived) { /* Start of Frame Interrupt */
460  }
461 
462  if (USBSTS_D & USBSTS_D_ResetReceived) { /* Reset */
463  HAL_Reset();
469  0);
474  0);
475  }
476 
477  if (USBSTS_D & USBSTS_D_SuspendInt) { /* Suspend */
478 
479  }
480 
481  if (USBSTS_D & USBSTS_D_PortChangeDetect) { /* Resume */
482 
483  }
484 
485  if (USBSTS_D & USBSTS_D_UsbErrorInt) { /* Error Interrupt */
486  // while(1){}
487  }
488 }
489 
490 uint32_t Dummy_EPGetISOAddress(uint32_t EPNum, uint32_t *last_packet_size)
491 {
492  return (uint32_t) iso_buffer;
493 }
494 
495 /*********************************************************************/
503 void Dummy_EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)
504 {
510 }
511 // #endif
512 
513 #endif /*__LPC18XX__*/