void main_vendor_iso_out_received(udd_ep_status_t status, iram_size_t nb_transfered, udd_ep_id_t ep) { uint8_t *buf_ptr; UNUSED(ep); if (UDD_EP_TRANSFER_OK != status) { return; // Transfer aborted, then stop loopback } if (nb_transfered) { ui_loop_back_state(true); // Send on IN endpoint the data received on endpoint OUT buf_ptr = &main_buf_loopback[ main_buf_iso_sel *(sizeof(main_buf_loopback)/2) ]; udi_vendor_iso_in_run( buf_ptr, nb_transfered, main_vendor_iso_in_received); } // Switch of buffer main_buf_iso_sel = main_buf_iso_sel? 0:1; // Immediately enable a transfer on next USB isochronous OUT packet // to avoid to skip a USB packet. // NOTE: // Here the expected buffer size is equal to endpoint size. // Thus, this transfer request will end after reception of // one USB packet. // // When using buffer size larger than endpoint size, // the requested transfer is stopped when the buffer is = full*. // *on USBC and XMEGA USB driver, the buffer is full // when "number of data transfered" > "buffer size" - "endpoint size". buf_ptr = &main_buf_loopback[ main_buf_iso_sel *(sizeof(main_buf_loopback)/2) ]; // Send on IN endpoint the data received on endpoint OUT udi_vendor_iso_out_run( buf_ptr, udd_is_high_speed()? UDI_VENDOR_EPS_SIZE_ISO_HS:UDI_VENDOR_EPS_SIZE_ISO_FS, main_vendor_iso_out_received); }
void usb_iso_received() { // Byte 0-3: First packet control bits (0xAAAAAAAA) // Byte 4-5: Scanning speed in pps (big endian) // Byte 6-7: Size of frame in points (big endian) // Byte 8-X: Point data // Each point: 8 MSB of x, 4 LSB of x + 4 MSB of y, 8 LSB of y, r, g, b, i (7 bytes total) // Byte X-4: Last packet control bits (0xBBBBBBBB) uint8_t* data = usbIsoBufferAddress; bool processPacket = false; bool lastPacket = false; uint8_t intraFramePos = 0; if (!newFrameReady) { //if control bits indicate first packet in frame if ( (data[0] == 0xAA) && (data[1] == 0xAA) && (data[2] == 0xAA) && (data[3] == 0xAA) ) { outputSpeed = ( (data[4] << 8) + data[5] ); newFrameSize = ( ((data[6] << 8) + data[7]) * 7 + 4); if ((outputSpeed > MAXSPEED) || (outputSpeed < MINSPEED)) { //error: wrong speed } else if (newFrameSize > MAXFRAMESIZE) { //error: wrong size } else { intraFramePos = 8; newFramePos = 0; processPacket = true; } } else if (newFramePos != 0) { processPacket = true; } } if (processPacket) { uint16_t bytesToCopy = 512 - intraFramePos; //if last packet in frame expected if ( (newFrameSize - newFramePos) <= bytesToCopy ) { //adjust copy size and position bytesToCopy = newFrameSize - newFramePos; lastPacket = true; } //TODO copy data, below works? memcpy(&newFrameAddress[newFramePos], &data[intraFramePos], bytesToCopy); newFramePos += bytesToCopy; //if last packet in frame expected if (lastPacket) { //if control bytes indicates last packet in frame uint8_t* frameEnd = newFrameAddress+newFrameSize; if ( ( *(frameEnd-0) == 0xBB) && ( *(frameEnd-1) == 0xBB) && ( *(frameEnd-2) == 0xBB) && ( *(frameEnd-3) == 0xBB) ) { //frame successfully received newFrameReady = true; if (!playing) { playing = true; speed_set(outputSpeed); } } else { //faulty frame, discard newFramePos = 0; } } } udi_vendor_iso_out_run(usbIsoBufferAddress, 512, usb_iso_received); }
int callback_vendor_enable(void) { start(); udi_vendor_iso_out_run(usbIsoBufferAddress, 512, usb_iso_received); return 1; }