Pinscape Controller version 1 fork. This is a fork to allow for ongoing bug fixes to the original controller version, from before the major changes for the expansion board project.

Dependencies:   FastIO FastPWM SimpleDMA mbed

Fork of Pinscape_Controller by Mike R

Files at this revision

API Documentation at this revision

Comitter:
mjr
Date:
Thu Feb 11 23:03:01 2016 +0000
Parent:
59:2ef8b269f2a8
Child:
61:a23a7b57bb95
Commit message:
Additional USBHAL_KL25Z ISR cleanup

Changed in this revision

USBDevice/USBDevice/USBHAL_KL25Z.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/USBDevice/USBDevice/USBHAL_KL25Z.cpp	Thu Feb 11 22:47:51 2016 +0000
+++ b/USBDevice/USBDevice/USBHAL_KL25Z.cpp	Thu Feb 11 23:03:01 2016 +0000
@@ -621,50 +621,68 @@
     // token interrupt
     if (istat & USB_ISTAT_TOKDNE_MASK) 
     {
+        // get the endpoint information from the status register
         uint32_t num  = (USB0->STAT >> 4) & 0x0F;
         uint32_t dir  = (USB0->STAT >> 3) & 0x01;
+        int ep = (num << 1) | dir;
         uint32_t ev_odd = (USB0->STAT >> 2) & 0x01;
-
-        // setup packet
-        if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) {
-            Data1 &= ~0x02;
-            bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
-            bdt[EP_BDT_IDX(0, TX, ODD)].info  &= ~BD_OWN_MASK;
-
-            // EP0 SETUP event (SETUP data received)
-            EP0setupCallback();
+        uint32_t idx = EP_BDT_IDX(num, dir, ev_odd);
 
-        } else {
-            // OUT packet
-            if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) {
-                if (num == 0)
-                    EP0out();
-                else {
-                    epComplete |= (1 << EP(num));
-                    if ((instance->*(epCallback[EP(num) - 2]))()) {
-                        epComplete &= ~(1 << EP(num));
-                    }
-                }
-            }
+        // check which endpoint we're working with
+        if (num == 0)
+        {
+            // Endpoint 0 requires special handling
+            int pid = TOK_PID(idx);
+            if (pid == SETUP_TOKEN)
+            {
+                // SETUP packet - next IN (TX) packet must be DATA1 (confusingly,
+                // this means we must clear the Data1 bit, since we flip the bit
+                // before each send)
+                Data1 &= ~0x02;
+                
+                // forcibly take ownership of the EP0IN endpoints in case we have
+                // unfinished previous transmissions (the protocol state machine here
+                // assumes that we don't, so it's probably an error if this code
+                // actually does anything, but we make no provision for handling this)
+                bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
+                bdt[EP_BDT_IDX(0, TX, ODD)].info  &= ~BD_OWN_MASK;
 
-            // IN packet
-            if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) {
-                if (num == 0) {
-                    EP0in();
-                    if (set_addr == 1) {
-                        USB0->ADDR = addr & 0x7F;
-                        set_addr = 0;
-                    }
-                }
-                else {
-                    epComplete |= (1 << (EP(num) + 1));
-                    if ((instance->*(epCallback[EP(num) + 1 - 2]))()) {
-                        epComplete &= ~(1 << (EP(num) + 1));
-                    }
+                // handle the EP0 SETUP event in the generic protocol layer
+                EP0setupCallback();
+            } 
+            else if (pid == OUT_TOKEN)
+            {
+                // OUT packet on EP0
+                EP0out();
+            }
+            else if (pid == IN_TOKEN)
+            {
+                // IN packet on EP0
+                EP0in();
+                
+                // Special case: if the 'set address' flag is set, it means that the
+                // host just sent us our bus address.  We must put this into effect
+                // in the hardware SIE *after* sending the reply, which we just did
+                // above.  So it's now time!
+                if (set_addr == 1) {
+                    USB0->ADDR = addr & 0x7F;
+                    set_addr = 0;
                 }
             }
         }
+        else
+        {
+            // For all other endpoints, note the read/write completion in the flags
+            epComplete |= EP(ep);
+            
+            // call the endpoint token callback; if that handles the token, it consumes
+            // the 'completed' status, so clear that flag again
+            if ((instance->*(epCallback[ep - 2]))()) {
+                epComplete &= ~EP(ep);
+            }
+        }
 
+        // clear the TOKDNE interrupt status bit
         USB0->ISTAT = USB_ISTAT_TOKDNE_MASK;
     }