29
29
// Convert physical endpoint number to register bit
30
30
#define EP (endpoint ) (1UL <<DESC_TO_PHY(endpoint))
31
31
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
+
32
35
#define DESC_TO_PHY (endpoint ) ((((endpoint)&0x0F )<<1 ) | (((endpoint) & 0x80 ) ? 1 :0 ))
33
36
#define PHY_TO_DESC (endpoint ) (((endpoint)>>1 )|(((endpoint)&1 )?0x80 :0 ))
34
37
@@ -122,6 +125,13 @@ static USBPhyHw *instance;
122
125
123
126
static uint32_t opStarted;
124
127
128
+ static const usb_ep_t ISO_EPS[] = {
129
+ 0x03 , 0x83 ,
130
+ 0x06 , 0x86 ,
131
+ 0x09 , 0x89 ,
132
+ 0x0C , 0x8C
133
+ };
134
+
125
135
static void SIECommand (uint32_t command)
126
136
{
127
137
// The command phase of a SIE transaction
@@ -465,6 +475,9 @@ void USBPhyHw::disconnect(void)
465
475
466
476
// Disconnect USB device
467
477
SIEdisconnect ();
478
+
479
+ // Reset all started operations
480
+ opStarted = 0 ;
468
481
}
469
482
470
483
void USBPhyHw::configure (void )
@@ -551,7 +564,7 @@ uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint)
551
564
read_sizes[endpoint] = 0 ;
552
565
553
566
// Don't clear isochronous endpoints
554
- if (( DESC_TO_PHY ( endpoint) >> 1 ) % 3 || ( DESC_TO_PHY (endpoint) >> 1 ) == 0 ) {
567
+ if (! ISO_EP ( endpoint)) {
555
568
SIEselectEndpoint (endpoint);
556
569
SIEclearBuffer ();
557
570
}
@@ -692,6 +705,20 @@ void USBPhyHw::process(void)
692
705
events->sof (SIEgetFrameNumber ());
693
706
// Clear interrupt status flag
694
707
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
+
695
722
}
696
723
697
724
if (LPC_USB->USBDevIntSt & DEV_STAT) {
@@ -717,6 +744,7 @@ void USBPhyHw::process(void)
717
744
}
718
745
memset (read_buffers, 0 , sizeof (read_buffers));
719
746
memset (read_sizes, 0 , sizeof (read_sizes));
747
+ opStarted = 0 ;
720
748
events->reset ();
721
749
}
722
750
}
@@ -752,12 +780,16 @@ void USBPhyHw::process(void)
752
780
}
753
781
}
754
782
755
- // TODO - should probably process in the reverse order
756
783
for (uint8_t num = 2 ; num < 16 * 2 ; num++) {
757
784
uint8_t endpoint = PHY_TO_DESC (num);
758
785
if (LPC_USB->USBEpIntSt & EP (endpoint)) {
759
786
selectEndpointClearInterrupt (endpoint);
787
+ if (ISO_EP (endpoint)) {
788
+ // Processing for ISO endpoints done in FRAME handling
789
+ continue ;
790
+ }
760
791
if (opStarted & EP (endpoint)) {
792
+ opStarted &= ~EP (endpoint);
761
793
if (IN_EP (endpoint)) {
762
794
events->in (endpoint);
763
795
} else {
0 commit comments