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