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 68:edfecf67a931, committed 2016-02-15
- Comitter:
- mjr
- Date:
- Mon Feb 15 23:03:55 2016 +0000
- Parent:
- 65:3b280c430660
- Commit message:
- Finalize USB library updates to fix compatibility problems introduced in USBHAL_KL25Z overhaul.
Changed in this revision
--- a/USBDevice/USBDevice/USBDevice.cpp Fri Feb 12 21:46:21 2016 +0000 +++ b/USBDevice/USBDevice/USBDevice.cpp Mon Feb 15 23:03:55 2016 +0000 @@ -23,6 +23,11 @@ #include "USBDescriptor.h" //#define DEBUG +#ifdef DEBUG +#define printd(fmt, ...) printf(fmt, __VA_ARGS__) +#else +#define printd(fmt, ...) +#endif /* Device status */ #define DEVICE_STATUS_SELF_POWERED (1U<<0) @@ -43,9 +48,7 @@ bool USBDevice::requestGetDescriptor(void) { bool success = false; -#ifdef DEBUG - printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue)); -#endif + printd("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue)); switch (DESCRIPTOR_TYPE(transfer.setup.wValue)) { case DEVICE_DESCRIPTOR: @@ -54,9 +57,7 @@ if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \ && (deviceDesc()[1] == DEVICE_DESCRIPTOR)) { -#ifdef DEBUG - printf("device descr\r\n"); -#endif + printd("device descr\r\n"); transfer.remaining = DEVICE_DESCRIPTOR_LENGTH; transfer.ptr = deviceDesc(); transfer.direction = DEVICE_TO_HOST; @@ -70,9 +71,8 @@ if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \ && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR)) { -#ifdef DEBUG - printf("conf descr request\r\n"); -#endif + printd("conf descr request\r\n"); + /* Get wTotalLength */ transfer.remaining = configurationDesc()[2] \ | (configurationDesc()[3] << 8); @@ -84,60 +84,46 @@ } break; case STRING_DESCRIPTOR: -#ifdef DEBUG - printf("str descriptor\r\n"); -#endif + printd("str descriptor\r\n"); switch (DESCRIPTOR_INDEX(transfer.setup.wValue)) { case STRING_OFFSET_LANGID: -#ifdef DEBUG - printf("1\r\n"); -#endif + printd("1\r\n"); transfer.remaining = stringLangidDesc()[0]; transfer.ptr = stringLangidDesc(); transfer.direction = DEVICE_TO_HOST; success = true; break; case STRING_OFFSET_IMANUFACTURER: -#ifdef DEBUG - printf("2\r\n"); -#endif + printd("2\r\n"); transfer.remaining = stringImanufacturerDesc()[0]; transfer.ptr = stringImanufacturerDesc(); transfer.direction = DEVICE_TO_HOST; success = true; break; case STRING_OFFSET_IPRODUCT: -#ifdef DEBUG - printf("3\r\n"); -#endif + printd("3\r\n"); transfer.remaining = stringIproductDesc()[0]; transfer.ptr = stringIproductDesc(); transfer.direction = DEVICE_TO_HOST; success = true; break; case STRING_OFFSET_ISERIAL: -#ifdef DEBUG - printf("4\r\n"); -#endif + printd("4\r\n"); transfer.remaining = stringIserialDesc()[0]; transfer.ptr = stringIserialDesc(); transfer.direction = DEVICE_TO_HOST; success = true; break; case STRING_OFFSET_ICONFIGURATION: -#ifdef DEBUG - printf("5\r\n"); -#endif + printd("5\r\n"); transfer.remaining = stringIConfigurationDesc()[0]; transfer.ptr = stringIConfigurationDesc(); transfer.direction = DEVICE_TO_HOST; success = true; break; case STRING_OFFSET_IINTERFACE: -#ifdef DEBUG - printf("6\r\n"); -#endif + printd("6\r\n"); transfer.remaining = stringIinterfaceDesc()[0]; transfer.ptr = stringIinterfaceDesc(); transfer.direction = DEVICE_TO_HOST; @@ -145,20 +131,18 @@ break; } break; + case INTERFACE_DESCRIPTOR: -#ifdef DEBUG - printf("interface descr\r\n"); -#endif + printd("interface descr\r\n"); + break; + case ENDPOINT_DESCRIPTOR: -#ifdef DEBUG - printf("endpoint descr\r\n"); -#endif /* TODO: Support is optional, not implemented here */ + printd("endpoint descr\r\n"); break; + default: -#ifdef DEBUG - printf("ERROR\r\n"); -#endif + printd("ERROR - unknown descriptor type in GET DESCRIPTOR\r\n"); break; } @@ -192,17 +176,17 @@ * We seem to have a pending device-to-host transfer. The host must have * sent a new control request without waiting for us to finish processing * the previous one. This appears to happen when we're connected to certain - * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not + * USB 3.0 host chip sets. Do a zero-length send to tell the host we're not * ready for the new request - that'll make it resend - and then just * pretend we were successful here so that the pending transfer can finish. */ uint8_t buf[1] = { 0 }; EP0write(buf, 0); - /* execute our pending ttransfer */ + /* execute our pending transfer */ controlIn(); - /* indicate success */ + /* indicate failure */ return false; #else /* for other platforms, count on the HAL to handle this case */ @@ -573,15 +557,14 @@ transfer.zlp = false; transfer.notify = false; -#ifdef DEBUG - printf("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n",transfer.setup.bmRequestType.dataTransferDirection, - transfer.setup.bmRequestType.Type, - transfer.setup.bmRequestType.Recipient, - transfer.setup.bRequest, - transfer.setup.wValue, - transfer.setup.wIndex, - transfer.setup.wLength); -#endif + printd("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n", + transfer.setup.bmRequestType.dataTransferDirection, + transfer.setup.bmRequestType.Type, + transfer.setup.bmRequestType.Recipient, + transfer.setup.bRequest, + transfer.setup.wValue, + transfer.setup.wIndex, + transfer.setup.wLength); /* Class / vendor specific */ success = USBCallback_request(); @@ -591,22 +574,20 @@ /* Standard requests */ if (!requestSetup()) { -#ifdef DEBUG - printf("fail!!!!\r\n"); -#endif + printd("requestSetup() failed: type=%d, req=%d\r\n", (int)transfer.setup.bmRequestType.Type, (int)transfer.setup.bRequest); return false; } } /* Check transfer size and direction */ - if (transfer.setup.wLength>0) + if (transfer.setup.wLength > 0) { - if (transfer.setup.bmRequestType.dataTransferDirection \ - == DEVICE_TO_HOST) + if (transfer.setup.bmRequestType.dataTransferDirection == DEVICE_TO_HOST) { /* IN data stage is required */ if (transfer.direction != DEVICE_TO_HOST) { + printd("controlSetup transfer direction wrong 1\r\n"); return false; } @@ -623,12 +604,15 @@ /* OUT data stage is required */ if (transfer.direction != HOST_TO_DEVICE) { + printd("controlSetup transfer direction wrong 2: type=%d, req=%d\r\n", (int)transfer.setup.bmRequestType.Type, (int)transfer.setup.bRequest); return false; } /* Transfer must be equal to the size requested by the host */ if (transfer.remaining != transfer.setup.wLength) { + printd("controlSetup remaining length wrong: return len=%d, type=%d, req=%d, wvalue=%d, windex=%x, wlength=%d\r\n", + transfer.remaining, transfer.setup.bmRequestType.Type, transfer.setup.bRequest, transfer.setup.wValue, transfer.setup.wIndex, transfer.setup.wLength); return false; } } @@ -638,12 +622,14 @@ /* No data stage; transfer size must be zero */ if (transfer.remaining != 0) { + printd("controlSetup remaining length must be zero: return len=%d, type=%d, req=%d, wvalue=%d, windex=%x, wlength=%d\r\n", + (int)transfer.remaining, (int)transfer.setup.bmRequestType.Type, (int)transfer.setup.bRequest, (int)transfer.setup.wValue, (int)transfer.setup.wIndex, (int)transfer.setup.wLength); return false; } } /* Data or status stage if applicable */ - if (transfer.setup.wLength>0) + if (transfer.setup.wLength > 0) { if (transfer.setup.bmRequestType.dataTransferDirection \ == DEVICE_TO_HOST) @@ -696,8 +682,6 @@ /* Protocol stall */ EP0stall(); } - - /* Return true if an OUT data stage is expected */ } void USBDevice::EP0out(void) @@ -712,10 +696,8 @@ void USBDevice::EP0in(void) { -#ifdef DEBUG - printf("EP0IN\r\n"); -#endif /* Endpoint 0 IN data event */ + printd("EP0IN\r\n"); if (!controlIn()) { /* Protocol stall; this will stall both endpoints */ @@ -735,8 +717,8 @@ USBHAL::connect(); if (blocking) { - /* Block if not configured */ - while (!configured()); + /* Block until configured */ + while (!configured()) { } } } @@ -911,14 +893,13 @@ return false; } - if(!configured()) { return false; } /* Send report */ result = endpointWrite(endpoint, buffer, size); - + if (result != EP_PENDING) { return false; @@ -936,9 +917,6 @@ return (result == EP_COMPLETED); } - - - bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) { EP_STATUS result;
--- a/USBDevice/USBDevice/USBHAL_KL25Z.cpp Fri Feb 12 21:46:21 2016 +0000 +++ b/USBDevice/USBDevice/USBHAL_KL25Z.cpp Mon Feb 15 23:03:55 2016 +0000 @@ -25,6 +25,7 @@ #define printd(fmt, ...) #endif + #include "USBHAL.h" // Critical section controls. This module uses a bunch of static variables, @@ -89,7 +90,7 @@ #define ODD 1 // Get the BDT index for a given logical endpoint, direction, and buffer parity -#define EP_BDT_IDX(logep, dir, odd) ((((logep) * 4) + (2 * (dir)) + (1 * (odd)))) +#define EP_BDT_IDX(logep, dir, odd) (((logep) * 4) + (2 * (dir)) + (1 * (odd))) // Get the BDT index for a given physical endpoint and buffer parity #define PEP_BDT_IDX(phyep, odd) (((phyep) * 2) + (1 * (odd))) @@ -149,11 +150,13 @@ // consumed yet). static volatile uint32_t epComplete = 0; -static uint32_t frameNumber() { +static uint32_t frameNumber() +{ return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF); } -uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { +uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) +{ return 0; } @@ -196,7 +199,6 @@ epCallback[28] = &USBHAL::EP15_OUT_callback; epCallback[29] = &USBHAL::EP15_IN_callback; - // choose usb src as PLL SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK); @@ -235,7 +237,9 @@ USB0->USBTRC0 |= 0x40; } -USBHAL::~USBHAL(void) { } +USBHAL::~USBHAL(void) +{ +} void USBHAL::connect(void) { @@ -266,15 +270,18 @@ } } -void USBHAL::configureDevice(void) { +void USBHAL::configureDevice(void) +{ // not needed } -void USBHAL::unconfigureDevice(void) { +void USBHAL::unconfigureDevice(void) +{ // not needed } -void USBHAL::setAddress(uint8_t address) { +void USBHAL::setAddress(uint8_t address) +{ // we don't set the address now otherwise the usb controller does not ack // we set a flag instead // see usbisr when an IN token is received @@ -290,15 +297,16 @@ // get the logical endpoint uint32_t log_endpoint = PHY_TO_LOG(endpoint); - - // For bulk and interrupt endpoints, the hardware maximum packet size is 64 bytes, - // and we use packet handshaking. Set these defaults. + + // Assume this is a bulk or interrupt endpoint. For these, the hardware maximum + // packet size is 64 bytes, and we use packet handshaking. uint32_t hwMaxPacket = 64; uint32_t handshake_flag = USB_ENDPT_EPHSHK_MASK; // If it's to be an isochronous endpoint, the hardware maximum packet size // increases to 1023 bytes, and we don't use handshaking. - if (flags & ISOCHRONOUS) { + if (flags & ISOCHRONOUS) + { handshake_flag = 0; hwMaxPacket = 1023; } @@ -354,7 +362,7 @@ Data1 |= (1 << endpoint); } EXIT_CRITICAL_SECTION - + // success return true; } @@ -378,9 +386,8 @@ void USBHAL::EP0read(void) { - uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0); - if (!(bdt[idx].info & BD_OWN_MASK)) - bdt[idx].byte_count = MAX_PACKET_SIZE_EP0; + if (!(bdt[0].info & BD_OWN_MASK)) + bdt[0].byte_count = MAX_PACKET_SIZE_EP0; } uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) @@ -413,7 +420,7 @@ return EP_PENDING; } -EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) +EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *buffer, uint32_t *bytesRead) { // validate the endpoint number and direction if (endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS || !OUT_EP(endpoint)) @@ -421,12 +428,14 @@ // get the logical endpoint uint32_t log_endpoint = PHY_TO_LOG(endpoint); - - // get the BDT entry - uint32_t idx = EP_BDT_IDX(log_endpoint, RX, 0); + + // get the mode - it's isochronous if it doesn't have the handshake flag bool iso = (USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK) == 0; - - // check to see if the endpoint is ready to read + + // get the BDT index + int idx = EP_BDT_IDX(log_endpoint, RX, 0); + + // Check to see if the endpoint is ready to read if (log_endpoint == 0) { // control endpoint - just make sure we own the BDT @@ -457,20 +466,24 @@ 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)) { + // Figure the DATA0/DATA1 bit for the next packet received on this + // endpoint. The bit normally toggles on each packet, but it's + // special for SETUP packets on endpoint 0. The next OUT packet + // after a SETUP packet with no data stage is always DATA0, even + // if the SETUP packet was also DATA0. + 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 + Data1 ^= (1 << endpoint); // otherwise just toggle the last bit } - // reset the BDT buffer to the max packet size for the endpoint, and - // hand off the BDT to the SIE so that it can receive the next packet + // set up the BDT entry to receive the next packet, and hand it to the SIE bdt[idx].byte_count = epMaxPacket[endpoint]; bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK | (((Data1 >> endpoint) & 1) << 6); - // clear the "suspend busy" flag to allow continued token processing + // clear the SUSPEND TOKEN BUSY flag to allow token processing to continue USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; // clear the 'completed' flag - we're now awaiting the next packet @@ -478,7 +491,7 @@ } EXIT_CRITICAL_SECTION - // read completed + // the read is completed return EP_COMPLETED; } @@ -488,20 +501,20 @@ if (endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS || !IN_EP(endpoint)) return EP_INVALID; - // get the BDT - uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0); - + // get the BDT index + int idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0); + ENTER_CRITICAL_SECTION { // get the endpoint buffer uint8_t *ep_buf = endpoint_buffer[endpoint]; - // copy the data to the BDT buffer + // copy the data to the hardware buffer bdt[idx].byte_count = size; for (uint32_t n = 0 ; n < size ; n++) ep_buf[n] = data[n]; - // toggle DATA0/DATA1 + // toggle DATA0/DATA1 before sending Data1 ^= (1 << endpoint); // hand the BDT to the SIE to do the send @@ -527,11 +540,11 @@ result = EP_COMPLETED; // clear the 'completed' flag - this is consumed by fetching the result - epComplete &= ~EP(endpoint); + epComplete &= ~EP(endpoint); } } EXIT_CRITICAL_SECTION - + // return the result return result; } @@ -575,11 +588,11 @@ return (stall) ? true : false; } -void USBHAL::remoteWakeup(void) { +void USBHAL::remoteWakeup(void) +{ // [TODO] } - void USBHAL::_usbisr(void) { inIRQ = true; @@ -595,7 +608,7 @@ // reset interrupt if (istat & USB_ISTAT_USBRST_MASK) - { + { // disable all endpoints for (i = 0 ; i < 16 ; i++) USB0->ENDPOINT[i].ENDPT = 0x00; @@ -606,8 +619,8 @@ // reset DATA0/1 state Data1 = 0x55555555; - - // reset endpoint completeion status + + // reset endpoint completion status epComplete = 0; // reset EVEN/ODD state (and keep it permanently on EVEN - @@ -630,21 +643,24 @@ } // resume interrupt - if (istat & USB_ISTAT_RESUME_MASK) { + if (istat & USB_ISTAT_RESUME_MASK) + { suspendStateChanged(0); USB0->ISTAT = USB_ISTAT_RESUME_MASK; } // SOF interrupt - if (istat & USB_ISTAT_SOFTOK_MASK) { + if (istat & USB_ISTAT_SOFTOK_MASK) + { + // Read frame number and signal the SOF event to the callback SOF(frameNumber()); USB0->ISTAT = USB_ISTAT_SOFTOK_MASK; } // stall interrupt - if (istat & USB_ISTAT_STALL_MASK) + if (istat & USB_ISTAT_STALL_MASK) { - // if endpoint 0 is stalled, explicitly un-stall it + // if the control endpoint (EP 0) is stalled, unstall it if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK) { // clear the stall bit in the endpoint register @@ -677,14 +693,14 @@ // 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; + int endpoint = (num << 1) | dir; uint32_t ev_odd = (USB0->STAT >> 2) & 0x01; - uint32_t idx = EP_BDT_IDX(num, dir, ev_odd); // check which endpoint we're working with if (num == 0) { // Endpoint 0 requires special handling + uint32_t idx = EP_BDT_IDX(num, dir, ev_odd); int pid = TOK_PID(idx); if (pid == SETUP_TOKEN) { @@ -726,12 +742,12 @@ else { // For all other endpoints, note the read/write completion in the flags - epComplete |= EP(ep); + epComplete |= EP(endpoint); // 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); + if ((instance->*(epCallback[endpoint - 2]))()) { + epComplete &= ~EP(endpoint); } } @@ -740,18 +756,21 @@ } // sleep interrupt - if (istat & USB_ISTAT_SLEEP_MASK) { + if (istat & USB_ISTAT_SLEEP_MASK) + { suspendStateChanged(1); USB0->ISTAT = USB_ISTAT_SLEEP_MASK; } // error interrupt - if (istat & USB_ISTAT_ERROR_MASK) { + if (istat & USB_ISTAT_ERROR_MASK) + { + // reset all error status bits, and clear the SUSPEND flag to allow + // token processing to continue USB0->ERRSTAT = 0xFF; USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; USB0->ISTAT = USB_ISTAT_ERROR_MASK; } } - #endif
--- a/USBDevice/USBHID/USBHID.cpp Fri Feb 12 21:46:21 2016 +0000 +++ b/USBDevice/USBHID/USBHID.cpp Mon Feb 15 23:03:55 2016 +0000 @@ -174,7 +174,7 @@ transfer->notify = true; success = true; break; - + case SET_IDLE: // Set idle time - time between INTERRUPT IN reports from the // device when there are no changes to report. setup.wIndex @@ -185,6 +185,7 @@ transfer->remaining = 0; transfer->direction = DEVICE_TO_HOST; success = true; + break; case SET_PROTOCOL: // not implemented