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 22:39:30 2016 +0000
Parent:
57:20d54f25065a
Child:
59:2ef8b269f2a8
Commit message:
Add USBHAL_KL25Z critical sections

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:18:30 2016 +0000
+++ b/USBDevice/USBDevice/USBHAL_KL25Z.cpp	Thu Feb 11 22:39:30 2016 +0000
@@ -306,89 +306,101 @@
     // limit the requested max packet size to the hardware limit
     if (maxPacket > hwMaxPacket)
         maxPacket = hwMaxPacket;
-
-    // if the endpoint buffer hasn't been allocated yet or was previously
-    // allocated at a smaller size, allocate a new buffer        
-    uint8_t *buf = endpoint_buffer[endpoint];
-    
-    if (buf == NULL || epMaxPacket[endpoint] < maxPacket)
-    {
-        // free any previous buffer
-        if (buf != 0)
-            free(buf);
-
-        // allocate at the new size
-        endpoint_buffer[endpoint] = buf = (uint8_t *)malloc(maxPacket);
         
-        // set the new max packet size
-        epMaxPacket[endpoint] = maxPacket;
-    }
-    
-    // set the endpoint register flags and BDT entry
-    if (IN_EP(endpoint)) 
+    ENTER_CRITICAL_SECTION
     {
-        // IN endpt -> device to host (TX)
-        USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPTXEN_MASK;  // en TX (IN) tran
-        bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = (uint32_t) buf;
-        bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = 0;
-    }
-    else 
-    {
-        // OUT endpt -> host to device (RX)
-        USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPRXEN_MASK;  // en RX (OUT) tran.
-        bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].address = (uint32_t) buf;
-        bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = 0;
+        // if the endpoint buffer hasn't been allocated yet or was previously
+        // allocated at a smaller size, allocate a new buffer        
+        uint8_t *buf = endpoint_buffer[endpoint];
+        if (buf == NULL || epMaxPacket[endpoint] < maxPacket)
+        {
+            // free any previous buffer
+            if (buf != 0)
+                free(buf);
+    
+            // allocate at the new size
+            endpoint_buffer[endpoint] = buf = (uint8_t *)malloc(maxPacket);
+            
+            // set the new max packet size
+            epMaxPacket[endpoint] = maxPacket;
+        }
         
-        // set up the first read
-        bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].byte_count = maxPacket;
-        bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info       = BD_OWN_MASK | BD_DTS_MASK;
-        bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info       = 0;
+        // set the endpoint register flags and BDT entry
+        if (IN_EP(endpoint)) 
+        {
+            // IN endpt -> device to host (TX)
+            USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPTXEN_MASK;  // en TX (IN) tran
+            bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = (uint32_t) buf;
+            bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = 0;
+        }
+        else 
+        {
+            // OUT endpt -> host to device (RX)
+            USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPRXEN_MASK;  // en RX (OUT) tran.
+            bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].address = (uint32_t) buf;
+            bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = 0;
+            
+            // set up the first read
+            bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].byte_count = maxPacket;
+            bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info       = BD_OWN_MASK | BD_DTS_MASK;
+            bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info       = 0;
+        }
+    
+        // Set DATA1 on the endpoint.  For RX endpoints, we just queued up our first
+        // read, which will always be a DATA0 packet, so the next read will use DATA1.
+        // For TX endpoints, we always flip the bit *before* sending the packet, so
+        // (counterintuitively) we need to set the DATA1 bit now to send DATA0 in the
+        // next packet.  So in either case, we want DATA1 initially.
+        Data1 |= (1 << endpoint);
     }
+    EXIT_CRITICAL_SECTION
 
-    // Set DATA1 on the endpoint.  For RX endpoints, we just queued up our first
-    // read, which will always be a DATA0 packet, so the next read will use DATA1.
-    // For TX endpoints, we always flip the bit *before* sending the packet, so
-    // (counterintuitively) we need to set the DATA1 bit now to send DATA0 in the
-    // next packet.  So in either case, we want DATA1 initially.
-    Data1 |= (1 << endpoint);
-
+    // success
     return true;
 }
 
 // read setup packet
-void USBHAL::EP0setup(uint8_t *buffer) {
+void USBHAL::EP0setup(uint8_t *buffer) 
+{
     uint32_t sz;
     endpointReadResult(EP0OUT, buffer, &sz);
 }
 
-void USBHAL::EP0readStage(void) {
+void USBHAL::EP0readStage(void) 
+{
     Data1 &= ~1UL;  // set DATA0
     bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
 }
 
-void USBHAL::EP0read(void) {
+void USBHAL::EP0read(void) 
+{
     uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0);
     bdt[idx].byte_count = MAX_PACKET_SIZE_EP0;
 }
 
-uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) 
+{
     uint32_t sz;
     endpointReadResult(EP0OUT, buffer, &sz);
     return sz;
 }
 
-void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) 
+{
     endpointWrite(EP0IN, buffer, size);
 }
 
-void USBHAL::EP0getWriteResult(void) {
+void USBHAL::EP0getWriteResult(void) 
+{
 }
 
-void USBHAL::EP0stall(void) {
+void USBHAL::EP0stall(void) 
+{
     stallEndpoint(EP0OUT);
 }
 
-EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) 
+{
     endpoint = PHY_TO_LOG(endpoint);
     uint32_t idx = EP_BDT_IDX(endpoint, RX, 0);
     bdt[idx].byte_count = maximumSize;
@@ -414,39 +426,43 @@
     // apply if it's an iso endpoint.
     if ((log_endpoint != 0) && !iso && !(epComplete & EP(endpoint)))
         return EP_PENDING;
-
-    // note if we have a SETUP token
-    bool setup = (log_endpoint == 0 && TOK_PID(idx) == SETUP_TOKEN);
-
-    // get the received data buffer and size
-    uint8_t *ep_buf = endpoint_buffer[endpoint];
-    uint32_t sz  = bdt[idx].byte_count;
-
-    // copy the data from the hardware receive buffer to the caller's buffer
-    *bytesRead = sz;
-    for (uint32_t n = 0 ; n < sz ; n++)
-        buffer[n] = ep_buf[n];
-
-    // figure the DATA0/DATA1 bit for the next packet
-    if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) {
-        if (setup && (buffer[6] == 0))  // if SETUP with no data stage,
-            Data1 &= ~1UL;              // the next packet is always DATA0
+        
+    ENTER_CRITICAL_SECTION
+    {
+        // note if we have a SETUP token
+        bool setup = (log_endpoint == 0 && TOK_PID(idx) == SETUP_TOKEN);
+    
+        // get the received data buffer and size
+        uint8_t *ep_buf = endpoint_buffer[endpoint];
+        uint32_t sz  = bdt[idx].byte_count;
+    
+        // copy the data from the hardware receive buffer to the caller's buffer
+        *bytesRead = sz;
+        for (uint32_t n = 0 ; n < sz ; n++)
+            buffer[n] = ep_buf[n];
+    
+        // figure the DATA0/DATA1 bit for the next packet
+        if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) {
+            if (setup && (buffer[6] == 0))  // if SETUP with no data stage,
+                Data1 &= ~1UL;              // the next packet is always DATA0
+            else
+                Data1 ^= (1 << endpoint);   // for all other cases, toggle from the last packet
+        }
+    
+        // hand off the BDT to the SIE to start the next read
+        bdt[idx].byte_count = epMaxPacket[endpoint];
+        if (((Data1 >> endpoint) & 1))
+            bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK;
         else
-            Data1 ^= (1 << endpoint);   // for all other cases, toggle from the last packet
+            bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK;
+    
+        // clear the "suspend busy" flag to allow continued token processing
+        USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+    
+        // clear the 'completed' flag - we're now awaiting the next packet
+        epComplete &= ~EP(endpoint);
     }
-
-    // hand off the BDT to the SIE to start the next read
-    bdt[idx].byte_count = epMaxPacket[endpoint];
-    if (((Data1 >> endpoint) & 1))
-        bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK;
-    else
-        bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK;
-
-    // clear the "suspend busy" flag to allow continued token processing
-    USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
-
-    // clear the 'completed' flag - we're now awaiting the next packet
-    epComplete &= ~EP(endpoint);
+    EXIT_CRITICAL_SECTION
     
     // read completed
     return EP_COMPLETED;
@@ -461,33 +477,52 @@
     // get the BDT
     uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0);
 
-    // get the endpoint buffer
-    uint8_t *ep_buf = endpoint_buffer[endpoint];
-
-    // copy the data to the BDT buffer
-    bdt[idx].byte_count = size;
-    for (uint32_t n = 0 ; n < size ; n++)
-        ep_buf[n] = data[n];
-
-    // figure the DATA0/DATA1 mode and hand the BDT to the SIE to do the send
-    if ((Data1 >> endpoint) & 1)
-        bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
-    else
-        bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK;
-
-    // toggle DATA0/DATA1
-    Data1 ^= (1 << endpoint);
-
+    ENTER_CRITICAL_SECTION
+    {
+        // get the endpoint buffer
+        uint8_t *ep_buf = endpoint_buffer[endpoint];
+    
+        // copy the data to the BDT buffer
+        bdt[idx].byte_count = size;
+        for (uint32_t n = 0 ; n < size ; n++)
+            ep_buf[n] = data[n];
+    
+        // figure the DATA0/DATA1 mode and hand the BDT to the SIE to do the send
+        if ((Data1 >> endpoint) & 1)
+            bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
+        else
+            bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK;
+    
+        // toggle DATA0/DATA1
+        Data1 ^= (1 << endpoint);
+    }
+    EXIT_CRITICAL_SECTION
+    
+    // write is now pending in the hardware
     return EP_PENDING;
 }
 
-EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
-    if (epComplete & EP(endpoint)) {
-        epComplete &= ~EP(endpoint);
-        return EP_COMPLETED;
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) 
+{
+    // assume write is still pending
+    EP_STATUS result = EP_PENDING;
+    
+    ENTER_CRITICAL_SECTION
+    {
+        // check the 'completed' flag - if set, the write is completed
+        if (epComplete & EP(endpoint)) 
+        {
+            // the result is COMPLETED
+            result = EP_COMPLETED;
+
+            // clear the 'completed' flag - this is consumed by fetching the result
+            epComplete &= ~EP(endpoint);            
+        }
     }
+    EXIT_CRITICAL_SECTION
 
-    return EP_PENDING;
+    // return the result
+    return result;
 }
 
 void USBHAL::stallEndpoint(uint8_t endpoint) {