2 * @brief USB Endpoint definitions for the LPC11Uxx 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(__LPC11U1X__) || defined(__LPC11U2X_3X__) || defined(__LPC1347__)) && defined(USB_CAN_BE_DEVICE)
\r
36 #include "../../Endpoint.h"
\r
38 #if defined(USB_DEVICE_ROM_DRIVER)
\r
41 uint8_t usb_RomDriver_buffer[ROMDRIVER_MEM_SIZE] ATTR_ALIGNED(256);
\r
43 uint8_t usb_RomDriver_MSC_buffer[ROMDRIVER_MSC_MEM_SIZE] ATTR_ALIGNED(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
48 uint8_t UsbdCdc_EPIN_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4);
\r
49 /** Endpoint OUT buffer, used for DMA operation */
\r
51 uint8_t UsbdCdc_EPOUT_buffer[CDC_MAX_BULK_EP_SIZE] ATTR_ALIGNED(4);
\r
53 uint8_t usb_RomDriver_HID_buffer[ROMDRIVER_HID_MEM_SIZE] ATTR_ALIGNED(4);
\r
57 #define IsOutEndpoint(PhysicalEP) (!((PhysicalEP) & 1) )
\r
59 /*static*/ USB_CMD_STAT EndPointCmdStsList[USED_PHYSICAL_ENDPOINTS][2] __BSS(USBRAM_SECTION) ATTR_ALIGNED(256);/* 10 endpoints with 2 buffers each */
\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
67 void HAL_Reset(void)
\r
69 LPC_USB->EPINUSE = 0;
\r
70 LPC_USB->EPSKIP = 0xFFFFFFFF;
\r
71 LPC_USB->EPBUFCFG = 0;
\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
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
85 memset(EndPointCmdStsList, 0, sizeof(EndPointCmdStsList) );
\r
87 HAL_SetDeviceAddress(0);
\r
89 shortpacket = epout_primed = false;
\r
93 bool Endpoint_ConfigureEndpointControl(const uint16_t Size)
\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
101 EndPointCmdStsList[0][1].BufferAddrOffset = ( ((uint32_t) SetupPackage) >> 6) & 0xFFFF;
\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
108 LPC_USB->INTSTAT &= ~3;
\r
109 LPC_USB->INTEN |= 3;
\r
111 EndpointMaxPacketSize[0] = EndpointMaxPacketSize[1] = Size;
\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
119 uint32_t PhyEP = 2 * Number + (Direction == ENDPOINT_DIR_OUT ? 0 : 1);
\r
121 memset(EndPointCmdStsList[PhyEP], 0, sizeof(USB_CMD_STAT) * 2);
\r
122 EndPointCmdStsList[PhyEP][0].NBytes = IsOutEndpoint(PhyEP) ? 0x200 : 0;
\r
124 LPC_USB->INTSTAT &= ~(1 << PhyEP);
\r
125 LPC_USB->INTEN |= (1 << PhyEP);
\r
127 EndpointMaxPacketSize[PhyEP] = Size;
\r
128 endpointhandle(corenum)[Number] = (Number == ENDPOINT_CONTROLEP) ? ENDPOINT_CONTROLEP : PhyEP;
\r
133 void Endpoint_Streaming(uint8_t corenum, uint8_t *buffer, uint16_t packetsize,
\r
134 uint16_t totalpackets, uint16_t dummypackets)
\r
136 uint8_t PhyEP = endpointhandle(corenum)[endpointselected[corenum]];
\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
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
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
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
163 stream_total_packets = 0;
\r
167 void DcdDataTransfer(uint8_t EPNum, uint8_t *pData, uint32_t length)
\r
170 if (length >= EndpointMaxPacketSize[EPNum]) {
\r
171 if ((length == EndpointMaxPacketSize[EPNum]) && (EPNum == 1)) {
\r
172 shortpacket = true;
\r
174 Remain_length[EPNum / 2] = length - EndpointMaxPacketSize[EPNum];
\r
175 length = EndpointMaxPacketSize[EPNum];
\r
178 Remain_length[EPNum / 2] = 0;
\r
180 EndPointCmdStsList[EPNum][0].NBytes = length;
\r
182 EndPointCmdStsList[EPNum][0].BufferAddrOffset = ( ((uint32_t) pData) >> 6 ) & 0xFFFF;
\r
184 EndPointCmdStsList[EPNum][0].Active = 1;
\r
187 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData)
\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
195 void USB_IRQHandler(void)
\r
198 #if defined(USB_DEVICE_ROM_DRIVER)
\r
199 UsbdRom_IrqHandler();
\r
201 uint32_t IntStat = LPC_USB->INTSTAT;
\r
202 uint32_t IntEn = LPC_USB->INTEN;
\r
204 IntStat &= IntEn; /* Get Interrupt Status and clear immediately. */
\r
206 if (IntStat == 0) {
\r
210 LPC_USB->INTSTAT = IntStat;
\r
212 /* SOF Interrupt */
\r
213 if (IntStat & FRAME_INT) {}
\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
219 if (DevCmdStat & USB_DRESET_C) { /* Reset */
\r
220 LPC_USB->DEVCMDSTAT |= USB_DRESET_C;
\r
222 USB_DeviceState[0] = DEVICE_STATE_Default;
\r
223 Endpoint_ConfigureEndpointControl(USB_Device_ControlEndpointSize);
\r
226 if (DevCmdStat & USB_DCON_C) { /* Connect change */
\r
227 LPC_USB->DEVCMDSTAT |= USB_DCON_C;
\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
234 else { /* Resume */
\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
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
248 DcdDataTransfer(PhyEP, usb_data_buffer[0], 512);
\r
250 else if (stream_total_packets == 0) {
\r
251 DcdDataTransfer(PhyEP, usb_data_buffer_OUT[0], 512);
\r
253 if ((PhyEP == 0) || (stream_total_packets == 0)) {
\r
254 epout_primed = true;
\r
258 if (epout_primed) {
\r
259 epout_primed = false;
\r
261 usb_data_buffer_size[0] = (512 - EndPointCmdStsList[PhyEP][0].NBytes);
\r
264 usb_data_buffer_OUT_size[0] = (512 - EndPointCmdStsList[PhyEP][0].NBytes);
\r
270 else { /* IN Endpoint */
\r
271 if (Remain_length[PhyEP / 2] > 0) {
\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
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
285 if (PhyEP == 1) { /* Control IN */
\r
287 shortpacket = false;
\r
288 DcdDataTransfer(PhyEP, usb_data_buffer[0], 0);
\r
298 //#endif // defined(USB_DEVICE_ROM_DRIVER)
\r
300 #endif /*__LPC11UXX__ || __LPC1347__*/
\r