2 * @brief USB Endpoint definitions for the LPC18xx microcontrollers
\r
5 * Copyright(C) NXP Semiconductors, 2012
\r
6 * All rights reserved.
\r
9 * Software that is described herein is for illustrative purposes only
\r
10 * which provides customers with programming information regarding the
\r
11 * LPC products. This software is supplied "AS IS" without any warranties of
\r
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
\r
13 * all warranties, express or implied, including all implied warranties of
\r
14 * merchantability, fitness for a particular purpose and non-infringement of
\r
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
\r
16 * or liability for the use of the software, conveys no license or rights under any
\r
17 * patent, copyright, mask work right, or any other intellectual property rights in
\r
18 * or to any products. NXP Semiconductors reserves the right to make changes
\r
19 * in the software without notification. NXP Semiconductors also makes no
\r
20 * representation or warranty that such application will be suitable for the
\r
21 * specified use without further testing or modification.
\r
24 * Permission to use, copy, modify, and distribute this software and its
\r
25 * documentation is hereby granted, under NXP Semiconductors' and its
\r
26 * licensor's relevant copyrights in the software, without fee, provided that it
\r
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
\r
28 * copyright, permission, and disclaimer notice must appear in all copies of
\r
32 #define __INCLUDE_FROM_USB_DRIVER
\r
33 #include "../../USBMode.h"
\r
35 #if (defined(__LPC18XX__) || defined(__LPC43XX__)) && defined(USB_CAN_BE_DEVICE)
\r
36 #include "../../Endpoint.h"
\r
39 #if defined(USB_DEVICE_ROM_DRIVER)
\r
41 uint8_t usb_RomDriver_buffer[ROMDRIVER_MEM_SIZE] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);
\r
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
\r
45 uint8_t usb_RomDriver_CDC_buffer[ROMDRIVER_CDC_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
\r
46 /** Endpoint IN buffer, used for DMA operation */
\r
48 uint8_t UsbdCdc_EPIN_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
\r
49 /** Endpoint OUT buffer, used for DMA operation */
\r
51 uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
\r
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);
\r
57 #define STREAM_TDs 16
\r
60 volatile DeviceQueueHead dQueueHead0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);
\r
62 volatile DeviceQueueHead dQueueHead1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);
\r
64 DeviceTransferDescriptor dTransferDescriptor0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
\r
66 DeviceTransferDescriptor dTransferDescriptor1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
\r
68 DeviceTransferDescriptor dStreamTD0[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
\r
70 DeviceTransferDescriptor dStreamTD1[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);
\r
72 uint8_t iso_buffer[512] ATTR_ALIGNED(4);
\r
73 volatile DeviceQueueHead * const dQueueHead[LPC18_43_MAX_USB_CORE] = {dQueueHead0, dQueueHead1};
\r
74 DeviceTransferDescriptor * const dTransferDescriptor[LPC18_43_MAX_USB_CORE] = {dTransferDescriptor0, dTransferDescriptor1};
\r
75 DeviceTransferDescriptor * const dStreamTD_Tbl[LPC18_43_MAX_USB_CORE] = {dStreamTD0, dStreamTD1};
\r
78 uint32_t stream_buffer_address,
\r
79 stream_dummy_buffer_address,
\r
80 stream_remain_packets,
\r
81 stream_dummy_packets,
\r
83 stream_total_packets;
\r
86 static STREAM_VAR_t Stream_Variable[LPC18_43_MAX_USB_CORE];
\r
88 PRAGMA_WEAK(CALLBACK_HAL_GetISOBufferAddress, Dummy_EPGetISOAddress)
\r
89 uint32_t CALLBACK_HAL_GetISOBufferAddress(const uint32_t EPNum, uint32_t *last_packet_size) ATTR_WEAK ATTR_ALIAS(
\r
90 Dummy_EPGetISOAddress);
\r
92 /* Device transfer completed event
\r
93 * Event is required for using the device stack with any RTOS
\r
95 PRAGMA_WEAK(EVENT_USB_Device_TransferComplete,Dummy_EVENT_USB_Device_TransferComplete)
\r
96 void EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in) ATTR_WEAK ATTR_ALIAS(Dummy_EVENT_USB_Device_TransferComplete);
\r
98 void DcdInsertTD(uint32_t head, uint32_t newtd);
\r
100 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC);
\r
102 void HAL_Reset(uint8_t corenum)
\r
105 IP_USBHS_001_T * USB_Reg;
\r
106 USB_Reg = USB_REG(corenum);
\r
108 /* disable all EPs */
\r
109 USB_Reg->ENDPTCTRL[0] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
110 USB_Reg->ENDPTCTRL[1] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
111 USB_Reg->ENDPTCTRL[2] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
112 USB_Reg->ENDPTCTRL[3] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
113 if (corenum == 0) {
\r
114 USB_Reg->ENDPTCTRL[4] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
115 USB_Reg->ENDPTCTRL[5] &= ~(ENDPTCTRL_RxEnable | ENDPTCTRL_TxEnable);
\r
118 /* Clear all pending interrupts */
\r
119 USB_Reg->ENDPTNAK = 0xFFFFFFFF;
\r
120 USB_Reg->ENDPTNAKEN = 0;
\r
121 USB_Reg->USBSTS_D = 0xFFFFFFFF;
\r
122 USB_Reg->ENDPTSETUPSTAT = USB_Reg->ENDPTSETUPSTAT;
\r
123 USB_Reg->ENDPTCOMPLETE = USB_Reg->ENDPTCOMPLETE;
\r
124 while (USB_Reg->ENDPTPRIME) ; /* Wait until all bits are 0 */
\r
125 USB_Reg->ENDPTFLUSH = 0xFFFFFFFF;
\r
126 while (USB_Reg->ENDPTFLUSH) ; /* Wait until all bits are 0 */
\r
128 /* Set the interrupt Threshold control interval to 0 */
\r
129 USB_Reg->USBCMD_D &= ~0x00FF0000;
\r
131 /* Configure the Endpoint List Address */
\r
132 /* make sure it in on 64 byte boundary !!! */
\r
133 /* init list address */
\r
134 USB_Reg->ENDPOINTLISTADDR = (uint32_t) dQueueHead[corenum];
\r
136 /* Enable interrupts: USB interrupt, error, port change, reset, suspend, NAK interrupt */
\r
137 USB_Reg->USBINTR_D = USBINTR_D_UsbIntEnable | USBINTR_D_UsbErrorIntEnable |
\r
138 USBINTR_D_PortChangeIntEnable | USBINTR_D_UsbResetEnable |
\r
139 USBINTR_D_SuspendEnable | USBINTR_D_NAKEnable | USBINTR_D_SofReceivedEnable;
\r
141 USB_Device_SetDeviceAddress(corenum, 0);
\r
143 endpointselected[corenum] = 0;
\r
144 for (i = 0; i < ENDPOINT_TOTAL_ENDPOINTS(corenum); i++)
\r
145 endpointhandle(corenum)[i] = 0;
\r
147 usb_data_buffer_size[corenum] = 0;
\r
148 usb_data_buffer_index[corenum] = 0;
\r
150 usb_data_buffer_OUT_size[corenum] = 0;
\r
151 usb_data_buffer_OUT_index[corenum] = 0;
\r
153 // usb_data_buffer_IN_size = 0;
\r
154 usb_data_buffer_IN_index[corenum] = 0;
\r
155 Stream_Variable[corenum].stream_total_packets = 0;
\r
158 bool Endpoint_ConfigureEndpoint(uint8_t corenum, const uint8_t Number, const uint8_t Type,
\r
159 const uint8_t Direction, const uint16_t Size, const uint8_t Banks)
\r
161 uint8_t * ISO_Address;
\r
162 volatile DeviceQueueHead * pdQueueHead;
\r
163 uint32_t PhyEP = 2 * Number + (Direction == ENDPOINT_DIR_OUT ? 0 : 1);
\r
164 __IO uint32_t * pEndPointCtrl = &ENDPTCTRL_REG(corenum, Number);
\r
165 uint32_t EndPtCtrl = *pEndPointCtrl;
\r
167 pdQueueHead = &(dQueueHead[corenum][PhyEP]);
\r
168 memset((void *) pdQueueHead, 0, sizeof(DeviceQueueHead) );
\r
170 pdQueueHead->MaxPacketSize = Size & 0x3ff;
\r
171 pdQueueHead->IntOnSetup = 1;
\r
172 pdQueueHead->ZeroLengthTermination = 1;
\r
173 pdQueueHead->overlay.NextTD = LINK_TERMINATE;
\r
175 if (Direction == ENDPOINT_DIR_OUT) {
\r
176 EndPtCtrl &= ~0x0000FFFF;
\r
177 EndPtCtrl |= ((Type << 2) & ENDPTCTRL_RxType) | ENDPTCTRL_RxEnable | ENDPTCTRL_RxToggleReset;
\r
178 if (Type == EP_TYPE_ISOCHRONOUS) {
\r
180 *pEndPointCtrl = (Type << 2); // TODO dummy to let DcdDataTransfer() knows iso transfer
\r
181 ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
\r
182 DcdDataTransfer(corenum, PhyEP, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
\r
185 USB_REG(corenum)->ENDPTNAKEN |= (1 << EP_Physical2BitPosition(PhyEP));
\r
188 else { /* ENDPOINT_DIR_IN */
\r
189 EndPtCtrl &= ~0xFFFF0000;
\r
190 EndPtCtrl |= ((Type << 18) & ENDPTCTRL_TxType) | ENDPTCTRL_TxEnable | ENDPTCTRL_TxToggleReset;
\r
191 if (Type == EP_TYPE_ISOCHRONOUS) {
\r
193 *pEndPointCtrl = (Type << 18); // TODO dummy to let DcdDataTransfer() knows iso transfer
\r
194 ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(Number, &size);
\r
195 DcdDataTransfer(corenum, PhyEP, ISO_Address, size);
\r
198 *pEndPointCtrl = EndPtCtrl;
\r
200 endpointhandle(corenum)[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;
\r
204 void Endpoint_Streaming(uint8_t corenum, uint8_t *buffer, uint16_t packetsize,
\r
205 uint16_t totalpackets, uint16_t dummypackets)
\r
207 uint8_t PhyEP = endpointhandle(corenum)[endpointselected[corenum]];
\r
209 volatile DeviceQueueHead * pdQueueHead;
\r
211 for (i = 0; i < totalpackets; i++) {
\r
212 DcdDataTransfer(corenum, PhyEP, (uint8_t *) (buffer + i * packetsize), packetsize);
\r
214 (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
\r
215 && (dQueueHead[PhyEP].overlay.Active == 0)
\r
219 for (i = 0; i < dummypackets; i++) {
\r
220 DcdDataTransfer(corenum, PhyEP, buffer, packetsize);
\r
222 (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)
\r
223 && (dQueueHead[PhyEP].overlay.Active == 0)
\r
228 STREAM_VAR_t * current_stream = &Stream_Variable[corenum];
\r
229 DeviceTransferDescriptor *dStreamTD = dStreamTD_Tbl[corenum];
\r
231 dummypackets = dummypackets;
\r
232 while ( USB_REG(corenum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
\r
235 for (i = 0; i < totalpackets; i++) {
\r
237 if (i == STREAM_TDs) {
\r
240 if ((i == totalpackets - 1) || (i == STREAM_TDs - 1)) {
\r
247 DcdPrepareTD(&dStreamTD[i], (uint8_t *) (buffer + i * packetsize), packetsize, ioc);
\r
249 DcdInsertTD((uint32_t) dStreamTD, (uint32_t) &dStreamTD[i]);
\r
254 if (STREAM_TDs < totalpackets) {
\r
255 current_stream->stream_remain_packets = totalpackets - STREAM_TDs;
\r
256 current_stream->stream_buffer_address = (uint32_t) buffer + STREAM_TDs * packetsize;
\r
257 current_stream->stream_packet_size = packetsize;
\r
260 current_stream->stream_remain_packets = current_stream->stream_buffer_address = current_stream->stream_packet_size = 0;
\r
262 current_stream->stream_total_packets = totalpackets;
\r
263 pdQueueHead = &(dQueueHead[corenum][PhyEP]);
\r
264 pdQueueHead->overlay.Halted = 0; /* this should be in USBInt */
\r
265 pdQueueHead->overlay.Active = 0; /* this should be in USBInt */
\r
266 pdQueueHead->overlay.NextTD = (uint32_t) dStreamTD;
\r
267 pdQueueHead->TransferCount = totalpackets * packetsize;
\r
268 pdQueueHead->IsOutReceived = 0;
\r
270 USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
\r
274 void DcdInsertTD(uint32_t head, uint32_t newtd)
\r
276 DeviceTransferDescriptor *pTD = (DeviceTransferDescriptor *) head;
\r
277 while (!(pTD->NextTD & LINK_TERMINATE)) pTD = (DeviceTransferDescriptor *) pTD->NextTD;
\r
278 pTD->NextTD = newtd;
\r
281 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC)
\r
283 /* Zero out the device transfer descriptors */
\r
284 memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
\r
286 pDTD->NextTD = LINK_TERMINATE;
\r
287 pDTD->TotalBytes = length;
\r
288 pDTD->IntOnComplete = IOC;
\r
290 pDTD->BufferPage[0] = (uint32_t) pData;
\r
291 pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
\r
292 // pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
\r
293 // pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
\r
294 // pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
\r
297 void DcdDataTransfer(uint8_t corenum, uint8_t PhyEP, uint8_t *pData, uint32_t length)
\r
299 DeviceTransferDescriptor * pDTD = (DeviceTransferDescriptor *) &dTransferDescriptor[corenum][PhyEP];
\r
300 volatile DeviceQueueHead * pdQueueHead = &(dQueueHead[corenum][PhyEP]);
\r
301 while ( USB_REG(corenum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */
\r
304 /* Zero out the device transfer descriptors */
\r
305 memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));
\r
307 if (((ENDPTCTRL_REG(corenum, PhyEP / 2) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
\r
308 uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
\r
309 pDTD->NextTD = LINK_TERMINATE;
\r
310 pdQueueHead->Mult = mult;
\r
312 else if (((ENDPTCTRL_REG(corenum, PhyEP / 2) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) {// iso in endpoint
\r
313 uint32_t mult = (USB_DATA_BUFFER_TEM_LENGTH + 1024) / 1024;
\r
314 pDTD->NextTD = LINK_TERMINATE;
\r
315 pdQueueHead->Mult = mult;
\r
317 else { // other endpoint types
\r
318 pDTD->NextTD = LINK_TERMINATE; /* The next DTD pointer is INVALID */
\r
320 pDTD->TotalBytes = length;
\r
321 pDTD->IntOnComplete = 1;
\r
324 pDTD->BufferPage[0] = (uint32_t) pData;
\r
325 pDTD->BufferPage[1] = ((uint32_t) pData + 0x1000) & 0xfffff000;
\r
326 pDTD->BufferPage[2] = ((uint32_t) pData + 0x2000) & 0xfffff000;
\r
327 pDTD->BufferPage[3] = ((uint32_t) pData + 0x3000) & 0xfffff000;
\r
328 pDTD->BufferPage[4] = ((uint32_t) pData + 0x4000) & 0xfffff000;
\r
330 pdQueueHead->overlay.Halted = 0; /* this should be in USBInt */
\r
331 pdQueueHead->overlay.Active = 0; /* this should be in USBInt */
\r
332 pdQueueHead->overlay.NextTD = (uint32_t) &dTransferDescriptor[corenum][PhyEP];
\r
333 pdQueueHead->TransferCount = length;
\r
335 /* prime the endpoint for transmit */
\r
336 USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );
\r
339 void TransferCompleteISR(uint8_t corenum)
\r
341 uint8_t * ISO_Address;
\r
342 IP_USBHS_001_T * USB_Reg = USB_REG(corenum);
\r
343 STREAM_VAR_t * current_stream = &Stream_Variable[corenum];
\r
344 uint32_t ENDPTCOMPLETE = USB_Reg->ENDPTCOMPLETE;
\r
345 USB_Reg->ENDPTCOMPLETE = ENDPTCOMPLETE;
\r
346 if (ENDPTCOMPLETE) {
\r
348 for (n = 0; n < USED_PHYSICAL_ENDPOINTS(corenum) / 2; n++) { /* LOGICAL */
\r
349 if ( ENDPTCOMPLETE & _BIT(n) ) {/* OUT */
\r
350 if (((ENDPTCTRL_REG(corenum, n) >> 2) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso out endpoint
\r
351 uint32_t size = dQueueHead[corenum][2 * n].TransferCount;
\r
352 size -= dQueueHead[corenum][2 * n].overlay.TotalBytes;
\r
353 // copy to share buffer
\r
354 ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
\r
355 DcdDataTransfer(corenum, 2 * n, ISO_Address, USB_DATA_BUFFER_TEM_LENGTH);
\r
359 uint32_t tem = dQueueHead[corenum][2 * n].overlay.TotalBytes;
\r
360 dQueueHead[corenum][2 * n].TransferCount -= tem;
\r
362 if (current_stream->stream_total_packets > 0) {
\r
363 if (current_stream->stream_remain_packets > 0) {
\r
364 uint32_t cnt = dQueueHead[corenum][2 * n].TransferCount;
\r
365 Endpoint_Streaming(corenum,(uint8_t *) current_stream->stream_buffer_address,
\r
366 current_stream->stream_packet_size,
\r
367 current_stream->stream_remain_packets,
\r
369 dQueueHead[corenum][2 * n].TransferCount = cnt;
\r
372 current_stream->stream_total_packets = 0;
\r
373 dQueueHead[corenum][2 * n].IsOutReceived = 1;
\r
377 //stream_total_packets = 0;
\r
378 dQueueHead[corenum][2 * n].IsOutReceived = 1;
\r
381 usb_data_buffer_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;
\r
384 usb_data_buffer_OUT_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;
\r
387 EVENT_USB_Device_TransferComplete(n, 0);
\r
389 if ( ENDPTCOMPLETE & _BIT( (n + 16) ) ) { /* IN */
\r
390 if (((ENDPTCTRL_REG(corenum, n) >> 18) & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) { // iso in endpoint
\r
392 ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);
\r
393 DcdDataTransfer(corenum, 2 * n + 1, ISO_Address, size);
\r
396 if (current_stream->stream_remain_packets > 0) {
\r
397 uint32_t cnt = dQueueHead[corenum][2 * n].TransferCount;
\r
398 Endpoint_Streaming(corenum, (uint8_t *) current_stream->stream_buffer_address,
\r
399 current_stream->stream_packet_size,
\r
400 current_stream->stream_remain_packets,
\r
402 dQueueHead[corenum][2 * n].TransferCount = cnt;
\r
405 current_stream->stream_total_packets = 0;
\r
408 EVENT_USB_Device_TransferComplete(n, 1);
\r
414 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData)
\r
416 USB_Request_Header_t * ctrlrq = (USB_Request_Header_t *) pData;
\r
417 volatile DeviceQueueHead* pdQueueHead = &(dQueueHead[corenum][0]);
\r
418 memcpy(pData, (void *) pdQueueHead->SetupPackage, 8);
\r
419 /* Below fix is to prevent Endpoint_Read_Control_Stream_LE()
\r
420 * from getting wrong data*/
\r
423 (ctrlrq->wLength != 0)
\r
425 pdQueueHead->IsOutReceived = 0;
\r
429 void DcdIrqHandler(uint8_t corenum)
\r
432 IP_USBHS_001_T * USB_Reg = USB_REG(corenum);
\r
433 uint32_t t = USB_Reg->USBINTR_D;
\r
435 USBSTS_D = USB_Reg->USBSTS_D & t; /* Device Interrupt Status */
\r
436 if (USBSTS_D == 0) {/* avoid to clear disabled interrupt source */
\r
440 USB_Reg->USBSTS_D = USBSTS_D; /* Acknowledge Interrupt */
\r
442 /* Process Interrupt Sources */
\r
443 if (USBSTS_D & USBSTS_D_UsbInt) {
\r
444 if (USB_Reg->ENDPTSETUPSTAT) {
\r
445 // memcpy(SetupPackage, dQueueHead[0].SetupPackage, 8);
\r
446 /* Will be cleared by Endpoint_ClearSETUP */
\r
449 if (USB_Reg->ENDPTCOMPLETE) {
\r
450 TransferCompleteISR(corenum);
\r
454 if (USBSTS_D & USBSTS_D_NAK) { /* NAK */
\r
455 uint32_t ENDPTNAK = USB_Reg->ENDPTNAK;
\r
456 uint32_t en = USB_Reg->ENDPTNAKEN;
\r
458 USB_Reg->ENDPTNAK = ENDPTNAK;
\r
460 if (ENDPTNAK) { /* handle NAK interrupts */
\r
462 for (LogicalEP = 0; LogicalEP < USED_PHYSICAL_ENDPOINTS(corenum) / 2; LogicalEP++)
\r
463 if (ENDPTNAK & _BIT(LogicalEP)) { /* Only OUT Endpoint is NAK enable */
\r
464 uint8_t PhyEP = 2 * LogicalEP;
\r
465 if ( !(USB_Reg->ENDPTSTAT & _BIT(LogicalEP)) ) {/* Is In ready */
\r
466 /* Check read OUT flag */
\r
467 if (!dQueueHead[corenum][PhyEP].IsOutReceived) {
\r
470 usb_data_buffer_size[corenum] = 0;
\r
471 USB_Reg->ENDPTNAKEN &= ~(1 << 0);
\r
472 DcdDataTransfer(corenum, PhyEP, usb_data_buffer[corenum], 512);
\r
475 if (Stream_Variable[corenum].stream_total_packets == 0) {
\r
476 usb_data_buffer_OUT_size[corenum] = 0;
\r
478 USB_Reg->ENDPTNAKEN &= ~(1 << LogicalEP);
\r
479 DcdDataTransfer(corenum, PhyEP, usb_data_buffer_OUT[corenum], 512 /*512*/);
\r
488 if (USBSTS_D & USBSTS_D_SofReceived) { /* Start of Frame Interrupt */
\r
489 EVENT_USB_Device_StartOfFrame();
\r
492 if (USBSTS_D & USBSTS_D_ResetReceived) { /* Reset */
\r
493 HAL_Reset(corenum);
\r
494 USB_DeviceState[corenum] = DEVICE_STATE_Default;
\r
495 Endpoint_ConfigureEndpoint(corenum,
\r
496 ENDPOINT_CONTROLEP,
\r
499 USB_Device_ControlEndpointSize,
\r
501 Endpoint_ConfigureEndpoint(corenum,
\r
502 ENDPOINT_CONTROLEP,
\r
505 USB_Device_ControlEndpointSize,
\r
509 if (USBSTS_D & USBSTS_D_SuspendInt) { /* Suspend */
\r
513 if (USBSTS_D & USBSTS_D_PortChangeDetect) { /* Resume */
\r
517 if (USBSTS_D & USBSTS_D_UsbErrorInt) { /* Error Interrupt */
\r
522 uint32_t Dummy_EPGetISOAddress(uint32_t EPNum, uint32_t *last_packet_size)
\r
524 return (uint32_t) iso_buffer;
\r
527 /*********************************************************************//**
\r
528 * @brief Dummy USB device transfer complete event
\r
529 * @param[in] logicalEP Logical endpoint number
\r
530 * @param[in] xfer_in If this argument is 0 then xfer type is out, else in
\r
531 * @note This event is required for running the stack with RTOS
\r
532 * and so it should never be removed!
\r
534 **********************************************************************/
\r
535 void Dummy_EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)
\r
538 * This is a dummy function
\r
539 * If xfer_in zero then the endpoint it OUT
\r
545 #endif /*__LPC18XX__*/
\r