void fcBuffers::finalizeFrame() { // Called in main loop context. // Finalize any frames received during the course of this loop iteration, // and update the status LED. if (flags & CFLAG_NO_ACTIVITY_LED) { // LED under manual control digitalWriteFast(LED_BUILTIN, flags & CFLAG_LED_CONTROL); } else { // Use the built-in LED as a USB activity indicator. digitalWriteFast(LED_BUILTIN, handledAnyPacketsThisFrame); } handledAnyPacketsThisFrame = false; if (pendingFinalizeFrame) { finalizeFramebuffer(); pendingFinalizeFrame = false; } if (pendingFinalizeLUT) { finalizeLUT(); pendingFinalizeLUT = false; } // Let the USB driver know we may be able to process buffers that were previously deferred usb_rx_resume(); }
void fcBuffers::handleUSB() { /* * Look for incoming USB packets, and file them appropriately. * Our framebuffer and LUT buffers are arrays of references to USB packets * which we hold until a new packet arrives to replace them. */ bool handledAnyPackets = false; while (1) { usb_packet_t *packet = usb_rx(FC_OUT_ENDPOINT); if (!packet) { break; } handledAnyPackets = true; unsigned control = packet->buf[0]; unsigned type = control & TYPE_BITS; unsigned final = control & FINAL_BIT; unsigned index = control & INDEX_BITS; switch (type) { case TYPE_FRAMEBUFFER: fbNew->store(index, packet); if (final) { finalizeFramebuffer(); } break; case TYPE_LUT: lutNew.store(index, packet); if (final) { finalizeLUT(); } break; case TYPE_CONFIG: flags = packet->buf[1]; usb_free(packet); break; default: usb_free(packet); break; } } if (flags & CFLAG_NO_ACTIVITY_LED) { // LED under manual control digitalWrite(LED_BUILTIN, flags & CFLAG_LED_CONTROL); } else { // Use the built-in LED as a USB activity indicator. digitalWrite(LED_BUILTIN, handledAnyPackets); } }