Skip to content

Commit 64cd200

Browse files
author
Cruz Monrreal
authored
Merge pull request ARMmbed#7185 from c1728p9/fix_lpc1768_iso
Fix isochronous endpoints on LPC1768
2 parents c753780 + d732279 commit 64cd200

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

usb/device/targets/TARGET_NXP/USBHAL_LPC17.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
// Convert physical endpoint number to register bit
3030
#define EP(endpoint) (1UL<<DESC_TO_PHY(endpoint))
3131

32+
// Check if this is an isochronous endpoint
33+
#define ISO_EP(endpoint) ((((endpoint) & 0xF) == 3) || (((endpoint) & 0xF) == 6) || (((endpoint) & 0xF) == 9) || (((endpoint) & 0xF) == 12))
34+
3235
#define DESC_TO_PHY(endpoint) ((((endpoint)&0x0F)<<1) | (((endpoint) & 0x80) ? 1:0))
3336
#define PHY_TO_DESC(endpoint) (((endpoint)>>1)|(((endpoint)&1)?0x80:0))
3437

@@ -122,6 +125,13 @@ static USBPhyHw *instance;
122125

123126
static uint32_t opStarted;
124127

128+
static const usb_ep_t ISO_EPS[] = {
129+
0x03, 0x83,
130+
0x06, 0x86,
131+
0x09, 0x89,
132+
0x0C, 0x8C
133+
};
134+
125135
static void SIECommand(uint32_t command)
126136
{
127137
// The command phase of a SIE transaction
@@ -465,6 +475,9 @@ void USBPhyHw::disconnect(void)
465475

466476
// Disconnect USB device
467477
SIEdisconnect();
478+
479+
// Reset all started operations
480+
opStarted = 0;
468481
}
469482

470483
void USBPhyHw::configure(void)
@@ -551,7 +564,7 @@ uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint)
551564
read_sizes[endpoint] = 0;
552565

553566
// Don't clear isochronous endpoints
554-
if ((DESC_TO_PHY(endpoint) >> 1) % 3 || (DESC_TO_PHY(endpoint) >> 1) == 0) {
567+
if (!ISO_EP(endpoint)) {
555568
SIEselectEndpoint(endpoint);
556569
SIEclearBuffer();
557570
}
@@ -692,6 +705,20 @@ void USBPhyHw::process(void)
692705
events->sof(SIEgetFrameNumber());
693706
// Clear interrupt status flag
694707
LPC_USB->USBDevIntClr = FRAME;
708+
709+
// There is no ISO interrupt, instead a packet is transferred every SOF
710+
for (uint32_t i = 0; i < sizeof(ISO_EPS) / sizeof(ISO_EPS[0]); i++) {
711+
uint8_t endpoint = ISO_EPS[i];
712+
if (opStarted & EP(endpoint)) {
713+
opStarted &= ~EP(endpoint);
714+
if (IN_EP(endpoint)) {
715+
events->in(endpoint);
716+
} else {
717+
events->out(endpoint);
718+
}
719+
}
720+
}
721+
695722
}
696723

697724
if (LPC_USB->USBDevIntSt & DEV_STAT) {
@@ -717,6 +744,7 @@ void USBPhyHw::process(void)
717744
}
718745
memset(read_buffers, 0, sizeof(read_buffers));
719746
memset(read_sizes, 0, sizeof(read_sizes));
747+
opStarted = 0;
720748
events->reset();
721749
}
722750
}
@@ -752,12 +780,16 @@ void USBPhyHw::process(void)
752780
}
753781
}
754782

755-
//TODO - should probably process in the reverse order
756783
for (uint8_t num = 2; num < 16 * 2; num++) {
757784
uint8_t endpoint = PHY_TO_DESC(num);
758785
if (LPC_USB->USBEpIntSt & EP(endpoint)) {
759786
selectEndpointClearInterrupt(endpoint);
787+
if (ISO_EP(endpoint)) {
788+
// Processing for ISO endpoints done in FRAME handling
789+
continue;
790+
}
760791
if (opStarted & EP(endpoint)) {
792+
opStarted &= ~EP(endpoint);
761793
if (IN_EP(endpoint)) {
762794
events->in(endpoint);
763795
} else {

0 commit comments

Comments
 (0)