LPCOpen Platform  v1.03
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) __BSS(USBRAM_SECTION);
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
45 uint8_t usb_RomDriver_CDC_buffer[ROMDRIVER_CDC_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
48 uint8_t UsbdCdc_EPIN_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
51 uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
54 
55 #endif
56 
57 #define STREAM_TDs 16
58 
60 volatile DeviceQueueHead dQueueHead0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);
62 volatile DeviceQueueHead dQueueHead1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);
64 DeviceTransferDescriptor dTransferDescriptor0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
66 DeviceTransferDescriptor dTransferDescriptor1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
68 DeviceTransferDescriptor dStreamTD0[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
70 DeviceTransferDescriptor dStreamTD1[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
72 uint8_t iso_buffer[512] ATTR_ALIGNED(4);
73 volatile DeviceQueueHead * const dQueueHead[LPC18_43_MAX_USB_CORE] = {dQueueHead0, dQueueHead1};
74 DeviceTransferDescriptor * const dTransferDescriptor[LPC18_43_MAX_USB_CORE] = {dTransferDescriptor0, dTransferDescriptor1};
75 DeviceTransferDescriptor * const dStreamTD_Tbl[LPC18_43_MAX_USB_CORE] = {dStreamTD0, dStreamTD1};
76 
77 typedef struct {
78  uint32_t stream_buffer_address,
79  stream_dummy_buffer_address,
80  stream_remain_packets,
81  stream_dummy_packets,
82  stream_packet_size,
83  stream_total_packets;
84 } STREAM_VAR_t;
85 
86 static STREAM_VAR_t Stream_Variable[LPC18_43_MAX_USB_CORE];
87 
88 PRAGMA_WEAK(CALLBACK_HAL_GetISOBufferAddress, Dummy_EPGetISOAddress)
90  Dummy_EPGetISOAddress);
91 
92 /* Device transfer completed event
93  * Event is required for using the device stack with any RTOS
94  */
95 PRAGMA_WEAK(EVENT_USB_Device_TransferComplete,Dummy_EVENT_USB_Device_TransferComplete)
96 void EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in) ATTR_WEAK ATTR_ALIAS(Dummy_EVENT_USB_Device_TransferComplete);
97 
98 void DcdInsertTD(uint32_t head, uint32_t newtd);
99 
100 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC);
101 
102 void HAL_Reset(uint8_t corenum)
103 {
104  uint32_t i;
105  IP_USBHS_001_T * USB_Reg;
106  USB_Reg = USB_REG(corenum);
107 
108  /* disable all EPs */
109  USB_Reg->ENDPTCTRL[0] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
110  USB_Reg->ENDPTCTRL[1] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
111  USB_Reg->ENDPTCTRL[2] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
112  USB_Reg->ENDPTCTRL[3] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
113  if (corenum == 0) {
114  USB_Reg->ENDPTCTRL[4] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
115  USB_Reg->ENDPTCTRL[5] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
116  }
117 
118  /* Clear all pending interrupts */
119  USB_Reg->ENDPTNAK = 0xFFFFFFFF;
120  USB_Reg->ENDPTNAKEN = 0;
121  USB_Reg->USBSTS_D = 0xFFFFFFFF;
122  USB_Reg->ENDPTSETUPSTAT = USB_Reg->ENDPTSETUPSTAT;
123  USB_Reg->ENDPTCOMPLETE = USB_Reg->ENDPTCOMPLETE;
124  while (USB_Reg->ENDPTPRIME) ; /* Wait until all bits are 0 */
125  USB_Reg->ENDPTFLUSH = 0xFFFFFFFF;
126  while (USB_Reg->ENDPTFLUSH) ; /* Wait until all bits are 0 */
127 
128  /* Set the interrupt Threshold control interval to 0 */
129  USB_Reg->USBCMD_D &= ~0x00FF0000;
130 
131  /* Configure the Endpoint List Address */
132  /* make sure it in on 64 byte boundary !!! */
133  /* init list address */
134  USB_Reg->ENDPOINTLISTADDR = (uint32_t) dQueueHead[corenum];
135 
136  /* Enable interrupts: USB interrupt, error, port change, reset, suspend, NAK interrupt */
137  USB_Reg->USBINTR_D = USBINTR_D_UsbIntEnable | USBINTR_D_UsbErrorIntEnable |
138  USBINTR_D_PortChangeIntEnable | USBINTR_D_UsbResetEnable |
139  USBINTR_D_SuspendEnable | USBINTR_D_NAKEnable | USBINTR_D_SofReceivedEnable;
140 
141  USB_Device_SetDeviceAddress(corenum, 0);
142 
143  endpointselected[corenum] = 0;
144  for (i = 0; i < ENDPOINT_TOTAL_ENDPOINTS(corenum); i++)
145  endpointhandle(corenum)[i] = 0;
146 
147  usb_data_buffer_size[corenum] = 0;
148  usb_data_buffer_index[corenum] = 0;
149 
150  usb_data_buffer_OUT_size[corenum] = 0;
151  usb_data_buffer_OUT_index[corenum] = 0;
152 
153  // usb_data_buffer_IN_size = 0;
154  usb_data_buffer_IN_index[corenum] = 0;
155  Stream_Variable[corenum].stream_total_packets = 0;
156 }
157 
158 bool Endpoint_ConfigureEndpoint(uint8_t corenum, const uint8_t Number, const uint8_t Type,
159  const uint8_t Direction, const uint16_t Size, const uint8_t Banks)
160 {
161  uint8_t * ISO_Address;
162  volatile DeviceQueueHead * pdQueueHead;
163  uint32_t PhyEP = 2 * Number + (Direction == ENDPOINT_DIR_OUT ? 0 : 1);
164  __IO uint32_t * pEndPointCtrl = &ENDPTCTRL_REG(corenum, Number);
165  uint32_t EndPtCtrl = *pEndPointCtrl;
166 
167  pdQueueHead = &(dQueueHead[corenum][PhyEP]);
168  memset((void *) pdQueueHead, 0, sizeof(DeviceQueueHead) );
169 
170  pdQueueHead->MaxPacketSize = Size & 0x3ff;
171  pdQueueHead->IntOnSetup = 1;
172  pdQueueHead->ZeroLengthTermination = 1;
173  pdQueueHead->overlay.NextTD = LINK_TERMINATE;
174 
175  if (Direction == ENDPOINT_DIR_OUT) {
176  EndPtCtrl &= ~0x0000FFFF;
177  EndPtCtrl |= ((Type << 2) & ENDPTCTRL_RxType) | ENDPTCTRL_RxEnable | ENDPTCTRL_RxToggleReset;
178  if (Type == EP_TYPE_ISOCHRONOUS) {
179  uint32_t size = 0;
180  *pEndPointCtrl = (Type << 2); // TODO dummy to let DcdDataTransfer() knows iso transfer
181  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
182  DcdDataTransfer(corenum, PhyEP, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
183  }
184  else {
185  USB_REG(corenum)->ENDPTNAKEN |= (1 << EP_Physical2BitPosition(PhyEP));
186  }
187  }
188  else { /* ENDPOINT_DIR_IN */
189  EndPtCtrl &= ~0xFFFF0000;
190  EndPtCtrl |= ((Type << 18) & ENDPTCTRL_TxType) | ENDPTCTRL_TxEnable | ENDPTCTRL_TxToggleReset;
191  if (Type == EP_TYPE_ISOCHRONOUS) {
192  uint32_t size = 0;
193  *pEndPointCtrl = (Type << 18); // TODO dummy to let DcdDataTransfer() knows iso transfer
194  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
195  DcdDataTransfer(corenum, PhyEP, ISO_Address, size);
196  }
197  }
198  *pEndPointCtrl = EndPtCtrl;
199 
200  endpointhandle(corenum)[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;
201  return true;
202 }
203 
204 void Endpoint_Streaming(uint8_t corenum, uint8_t *buffer, uint16_t packetsize,
205  uint16_t totalpackets, uint16_t dummypackets)
206 {
207  uint8_t PhyEP = endpointhandle(corenum)[endpointselected[corenum]];
208  uint16_t i;
209  volatile DeviceQueueHead * pdQueueHead;
210 #if 0
211  for (i = 0; i < totalpackets; i++) {
212  DcdDataTransfer(corenum, PhyEP, (uint8_t *) (buffer + i * packetsize), packetsize);
213  while (!(
214  (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
215  && (dQueueHead[PhyEP].overlay.Active == 0)
216  )
217  ) ;
218  }
219  for (i = 0; i < dummypackets; i++) {
220  DcdDataTransfer(corenum, PhyEP, buffer, packetsize);
221  while (!(
222  (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
223  && (dQueueHead[PhyEP].overlay.Active == 0)
224  )
225  ) ;
226  }
227 #else
228  STREAM_VAR_t * current_stream = &Stream_Variable[corenum];
229  DeviceTransferDescriptor *dStreamTD = dStreamTD_Tbl[corenum];
230  uint16_t cnt = 0;
231  dummypackets = dummypackets;
232  while ( USB_REG(corenum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
233  }
234 
235  for (i = 0; i < totalpackets; i++) {
236  uint8_t ioc;
237  if (i == STREAM_TDs) {
238  break;
239  }
240  if ((i == totalpackets - 1) || (i == STREAM_TDs - 1)) {
241  ioc = 1;
242  }
243  else {
244  ioc = 0;
245  }
246 
247  DcdPrepareTD(&dStreamTD[i], (uint8_t *) (buffer + i * packetsize), packetsize, ioc);
248  if (i > 0) {
249  DcdInsertTD((uint32_t) dStreamTD, (uint32_t) &dStreamTD[i]);
250  }
251  cnt++;
252  }
253 
254  if (STREAM_TDs < totalpackets) {
255  current_stream->stream_remain_packets = totalpackets - STREAM_TDs;
256  current_stream->stream_buffer_address = (uint32_t) buffer + STREAM_TDs * packetsize;
257  current_stream->stream_packet_size = packetsize;
258  }
259  else {
260  current_stream->stream_remain_packets = current_stream->stream_buffer_address = current_stream->stream_packet_size = 0;
261  }
262  current_stream->stream_total_packets = totalpackets;
263  pdQueueHead = &(dQueueHead[corenum][PhyEP]);
264  pdQueueHead->overlay.Halted = 0; /* this should be in USBInt */
265  pdQueueHead->overlay.Active = 0; /* this should be in USBInt */
266  pdQueueHead->overlay.NextTD = (uint32_t) dStreamTD;
267  pdQueueHead->TransferCount = totalpackets * packetsize;
268  pdQueueHead->IsOutReceived = 0;
269 
270  USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
271 #endif
272 }
273 
274 void DcdInsertTD(uint32_t head, uint32_t newtd)
275 {
276  DeviceTransferDescriptor *pTD = (DeviceTransferDescriptor *) head;
277  while (!(pTD->NextTD & LINK_TERMINATE)) pTD = (DeviceTransferDescriptor *) pTD->NextTD;
278  pTD->NextTD = newtd;
279 }
280 
281 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC)
282 {
283  /* Zero out the device transfer descriptors */
284  memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
285 
286  pDTD->NextTD = LINK_TERMINATE;
287  pDTD->TotalBytes = length;
288  pDTD->IntOnComplete = IOC;
289  pDTD->Active = 1;
290  pDTD->BufferPage[0] = (uint32_t) pData;
291  pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
292  // pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
293  // pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
294  // pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
295 }
296 
297 void DcdDataTransfer(uint8_t corenum, uint8_t PhyEP, uint8_t *pData, uint32_t length)
298 {
299  DeviceTransferDescriptor * pDTD = (DeviceTransferDescriptor *) &dTransferDescriptor[corenum][PhyEP];
300  volatile DeviceQueueHead * pdQueueHead = &(dQueueHead[corenum][PhyEP]);
301  while ( USB_REG(corenum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
302  }
303 
304  /* Zero out the device transfer descriptors */
305  memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
306 
307  if (((ENDPTCTRL_REG(corenum, PhyEP / 2) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
308  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
309  pDTD->NextTD = LINK_TERMINATE;
310  pdQueueHead->Mult = mult;
311  }
312  else if (((ENDPTCTRL_REG(corenum, PhyEP / 2) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) {// iso in endpoint
313  uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
314  pDTD->NextTD = LINK_TERMINATE;
315  pdQueueHead->Mult = mult;
316  }
317  else { // other endpoint types
318  pDTD->NextTD = LINK_TERMINATE; /* The next DTD pointer is INVALID */
319  }
320  pDTD->TotalBytes = length;
321  pDTD->IntOnComplete = 1;
322  pDTD->Active = 1;
323 
324  pDTD->BufferPage[0] = (uint32_t) pData;
325  pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
326  pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
327  pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
328  pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
329 
330  pdQueueHead->overlay.Halted = 0; /* this should be in USBInt */
331  pdQueueHead->overlay.Active = 0; /* this should be in USBInt */
332  pdQueueHead->overlay.NextTD = (uint32_t) &dTransferDescriptor[corenum][PhyEP];
333  pdQueueHead->TransferCount = length;
334 
335  /* prime the endpoint for transmit */
336  USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
337 }
338 
339 void TransferCompleteISR(uint8_t corenum)
340 {
341  uint8_t * ISO_Address;
342  IP_USBHS_001_T * USB_Reg = USB_REG(corenum);
343  STREAM_VAR_t * current_stream = &Stream_Variable[corenum];
344  uint32_t ENDPTCOMPLETE = USB_Reg->ENDPTCOMPLETE;
345  USB_Reg->ENDPTCOMPLETE = ENDPTCOMPLETE;
346  if (ENDPTCOMPLETE) {
347  uint8_t n;
348  for (n = 0; n < USED_PHYSICAL_ENDPOINTS(corenum) / 2; n++) { /* LOGICAL */
349  if ( ENDPTCOMPLETE & _BIT(n) ) {/* OUT */
350  if (((ENDPTCTRL_REG(corenum, n) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
351  uint32_t size = dQueueHead[corenum][2 * n].TransferCount;
352  size -= dQueueHead[corenum][2 * n].overlay.TotalBytes;
353  // copy to share buffer
354  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
355  DcdDataTransfer(corenum, 2 * n, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
356  }
357  else {
358 
359  uint32_t tem = dQueueHead[corenum][2 * n].overlay.TotalBytes;
360  dQueueHead[corenum][2 * n].TransferCount -= tem;
361 
362  if (current_stream->stream_total_packets > 0) {
363  if (current_stream->stream_remain_packets > 0) {
364  uint32_t cnt = dQueueHead[corenum][2 * n].TransferCount;
365  Endpoint_Streaming(corenum,(uint8_t *) current_stream->stream_buffer_address,
366  current_stream->stream_packet_size,
367  current_stream->stream_remain_packets,
368  0);
369  dQueueHead[corenum][2 * n].TransferCount = cnt;
370  }
371  else {
372  current_stream->stream_total_packets = 0;
373  dQueueHead[corenum][2 * n].IsOutReceived = 1;
374  }
375  }
376  else {
377  //stream_total_packets = 0;
378  dQueueHead[corenum][2 * n].IsOutReceived = 1;
379  }
380  if (n == 0) {
381  usb_data_buffer_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;
382  }
383  else {
384  usb_data_buffer_OUT_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;
385  }
386  }
388  }
389  if ( ENDPTCOMPLETE & _BIT( (n + 16) ) ) { /* IN */
390  if (((ENDPTCTRL_REG(corenum, n) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso in endpoint
391  uint32_t size;
392  ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
393  DcdDataTransfer(corenum, 2 * n + 1, ISO_Address, size);
394  }
395  else {
396  if (current_stream->stream_remain_packets > 0) {
397  uint32_t cnt = dQueueHead[corenum][2 * n].TransferCount;
398  Endpoint_Streaming(corenum, (uint8_t *) current_stream->stream_buffer_address,
399  current_stream->stream_packet_size,
400  current_stream->stream_remain_packets,
401  0);
402  dQueueHead[corenum][2 * n].TransferCount = cnt;
403  }
404  else {
405  current_stream->stream_total_packets = 0;
406  }
407  }
409  }
410  }
411  }
412 }
413 
414 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData)
415 {
416  USB_Request_Header_t * ctrlrq = (USB_Request_Header_t *) pData;
417  volatile DeviceQueueHead* pdQueueHead = &(dQueueHead[corenum][0]);
418  memcpy(pData, (void *) pdQueueHead->SetupPackage, 8);
419  /* Below fix is to prevent Endpoint_Read_Control_Stream_LE()
420  * from getting wrong data*/
421 
422  if (
423  (ctrlrq->wLength != 0)
424  ) {
425  pdQueueHead->IsOutReceived = 0;
426  }
427 }
428 
429 void DcdIrqHandler(uint8_t corenum)
430 {
431  uint32_t USBSTS_D;
432  IP_USBHS_001_T * USB_Reg = USB_REG(corenum);
433  uint32_t t = USB_Reg->USBINTR_D;
434 
435  USBSTS_D = USB_Reg->USBSTS_D & t; /* Device Interrupt Status */
436  if (USBSTS_D == 0) {/* avoid to clear disabled interrupt source */
437  return;
438  }
439 
440  USB_Reg->USBSTS_D = USBSTS_D; /* Acknowledge Interrupt */
441 
442  /* Process Interrupt Sources */
443  if (USBSTS_D & USBSTS_D_UsbInt) {
444  if (USB_Reg->ENDPTSETUPSTAT) {
445  // memcpy(SetupPackage, dQueueHead[0].SetupPackage, 8);
446  /* Will be cleared by Endpoint_ClearSETUP */
447  }
448 
449  if (USB_Reg->ENDPTCOMPLETE) {
450  TransferCompleteISR(corenum);
451  }
452  }
453 
454  if (USBSTS_D & USBSTS_D_NAK) { /* NAK */
455  uint32_t ENDPTNAK = USB_Reg->ENDPTNAK;
456  uint32_t en = USB_Reg->ENDPTNAKEN;
457  ENDPTNAK &= en;
458  USB_Reg->ENDPTNAK = ENDPTNAK;
459 
460  if (ENDPTNAK) { /* handle NAK interrupts */
461  uint8_t LogicalEP;
462  for (LogicalEP = 0; LogicalEP < USED_PHYSICAL_ENDPOINTS(corenum) / 2; LogicalEP++)
463  if (ENDPTNAK & _BIT(LogicalEP)) { /* Only OUT Endpoint is NAK enable */
464  uint8_t PhyEP = 2 * LogicalEP;
465  if ( !(USB_Reg->ENDPTSTAT & _BIT(LogicalEP)) ) {/* Is In ready */
466  /* Check read OUT flag */
467  if (!dQueueHead[corenum][PhyEP].IsOutReceived) {
468 
469  if (PhyEP == 0) {
470  usb_data_buffer_size[corenum] = 0;
471  USB_Reg->ENDPTNAKEN &= ~(1 << 0);
472  DcdDataTransfer(corenum, PhyEP, usb_data_buffer[corenum], 512);
473  }
474  else {
475  if (Stream_Variable[corenum].stream_total_packets == 0) {
476  usb_data_buffer_OUT_size[corenum] = 0;
477  /* Clear NAK */
478  USB_Reg->ENDPTNAKEN &= ~(1 << LogicalEP);
479  DcdDataTransfer(corenum, PhyEP, usb_data_buffer_OUT[corenum], 512 /*512*/);
480  }
481  }
482  }
483  }
484  }
485  }
486  }
487 
488  if (USBSTS_D & USBSTS_D_SofReceived) { /* Start of Frame Interrupt */
490  }
491 
492  if (USBSTS_D & USBSTS_D_ResetReceived) { /* Reset */
493  HAL_Reset(corenum);
500  0);
506  0);
507  }
508 
509  if (USBSTS_D & USBSTS_D_SuspendInt) { /* Suspend */
510 
511  }
512 
513  if (USBSTS_D & USBSTS_D_PortChangeDetect) { /* Resume */
514 
515  }
516 
517  if (USBSTS_D & USBSTS_D_UsbErrorInt) { /* Error Interrupt */
518  // while(1){}
519  }
520 }
521 
522 uint32_t Dummy_EPGetISOAddress(uint32_t EPNum, uint32_t *last_packet_size)
523 {
524  return (uint32_t) iso_buffer;
525 }
526 
527 /*********************************************************************/
535 void Dummy_EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)
536 {
542 }
543 // #endif
544 
545 #endif /*__LPC18XX__*/