]> git.sur5r.net Git - freertos/blob
e6ce0178bc922fb118005146e4c0bc9b1ace649e
[freertos] /
1 /*\r
2  * @brief USB Endpoint definitions for the LPC18xx microcontrollers\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * All rights reserved.\r
7  *\r
8  * @par\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
22  *\r
23  * @par\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
29  * this code.\r
30  */\r
31 \r
32 #define  __INCLUDE_FROM_USB_DRIVER\r
33 #include "../../USBMode.h"\r
34 \r
35 #if (defined(__LPC18XX__) || defined(__LPC43XX__)) && defined(USB_CAN_BE_DEVICE)\r
36 #include "../../Endpoint.h"\r
37 #include <string.h>\r
38 \r
39 #if defined(USB_DEVICE_ROM_DRIVER)\r
40 PRAGMA_ALIGN_2048\r
41 uint8_t usb_RomDriver_buffer[ROMDRIVER_MEM_SIZE] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);\r
42 PRAGMA_ALIGN_4\r
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);\r
44 PRAGMA_ALIGN_4\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
47 PRAGMA_ALIGN_4\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
50 PRAGMA_ALIGN_4\r
51 uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);\r
52 PRAGMA_ALIGN_4\r
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4) __BSS(USBRAM_SECTION);\r
54 \r
55 #endif\r
56 \r
57 #define STREAM_TDs      16\r
58 \r
59 PRAGMA_ALIGN_2048\r
60 volatile DeviceQueueHead dQueueHead0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);\r
61 PRAGMA_ALIGN_2048\r
62 volatile DeviceQueueHead dQueueHead1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(2048) __BSS(USBRAM_SECTION);\r
63 PRAGMA_ALIGN_32\r
64 DeviceTransferDescriptor dTransferDescriptor0[USED_PHYSICAL_ENDPOINTS0] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);\r
65 PRAGMA_ALIGN_32\r
66 DeviceTransferDescriptor dTransferDescriptor1[USED_PHYSICAL_ENDPOINTS1] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);\r
67 PRAGMA_ALIGN_32\r
68 DeviceTransferDescriptor dStreamTD0[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);\r
69 PRAGMA_ALIGN_32\r
70 DeviceTransferDescriptor dStreamTD1[STREAM_TDs] ATTR_ALIGNED(32) __BSS(USBRAM_SECTION);\r
71 PRAGMA_ALIGN_4\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
76 \r
77 typedef struct {\r
78         uint32_t stream_buffer_address,\r
79                         stream_dummy_buffer_address,\r
80                         stream_remain_packets,\r
81                         stream_dummy_packets,\r
82                         stream_packet_size,\r
83                         stream_total_packets;\r
84 } STREAM_VAR_t;\r
85 \r
86 static STREAM_VAR_t Stream_Variable[LPC18_43_MAX_USB_CORE];\r
87 \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
91 \r
92 /* Device transfer completed event\r
93  * Event is required for using the device stack with any RTOS\r
94  */\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
97 \r
98 void DcdInsertTD(uint32_t head, uint32_t newtd);\r
99 \r
100 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC);\r
101 \r
102 void HAL_Reset(uint8_t corenum)\r
103 {\r
104         uint32_t i;\r
105         IP_USBHS_001_T * USB_Reg;\r
106         USB_Reg = USB_REG(corenum);\r
107 \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
116         }\r
117 \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
127 \r
128         /* Set the interrupt Threshold control interval to 0 */\r
129         USB_Reg->USBCMD_D &= ~0x00FF0000;\r
130 \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
135 \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
140 \r
141         USB_Device_SetDeviceAddress(corenum, 0);\r
142 \r
143         endpointselected[corenum] = 0;\r
144         for (i = 0; i < ENDPOINT_TOTAL_ENDPOINTS(corenum); i++)\r
145                 endpointhandle(corenum)[i] = 0;\r
146 \r
147         usb_data_buffer_size[corenum] = 0;\r
148         usb_data_buffer_index[corenum] = 0;\r
149 \r
150         usb_data_buffer_OUT_size[corenum] = 0;\r
151         usb_data_buffer_OUT_index[corenum] = 0;\r
152 \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
156 }\r
157 \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
160 {\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
166         \r
167         pdQueueHead = &(dQueueHead[corenum][PhyEP]);\r
168         memset((void *) pdQueueHead, 0, sizeof(DeviceQueueHead) );\r
169         \r
170         pdQueueHead->MaxPacketSize = Size & 0x3ff;\r
171         pdQueueHead->IntOnSetup = 1;\r
172         pdQueueHead->ZeroLengthTermination = 1;\r
173         pdQueueHead->overlay.NextTD = LINK_TERMINATE;\r
174 \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
179                         uint32_t size = 0;\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
183                 }\r
184                 else {\r
185                         USB_REG(corenum)->ENDPTNAKEN |=  (1 << EP_Physical2BitPosition(PhyEP));\r
186                 }\r
187         }\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
192                         uint32_t size = 0;\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
196                 }\r
197         }\r
198         *pEndPointCtrl = EndPtCtrl;\r
199 \r
200         endpointhandle(corenum)[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;\r
201         return true;\r
202 }\r
203 \r
204 void Endpoint_Streaming(uint8_t corenum, uint8_t *buffer, uint16_t packetsize,\r
205                                                 uint16_t totalpackets, uint16_t dummypackets)\r
206 {\r
207         uint8_t PhyEP = endpointhandle(corenum)[endpointselected[corenum]];\r
208         uint16_t i;\r
209         volatile DeviceQueueHead * pdQueueHead;\r
210 #if 0\r
211         for (i = 0; i < totalpackets; i++) {\r
212                 DcdDataTransfer(corenum, PhyEP, (uint8_t *) (buffer + i * packetsize), packetsize);\r
213                 while (!(\r
214                                    (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)\r
215                                    && (dQueueHead[PhyEP].overlay.Active == 0)\r
216                                    )\r
217                            ) ;\r
218         }\r
219         for (i = 0; i < dummypackets; i++) {\r
220                 DcdDataTransfer(corenum, PhyEP, buffer, packetsize);\r
221                 while (!(\r
222                                    (dQueueHead[PhyEP].overlay.NextTD & LINK_TERMINATE)\r
223                                    && (dQueueHead[PhyEP].overlay.Active == 0)\r
224                                    )\r
225                            ) ;\r
226         }\r
227 #else\r
228         STREAM_VAR_t * current_stream = &Stream_Variable[corenum];\r
229         DeviceTransferDescriptor *dStreamTD = dStreamTD_Tbl[corenum];\r
230         uint16_t cnt = 0;\r
231         dummypackets = dummypackets;\r
232         while ( USB_REG(corenum)->ENDPTSTAT & _BIT(EP_Physical2BitPosition(PhyEP) ) ) { /* Endpoint is already primed */\r
233         }\r
234 \r
235         for (i = 0; i < totalpackets; i++) {\r
236                 uint8_t ioc;\r
237                 if (i == STREAM_TDs) {\r
238                         break;\r
239                 }\r
240                 if ((i == totalpackets - 1) || (i == STREAM_TDs - 1)) {\r
241                         ioc = 1;\r
242                 }\r
243                 else {\r
244                         ioc = 0;\r
245                 }\r
246 \r
247                 DcdPrepareTD(&dStreamTD[i], (uint8_t *) (buffer + i * packetsize), packetsize, ioc);\r
248                 if (i > 0) {\r
249                         DcdInsertTD((uint32_t) dStreamTD, (uint32_t) &dStreamTD[i]);\r
250                 }\r
251                 cnt++;\r
252         }\r
253 \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
258         }\r
259         else {\r
260                 current_stream->stream_remain_packets = current_stream->stream_buffer_address = current_stream->stream_packet_size = 0;\r
261         }\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
269 \r
270         USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );\r
271 #endif\r
272 }\r
273 \r
274 void DcdInsertTD(uint32_t head, uint32_t newtd)\r
275 {\r
276         DeviceTransferDescriptor *pTD = (DeviceTransferDescriptor *) head;\r
277         while (!(pTD->NextTD & LINK_TERMINATE)) pTD = (DeviceTransferDescriptor *) pTD->NextTD;\r
278         pTD->NextTD = newtd;\r
279 }\r
280 \r
281 void DcdPrepareTD(DeviceTransferDescriptor *pDTD, uint8_t *pData, uint32_t length, uint8_t IOC)\r
282 {\r
283         /* Zero out the device transfer descriptors */\r
284         memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));\r
285 \r
286         pDTD->NextTD = LINK_TERMINATE;\r
287         pDTD->TotalBytes = length;\r
288         pDTD->IntOnComplete = IOC;\r
289         pDTD->Active = 1;\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
295 }\r
296 \r
297 void DcdDataTransfer(uint8_t corenum, uint8_t PhyEP, uint8_t *pData, uint32_t length)\r
298 {\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
302         }\r
303 \r
304         /* Zero out the device transfer descriptors */\r
305         memset((void *) pDTD, 0, sizeof(DeviceTransferDescriptor));\r
306 \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
311         }\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
316         }\r
317         else {                                                                                                                                          // other endpoint types\r
318                 pDTD->NextTD = LINK_TERMINATE;  /* The next DTD pointer is INVALID */\r
319         }\r
320         pDTD->TotalBytes = length;\r
321         pDTD->IntOnComplete = 1;\r
322         pDTD->Active = 1;\r
323 \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
329 \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
334 \r
335         /* prime the endpoint for transmit */\r
336         USB_REG(corenum)->ENDPTPRIME |= _BIT(EP_Physical2BitPosition(PhyEP) );\r
337 }\r
338 \r
339 void TransferCompleteISR(uint8_t corenum)\r
340 {\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
347                 uint8_t n;\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
356                                 }\r
357                                 else {\r
358                                         \r
359                                         uint32_t tem = dQueueHead[corenum][2 * n].overlay.TotalBytes;\r
360                                         dQueueHead[corenum][2 * n].TransferCount -= tem;\r
361 \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
368                                                                                            0);\r
369                                                         dQueueHead[corenum][2 * n].TransferCount = cnt;\r
370                                                 }\r
371                                                 else {\r
372                                                         current_stream->stream_total_packets = 0;\r
373                                                         dQueueHead[corenum][2 * n].IsOutReceived = 1;\r
374                                                 }\r
375                                         }\r
376                                         else {\r
377                                                 //stream_total_packets = 0;\r
378                                                 dQueueHead[corenum][2 * n].IsOutReceived = 1;\r
379                                         }\r
380                                         if (n == 0) {\r
381                                                 usb_data_buffer_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;\r
382                                         }\r
383                                         else {\r
384                                                 usb_data_buffer_OUT_size[corenum] = dQueueHead[corenum][2 * n].TransferCount;\r
385                                         }\r
386                                 }\r
387                                 EVENT_USB_Device_TransferComplete(n, 0);\r
388                         }\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
391                                         uint32_t size;\r
392                                         ISO_Address = (uint8_t *) CALLBACK_HAL_GetISOBufferAddress(n, &size);\r
393                                         DcdDataTransfer(corenum, 2 * n + 1, ISO_Address, size);\r
394                                 }\r
395                                 else {\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
401                                                                                    0);\r
402                                                 dQueueHead[corenum][2 * n].TransferCount = cnt;\r
403                                         }\r
404                                         else {\r
405                                                 current_stream->stream_total_packets = 0;\r
406                                         }\r
407                                 }\r
408                                 EVENT_USB_Device_TransferComplete(n, 1);\r
409                         }\r
410                 }\r
411         }\r
412 }\r
413 \r
414 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData)\r
415 {\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
421 \r
422         if (\r
423                 (ctrlrq->wLength != 0)\r
424                 ) {\r
425                 pdQueueHead->IsOutReceived = 0;\r
426         }\r
427 }\r
428 \r
429 void DcdIrqHandler(uint8_t corenum)\r
430 {\r
431         uint32_t USBSTS_D;\r
432         IP_USBHS_001_T *        USB_Reg = USB_REG(corenum);\r
433         uint32_t t = USB_Reg->USBINTR_D;\r
434 \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
437                 return;\r
438         }\r
439 \r
440         USB_Reg->USBSTS_D = USBSTS_D;   /* Acknowledge Interrupt */\r
441 \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
447                 }\r
448 \r
449                 if (USB_Reg->ENDPTCOMPLETE) {\r
450                         TransferCompleteISR(corenum);\r
451                 }\r
452         }\r
453 \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
457                 ENDPTNAK &= en;\r
458                 USB_Reg->ENDPTNAK = ENDPTNAK;\r
459 \r
460                 if (ENDPTNAK) { /* handle NAK interrupts */\r
461                         uint8_t LogicalEP;\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
468 \r
469                                                         if (PhyEP == 0) {\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
473                                                         }\r
474                                                         else {\r
475                                                                 if (Stream_Variable[corenum].stream_total_packets == 0) {\r
476                                                                         usb_data_buffer_OUT_size[corenum] = 0;\r
477                                                                         /* Clear NAK */\r
478                                                                         USB_Reg->ENDPTNAKEN &= ~(1 << LogicalEP);\r
479                                                                         DcdDataTransfer(corenum, PhyEP, usb_data_buffer_OUT[corenum], 512       /*512*/);\r
480                                                                 }\r
481                                                         }\r
482                                                 }\r
483                                         }\r
484                                 }\r
485                 }\r
486         }\r
487 \r
488         if (USBSTS_D & USBSTS_D_SofReceived) {                                  /* Start of Frame Interrupt */\r
489                 EVENT_USB_Device_StartOfFrame();\r
490         }\r
491 \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
497                                                                    EP_TYPE_CONTROL,\r
498                                                                    ENDPOINT_DIR_OUT,\r
499                                                                    USB_Device_ControlEndpointSize,\r
500                                                                    0);\r
501                 Endpoint_ConfigureEndpoint(corenum, \r
502                                                                          ENDPOINT_CONTROLEP,\r
503                                                                    EP_TYPE_CONTROL,\r
504                                                                    ENDPOINT_DIR_IN,\r
505                                                                    USB_Device_ControlEndpointSize,\r
506                                                                    0);\r
507         }\r
508 \r
509         if (USBSTS_D & USBSTS_D_SuspendInt) {                                   /* Suspend */\r
510 \r
511         }\r
512 \r
513         if (USBSTS_D & USBSTS_D_PortChangeDetect) {                                     /* Resume */\r
514 \r
515         }\r
516 \r
517         if (USBSTS_D & USBSTS_D_UsbErrorInt) {                                  /* Error Interrupt */\r
518                 // while(1){}\r
519         }\r
520 }\r
521 \r
522 uint32_t Dummy_EPGetISOAddress(uint32_t EPNum, uint32_t *last_packet_size)\r
523 {\r
524         return (uint32_t) iso_buffer;\r
525 }\r
526 \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
533  * @return              None\r
534  **********************************************************************/\r
535 void Dummy_EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)\r
536 {\r
537         /**\r
538          * This is a dummy function\r
539          * If xfer_in zero then the endpoint it OUT\r
540          * else ep is IN.\r
541          **/\r
542 }\r
543 // #endif\r
544 \r
545 #endif /*__LPC18XX__*/\r