@@ -161,11 +161,11 @@ static uint8_t SIEgetDeviceStatus(void)
161
161
return SIEReadData (SIE_CMD_GET_DEVICE_STATUS);
162
162
}
163
163
164
- void SIEsetAddress (uint8_t address)
164
+ void SIEsetAddress (uint8_t address, bool enable= true )
165
165
{
166
166
// Write SIE device address register
167
167
SIECommand (SIE_CMD_SET_ADDRESS);
168
- SIEWriteData ((address & 0x7f ) | SIE_DSA_DEV_EN);
168
+ SIEWriteData ((address & 0x7f ) | (enable ? SIE_DSA_DEV_EN : 0 ) );
169
169
}
170
170
171
171
static uint8_t SIEselectEndpoint (uint8_t endpoint)
@@ -402,8 +402,8 @@ void USBPhyHw::init(USBPhyEvents *events)
402
402
403
403
// Enable interrupts for device events and EP0
404
404
LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
405
- enableEndpointEvent (EP0IN);
406
- enableEndpointEvent (EP0OUT );
405
+
406
+ NVIC_EnableIRQ (USB_IRQn );
407
407
}
408
408
409
409
void USBPhyHw::deinit ()
@@ -422,14 +422,28 @@ bool USBPhyHw::powered()
422
422
423
423
void USBPhyHw::connect (void )
424
424
{
425
- NVIC_EnableIRQ (USB_IRQn);
425
+ enableEndpointEvent (EP0IN);
426
+ enableEndpointEvent (EP0OUT);
427
+
426
428
// Connect USB device
427
429
SIEconnect ();
428
430
}
429
431
430
432
void USBPhyHw::disconnect (void )
431
433
{
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
+
433
447
// Disconnect USB device
434
448
SIEdisconnect ();
435
449
}
@@ -696,7 +710,6 @@ void USBPhyHw::process(void)
696
710
// case of OUT as SETUP clobbers the OUT data).
697
711
if (LPC_USB->USBEpIntSt & EP (EP0IN)) {
698
712
selectEndpointClearInterrupt (EP0IN);
699
- LPC_USB->USBDevIntClr = EP_SLOW;
700
713
events->ep0_in ();
701
714
}
702
715
@@ -708,7 +721,6 @@ void USBPhyHw::process(void)
708
721
} else {
709
722
events->ep0_out ();
710
723
}
711
- LPC_USB->USBDevIntClr = EP_SLOW;
712
724
}
713
725
714
726
// TODO - should probably process in the reverse order
@@ -717,7 +729,6 @@ void USBPhyHw::process(void)
717
729
if (LPC_USB->USBEpIntSt & EP (endpoint)) {
718
730
selectEndpointClearInterrupt (endpoint);
719
731
epComplete |= EP (endpoint);
720
- LPC_USB->USBDevIntClr = EP_SLOW;
721
732
if (IN_EP (endpoint)) {
722
733
events->in (endpoint);
723
734
} else {
@@ -726,6 +737,8 @@ void USBPhyHw::process(void)
726
737
}
727
738
}
728
739
}
740
+
741
+ LPC_USB->USBDevIntClr = EP_SLOW;
729
742
}
730
743
731
744
NVIC_ClearPendingIRQ (USB_IRQn);
0 commit comments