Skip to content

Commit 6f1e632

Browse files
c1728p90xc0170
authored andcommitted
Improve LPC1768 USB stability
Make the following changes to improve stability: -When disconnecting set address to disabled to prevent nacks -Clear EP_SLOW one and only once for every interrupt where it is set_address -Disable and clear control endpoint interrupts when disconnecting
1 parent 7731a16 commit 6f1e632

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

targets/TARGET_NXP/TARGET_LPC176X/usb/USBHAL_LPC17.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,11 @@ static uint8_t SIEgetDeviceStatus(void)
161161
return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
162162
}
163163

164-
void SIEsetAddress(uint8_t address)
164+
void SIEsetAddress(uint8_t address, bool enable=true)
165165
{
166166
// Write SIE device address register
167167
SIECommand(SIE_CMD_SET_ADDRESS);
168-
SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
168+
SIEWriteData((address & 0x7f) | (enable ? SIE_DSA_DEV_EN : 0));
169169
}
170170

171171
static uint8_t SIEselectEndpoint(uint8_t endpoint)
@@ -402,8 +402,8 @@ void USBPhyHw::init(USBPhyEvents *events)
402402

403403
// Enable interrupts for device events and EP0
404404
LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
405-
enableEndpointEvent(EP0IN);
406-
enableEndpointEvent(EP0OUT);
405+
406+
NVIC_EnableIRQ(USB_IRQn);
407407
}
408408

409409
void USBPhyHw::deinit()
@@ -422,14 +422,28 @@ bool USBPhyHw::powered()
422422

423423
void USBPhyHw::connect(void)
424424
{
425-
NVIC_EnableIRQ(USB_IRQn);
425+
enableEndpointEvent(EP0IN);
426+
enableEndpointEvent(EP0OUT);
427+
426428
// Connect USB device
427429
SIEconnect();
428430
}
429431

430432
void USBPhyHw::disconnect(void)
431433
{
432-
NVIC_DisableIRQ(USB_IRQn);
434+
disableEndpointEvent(EP0IN);
435+
disableEndpointEvent(EP0OUT);
436+
437+
if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
438+
selectEndpointClearInterrupt(EP0IN);
439+
}
440+
if (LPC_USB->USBEpIntSt & EP(EP0OUT)) {
441+
selectEndpointClearInterrupt(EP0OUT);
442+
}
443+
444+
// Turn off USB nacking
445+
SIEsetAddress(0, false);
446+
433447
// Disconnect USB device
434448
SIEdisconnect();
435449
}
@@ -696,7 +710,6 @@ void USBPhyHw::process(void)
696710
// case of OUT as SETUP clobbers the OUT data).
697711
if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
698712
selectEndpointClearInterrupt(EP0IN);
699-
LPC_USB->USBDevIntClr = EP_SLOW;
700713
events->ep0_in();
701714
}
702715

@@ -708,7 +721,6 @@ void USBPhyHw::process(void)
708721
} else {
709722
events->ep0_out();
710723
}
711-
LPC_USB->USBDevIntClr = EP_SLOW;
712724
}
713725

714726
//TODO - should probably process in the reverse order
@@ -717,7 +729,6 @@ void USBPhyHw::process(void)
717729
if (LPC_USB->USBEpIntSt & EP(endpoint)) {
718730
selectEndpointClearInterrupt(endpoint);
719731
epComplete |= EP(endpoint);
720-
LPC_USB->USBDevIntClr = EP_SLOW;
721732
if (IN_EP(endpoint)) {
722733
events->in(endpoint);
723734
} else {
@@ -726,6 +737,8 @@ void USBPhyHw::process(void)
726737
}
727738
}
728739
}
740+
741+
LPC_USB->USBDevIntClr = EP_SLOW;
729742
}
730743

731744
NVIC_ClearPendingIRQ(USB_IRQn);

0 commit comments

Comments
 (0)