void processUsbSendQueue(UsbDevice* usbDevice) { while(usbDevice->configured && !QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) { // Make sure the USB write is 100% complete before messing with this buffer // after we copy the message into it - the Microchip library doesn't copy // the data to its own internal buffer. See #171 for background on this // issue. if(!waitForHandle(usbDevice)) { return; } int byteCount = 0; while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue) && byteCount < 64) { usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue); } int nextByteIndex = 0; while(nextByteIndex < byteCount) { if(!waitForHandle(usbDevice)) { return; } int bytesToTransfer = min(USB_PACKET_SIZE, byteCount - nextByteIndex); usbDevice->deviceToHostHandle = usbDevice->device.GenWrite( usbDevice->inEndpoint, &usbDevice->sendBuffer[nextByteIndex], bytesToTransfer); nextByteIndex += bytesToTransfer; } } }
void processUsbSendQueue(UsbDevice* usbDevice) { if(usbDevice->configured && vbusEnabled()) { // if there's nothing attached to the analog input it floats at ~828, so // if we're powering the board from micro-USB (and the jumper is going // to 5v and not the analog input), this is still OK. debug("USB no longer detected - marking unconfigured"); usbDevice->configured = false; } // Don't touch usbDevice->sendBuffer if there's still a pending transfer if(!waitForHandle(usbDevice)) { return; } while(usbDevice->configured && !QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) { int byteCount = 0; while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue) && byteCount < USB_SEND_BUFFER_SIZE) { usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue); } int nextByteIndex = 0; while(nextByteIndex < byteCount) { // Make sure the USB write is 100% complete before messing with this // buffer after we copy the message into it - the Microchip library // doesn't copy the data to its own internal buffer. See #171 for // background on this issue. // TODO instead of dropping, replace POP above with a SNAPSHOT // and POP off only exactly how many bytes were sent after the // fact. // TODO in order for this not to fail too often I had to increase // the USB_HANDLE_MAX_WAIT_COUNT. that may be OK since now we have // VBUS detection. if(!waitForHandle(usbDevice)) { debug("USB not responding in a timely fashion, dropped data"); return; } int bytesToTransfer = min(MAX_USB_PACKET_SIZE_BYTES, byteCount - nextByteIndex); usbDevice->deviceToHostHandle = usbDevice->device.GenWrite( usbDevice->inEndpoint, &usbDevice->sendBuffer[nextByteIndex], bytesToTransfer); nextByteIndex += bytesToTransfer; } } }