Skip to content

Commit 6a708d1

Browse files
authored
Merge pull request #5878 from c1728p9/lpc_usb_stability_fixes
LPC USB stability fixes
2 parents ff08b10 + 6fe0aa0 commit 6a708d1

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

features/unsupported/USBDevice/targets/TARGET_NXP/USBHAL_LPC17.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,11 +275,6 @@ uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
275275

276276
LPC_USB->USBCtrl = 0;
277277

278-
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
279-
SIEselectEndpoint(endpoint);
280-
SIEclearBuffer();
281-
}
282-
283278
return size;
284279
}
285280

@@ -431,7 +426,7 @@ void USBHAL::EP0setup(uint8_t *buffer) {
431426
}
432427

433428
void USBHAL::EP0read(void) {
434-
// Not required
429+
endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
435430
}
436431

437432
void USBHAL::EP0readStage(void) {
@@ -456,6 +451,11 @@ void USBHAL::EP0stall(void) {
456451
}
457452

458453
EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
454+
// Don't clear isochronous endpoints
455+
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
456+
SIEselectEndpoint(endpoint);
457+
SIEclearBuffer();
458+
}
459459
return EP_PENDING;
460460
}
461461

@@ -590,6 +590,25 @@ void USBHAL::usbisr(void) {
590590
if (LPC_USB->USBDevIntSt & EP_SLOW) {
591591
// (Slow) Endpoint Interrupt
592592

593+
// Process IN packets before SETUP packets
594+
// Note - order of OUT and SETUP does not matter as OUT packets
595+
// are clobbered by SETUP packets and thus ignored.
596+
//
597+
// A SETUP packet can arrive at any time where as an IN packet is
598+
// only sent after calling EP0write and an OUT packet after EP0read.
599+
// The functions EP0write and EP0read are called only in response to
600+
// a setup packet or IN/OUT packets sent in response to that
601+
// setup packet. Therefore, if an IN or OUT packet is pending
602+
// at the same time as a SETUP packet, the IN or OUT packet belongs
603+
// to the previous control transfer and should either be processed
604+
// before the SETUP packet (in the case of IN) or dropped (in the
605+
// case of OUT as SETUP clobbers the OUT data).
606+
if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
607+
selectEndpointClearInterrupt(EP0IN);
608+
LPC_USB->USBDevIntClr = EP_SLOW;
609+
EP0in();
610+
}
611+
593612
// Process each endpoint interrupt
594613
if (LPC_USB->USBEpIntSt & EP(EP0OUT)) {
595614
if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
@@ -601,12 +620,6 @@ void USBHAL::usbisr(void) {
601620
LPC_USB->USBDevIntClr = EP_SLOW;
602621
}
603622

604-
if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
605-
selectEndpointClearInterrupt(EP0IN);
606-
LPC_USB->USBDevIntClr = EP_SLOW;
607-
EP0in();
608-
}
609-
610623
for (uint8_t num = 2; num < 16*2; num++) {
611624
if (LPC_USB->USBEpIntSt & EP(num)) {
612625
selectEndpointClearInterrupt(num);

features/unsupported/USBDevice/targets/TARGET_NXP/USBHAL_LPC40.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,6 @@ uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
276276

277277
LPC_USB->Ctrl = 0;
278278

279-
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
280-
SIEselectEndpoint(endpoint);
281-
SIEclearBuffer();
282-
}
283-
284279
return size;
285280
}
286281

@@ -436,7 +431,7 @@ void USBHAL::EP0setup(uint8_t *buffer) {
436431
}
437432

438433
void USBHAL::EP0read(void) {
439-
// Not required
434+
endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
440435
}
441436

442437
void USBHAL::EP0readStage(void) {
@@ -461,6 +456,11 @@ void USBHAL::EP0stall(void) {
461456
}
462457

463458
EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
459+
// Don't clear isochronous endpoints
460+
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
461+
SIEselectEndpoint(endpoint);
462+
SIEclearBuffer();
463+
}
464464
return EP_PENDING;
465465
}
466466

@@ -595,6 +595,25 @@ void USBHAL::usbisr(void) {
595595
if (LPC_USB->DevIntSt & EP_SLOW) {
596596
// (Slow) Endpoint Interrupt
597597

598+
// Process IN packets before SETUP packets
599+
// Note - order of OUT and SETUP does not matter as OUT packets
600+
// are clobbered by SETUP packets and thus ignored.
601+
//
602+
// A SETUP packet can arrive at any time where as an IN packet is
603+
// only sent after calling EP0write and an OUT packet after EP0read.
604+
// The functions EP0write and EP0read are called only in response to
605+
// a setup packet or IN/OUT packets sent in response to that
606+
// setup packet. Therefore, if an IN or OUT packet is pending
607+
// at the same time as a SETUP packet, the IN or OUT packet belongs
608+
// to the previous control transfer and should either be processed
609+
// before the SETUP packet (in the case of IN) or dropped (in the
610+
// case of OUT as SETUP clobbers the OUT data).
611+
if (LPC_USB->EpIntSt & EP(EP0IN)) {
612+
selectEndpointClearInterrupt(EP0IN);
613+
LPC_USB->DevIntClr = EP_SLOW;
614+
EP0in();
615+
}
616+
598617
// Process each endpoint interrupt
599618
if (LPC_USB->EpIntSt & EP(EP0OUT)) {
600619
if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
@@ -606,12 +625,6 @@ void USBHAL::usbisr(void) {
606625
LPC_USB->DevIntClr = EP_SLOW;
607626
}
608627

609-
if (LPC_USB->EpIntSt & EP(EP0IN)) {
610-
selectEndpointClearInterrupt(EP0IN);
611-
LPC_USB->DevIntClr = EP_SLOW;
612-
EP0in();
613-
}
614-
615628
for (uint8_t num = 2; num < 16*2; num++) {
616629
if (LPC_USB->EpIntSt & EP(num)) {
617630
selectEndpointClearInterrupt(num);

0 commit comments

Comments
 (0)