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
Revision 58:480c2c786c71, committed 2016-02-11
- 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) {