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