]> git.sur5r.net Git - freertos/blob
4d04482e426f909e21e9904922925c851e37c3c3
[freertos] /
1 /*\r
2  * @brief USB Endpoint definitions for the LPC11Uxx 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(__LPC11U1X__) || defined(__LPC11U2X_3X__) || defined(__LPC1347__)) && defined(USB_CAN_BE_DEVICE)\r
36 #include "../../Endpoint.h"\r
37 \r
38 #if defined(USB_DEVICE_ROM_DRIVER)\r
39 \r
40 PRAGMA_ALIGN_256\r
41 uint8_t usb_RomDriver_buffer[ROMDRIVER_MEM_SIZE] ATTR_ALIGNED(256);\r
42 PRAGMA_ALIGN_4\r
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(4);\r
44 PRAGMA_ALIGN_4\r
45 uint8_t usb_RomDriver_CDC_buffer[ROMDRIVER_CDC_MEM_SIZE] ATTR_ALIGNED(4);\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);\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);\r
52 PRAGMA_ALIGN_4\r
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4);\r
54 \r
55 #endif\r
56 \r
57 #define IsOutEndpoint(PhysicalEP)       (!((PhysicalEP) & 1) )\r
58 PRAGMA_ALIGN_256\r
59 /*static*/ USB_CMD_STAT EndPointCmdStsList[USED_PHYSICAL_ENDPOINTS][2] __BSS(USBRAM_SECTION) ATTR_ALIGNED(256);/* 10 endpoints with 2 buffers each */\r
60 PRAGMA_ALIGN_64\r
61 static uint8_t SetupPackage[8] __BSS(USBRAM_SECTION) ATTR_ALIGNED(64);\r
62 uint32_t EndpointMaxPacketSize[USED_PHYSICAL_ENDPOINTS];\r
63 uint32_t Remain_length[ENDPOINT_DETAILS_MAXEP];\r
64 bool shortpacket, epout_primed;\r
65 uint16_t stream_total_packets;\r
66 \r
67 void HAL_Reset(void)\r
68 {\r
69         LPC_USB->EPINUSE = 0;\r
70         LPC_USB->EPSKIP = 0xFFFFFFFF;\r
71         LPC_USB->EPBUFCFG = 0;\r
72 \r
73         LPC_USB->DEVCMDSTAT |= USB_EN | USB_IntOnNAK_AO | USB_IntOnNAK_CO;\r
74         /* Clear all EP interrupts, device status, and SOF interrupts. */\r
75         LPC_USB->INTSTAT = 0xC00003FF;\r
76         /* Enable all ten(10) EPs interrupts including EP0, note: EP won't be\r
77            ready until it's configured/enabled when device sending SetEPStatus command\r
78            to the command engine. */\r
79         LPC_USB->INTEN  = DEV_STAT_INT;\r
80 \r
81         /* Initialize EP Command/Status List. */\r
82         LPC_USB->EPLISTSTART = (uint32_t) EndPointCmdStsList;\r
83         LPC_USB->DATABUFSTART = ((uint32_t) usb_data_buffer) & 0xFFC00000;\r
84 \r
85         memset(EndPointCmdStsList, 0, sizeof(EndPointCmdStsList) );\r
86 \r
87         HAL_SetDeviceAddress(0);\r
88 \r
89         shortpacket = epout_primed = false;\r
90 \r
91 }\r
92 \r
93 bool Endpoint_ConfigureEndpointControl(const uint16_t Size)\r
94 {\r
95         /* Endpoint Control OUT Buffer 0 */\r
96         EndPointCmdStsList[0][0].BufferAddrOffset = 0;\r
97         EndPointCmdStsList[0][0].NBytes = 0x200;\r
98         EndPointCmdStsList[0][0].Active = 0;\r
99 \r
100         /* Setup Buffer */\r
101         EndPointCmdStsList[0][1].BufferAddrOffset = ( ((uint32_t) SetupPackage) >> 6) & 0xFFFF;\r
102 \r
103         /* Endpoint Control IN Buffer 0 */\r
104         EndPointCmdStsList[1][0].BufferAddrOffset = 0;\r
105         EndPointCmdStsList[1][0].NBytes = 0;\r
106         EndPointCmdStsList[1][0].Active = 0;\r
107 \r
108         LPC_USB->INTSTAT &= ~3;\r
109         LPC_USB->INTEN |= 3;\r
110 \r
111         EndpointMaxPacketSize[0] = EndpointMaxPacketSize[1] = Size;\r
112 \r
113         return true;\r
114 }\r
115 \r
116 bool Endpoint_ConfigureEndpoint(uint8_t corenum, const uint8_t Number, const uint8_t Type,\r
117                                                                 const uint8_t Direction, const uint16_t Size, const uint8_t Banks)\r
118 {\r
119         uint32_t PhyEP = 2 * Number + (Direction == ENDPOINT_DIR_OUT ? 0 : 1);\r
120 \r
121         memset(EndPointCmdStsList[PhyEP], 0, sizeof(USB_CMD_STAT) * 2);\r
122         EndPointCmdStsList[PhyEP][0].NBytes = IsOutEndpoint(PhyEP) ? 0x200 : 0;\r
123 \r
124         LPC_USB->INTSTAT &= ~(1 << PhyEP);\r
125         LPC_USB->INTEN |= (1 << PhyEP);\r
126 \r
127         EndpointMaxPacketSize[PhyEP] = Size;\r
128         endpointhandle(corenum)[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;\r
129 \r
130         return true;\r
131 }\r
132 \r
133 void Endpoint_Streaming(uint8_t corenum, uint8_t *buffer, uint16_t packetsize,\r
134                                                 uint16_t totalpackets, uint16_t dummypackets)\r
135 {\r
136         uint8_t PhyEP = endpointhandle(corenum)[endpointselected[corenum]];\r
137         uint16_t i;\r
138 \r
139         if (PhyEP & 1) {\r
140                 for (i = 0; i < totalpackets; i++) {\r
141                         while (!Endpoint_IsReadWriteAllowed(corenum)) ;\r
142                         Endpoint_Write_Stream_LE(corenum,(void *) (buffer + i * packetsize), packetsize, NULL);\r
143                         Endpoint_ClearIN(corenum);\r
144                 }\r
145                 for (i = 0; i < dummypackets; i++) {\r
146                         while (!Endpoint_IsReadWriteAllowed(corenum)) ;\r
147                         Endpoint_Write_Stream_LE(corenum,(void *) buffer, packetsize, NULL);\r
148                         Endpoint_ClearIN(corenum);\r
149                 }\r
150         }\r
151         else {\r
152                 stream_total_packets = totalpackets + dummypackets;\r
153                 for (i = 0; i < totalpackets; i++) {\r
154                         DcdDataTransfer(PhyEP, (uint8_t *) (buffer + i * packetsize), packetsize);\r
155                         Endpoint_ClearOUT(corenum);\r
156                         while (!Endpoint_IsReadWriteAllowed(corenum)) ;\r
157                 }\r
158                 for (i = 0; i < dummypackets; i++) {\r
159                         DcdDataTransfer(PhyEP, buffer, packetsize);\r
160                         Endpoint_ClearOUT(corenum);\r
161                         while (!Endpoint_IsReadWriteAllowed(corenum)) ;\r
162                 }\r
163                 stream_total_packets = 0;\r
164         }\r
165 }\r
166 \r
167 void DcdDataTransfer(uint8_t EPNum, uint8_t *pData, uint32_t length)\r
168 {\r
169         if (EPNum & 1) {\r
170                 if (length >= EndpointMaxPacketSize[EPNum]) {\r
171                         if ((length == EndpointMaxPacketSize[EPNum]) && (EPNum == 1)) {\r
172                                 shortpacket = true;\r
173                         }\r
174                         Remain_length[EPNum / 2] = length - EndpointMaxPacketSize[EPNum];\r
175                         length = EndpointMaxPacketSize[EPNum];\r
176                 }\r
177                 else {\r
178                         Remain_length[EPNum / 2] = 0;\r
179                 }\r
180                 EndPointCmdStsList[EPNum][0].NBytes = length;\r
181         }\r
182         EndPointCmdStsList[EPNum][0].BufferAddrOffset = ( ((uint32_t) pData) >> 6 ) & 0xFFFF;\r
183 \r
184         EndPointCmdStsList[EPNum][0].Active = 1;\r
185 }\r
186 \r
187 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData)\r
188 {\r
189         memcpy(pData, SetupPackage, 8);\r
190         /* Clear endpoint control stall flag if set */\r
191         EndPointCmdStsList[0][0].Stall = 0;\r
192         EndPointCmdStsList[1][0].Stall = 0;\r
193 }\r
194 \r
195 void USB_IRQHandler(void)\r
196 {\r
197         \r
198 #if defined(USB_DEVICE_ROM_DRIVER)\r
199         UsbdRom_IrqHandler();\r
200 #else   \r
201         uint32_t IntStat = LPC_USB->INTSTAT;                    \r
202         uint32_t IntEn = LPC_USB->INTEN;\r
203         \r
204         IntStat &= IntEn;                                                       /* Get Interrupt Status and clear immediately. */\r
205         \r
206         if (IntStat == 0) {\r
207                 return;\r
208         }\r
209 \r
210         LPC_USB->INTSTAT = IntStat;\r
211 \r
212         /* SOF Interrupt */\r
213         if (IntStat & FRAME_INT) {}\r
214 \r
215         /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */\r
216         if (IntStat & DEV_STAT_INT) {\r
217                 uint32_t DevCmdStat = LPC_USB->DEVCMDSTAT;                              /* Device Status */\r
218 \r
219                 if (DevCmdStat & USB_DRESET_C) {                                /* Reset */\r
220                         LPC_USB->DEVCMDSTAT |= USB_DRESET_C;\r
221                         HAL_Reset();\r
222                         USB_DeviceState[0] = DEVICE_STATE_Default;\r
223                         Endpoint_ConfigureEndpointControl(USB_Device_ControlEndpointSize);\r
224                 }\r
225 \r
226                 if (DevCmdStat & USB_DCON_C) {                                  /* Connect change */\r
227                         LPC_USB->DEVCMDSTAT |= USB_DCON_C;\r
228                 }\r
229 \r
230                 if (DevCmdStat & USB_DSUS_C) {                                  /* Suspend/Resume */\r
231                         LPC_USB->DEVCMDSTAT |= USB_DSUS_C;\r
232                         if (DevCmdStat & USB_DSUS) {                            /* Suspend */\r
233                         }\r
234                         else {                                                          /* Resume */\r
235                         }\r
236                 }\r
237         }\r
238 \r
239         /* Endpoint's Interrupt */\r
240         if (IntStat & 0x3FF) {  /* if any of the EP0 through EP9 is set, or bit 0 through 9 on disr */\r
241                 uint32_t PhyEP;\r
242                 for (PhyEP = 0; PhyEP < USED_PHYSICAL_ENDPOINTS; PhyEP++) /* Check All Endpoints */\r
243                         if ( IntStat & (1 << PhyEP) ) {\r
244                                 if ( IsOutEndpoint(PhyEP) ) {   /* OUT Endpoint */\r
245                                         if ( !Endpoint_IsSETUPReceived(0) ) {\r
246                                                 if (EndPointCmdStsList[PhyEP][0].NBytes == 0x200) {\r
247                                                         if (PhyEP == 0) {\r
248                                                                 DcdDataTransfer(PhyEP, usb_data_buffer[0], 512);\r
249                                                         }\r
250                                                         else if (stream_total_packets == 0)   {\r
251                                                                 DcdDataTransfer(PhyEP, usb_data_buffer_OUT[0], 512);\r
252                                                         }\r
253                                                         if ((PhyEP == 0) || (stream_total_packets == 0)) {\r
254                                                                 epout_primed = true;\r
255                                                         }\r
256                                                 }\r
257                                                 else {\r
258                                                         if (epout_primed) {\r
259                                                                 epout_primed = false;\r
260                                                                 if (PhyEP == 0) {\r
261                                                                         usb_data_buffer_size[0] = (512 - EndPointCmdStsList[PhyEP][0].NBytes);\r
262                                                                 }\r
263                                                                 else {\r
264                                                                         usb_data_buffer_OUT_size[0] = (512 - EndPointCmdStsList[PhyEP][0].NBytes);\r
265                                                                 }\r
266                                                         }\r
267                                                 }\r
268                                         }\r
269                                 }\r
270                                 else {                                                          /* IN Endpoint */\r
271                                         if (Remain_length[PhyEP / 2] > 0) {\r
272                                                 uint32_t i;\r
273                                                 if (PhyEP == 1) {       /* Control IN */\r
274                                                         for (i = 0; i < Remain_length[PhyEP / 2]; i++)\r
275                                                                 usb_data_buffer[0][i] = usb_data_buffer[0][i + EndpointMaxPacketSize[PhyEP]];\r
276                                                         DcdDataTransfer(PhyEP, usb_data_buffer[0], Remain_length[PhyEP / 2]);\r
277                                                 }\r
278                                                 else {\r
279                                                         for (i = 0; i < Remain_length[PhyEP / 2]; i++)\r
280                                                                 usb_data_buffer_IN[0][i] = usb_data_buffer_IN[0][i + EndpointMaxPacketSize[PhyEP]];\r
281                                                         DcdDataTransfer(PhyEP, usb_data_buffer_IN[0], Remain_length[PhyEP / 2]);\r
282                                                 }\r
283                                         }\r
284                                         else {\r
285                                                 if (PhyEP == 1) {       /* Control IN */\r
286                                                         if (shortpacket) {\r
287                                                                 shortpacket = false;\r
288                                                                 DcdDataTransfer(PhyEP, usb_data_buffer[0], 0);\r
289                                                         }\r
290                                                 }\r
291                                         }\r
292                                 }\r
293                         }\r
294         }\r
295 #endif\r
296 }\r
297 \r
298 //#endif        // defined(USB_DEVICE_ROM_DRIVER)\r
299 \r
300 #endif /*__LPC11UXX__ || __LPC1347__*/\r