bool uhi_vendor_iso_out_run(uint8_t * buf, iram_size_t buf_size, uhd_callback_trans_t callback) { if (!uhi_vendor_iso_is_available()) { return false; } return uhd_ep_run(uhi_vendor_dev.dev->address, uhi_vendor_dev.ep_iso_out, false, buf, buf_size, UHI_VENDOR_TIMEOUT, callback); }
//for when you want to update the LED modes or LED states static bool uhi_manta_send_report(void) { if (uhi_manta_report_trans_ongoing) return false; // Transfer on going then send this one after transfer complete // Copy report on other array used only for transfer memcpy(uhi_manta_report_trans, uhi_manta_report, UHI_MANTA_EP_OUT_SIZE); uhi_manta_b_report_valid = false; // Send report return uhi_manta_report_trans_ongoing = uhd_ep_run(uhi_hid_manta_dev.dev->address,uhi_hid_manta_dev.ep_out,false,uhi_manta_report_trans,UHI_MANTA_EP_OUT_SIZE,0,uhi_manta_report_sent); }
static bool uhi_cdc_tx_update(uhi_cdc_line_t *line) { irqflags_t flags; uhi_cdc_buf_t *buf; flags = cpu_irq_save(); // Check if transfer is already on-going if (line->b_trans_ongoing) { cpu_irq_restore(flags); return false; } // Check if transfer must be delayed after the next SOF if (uhi_cdc_dev.dev->speed == UHD_SPEED_HIGH) { if (line->sof == uhd_get_microframe_number()) { cpu_irq_restore(flags); return false; } } else { if (line->sof == uhd_get_frame_number()) { cpu_irq_restore(flags); return false; } } // Send the current buffer if not empty buf = &line->buffer[line->buf_sel]; if (buf->nb == 0) { cpu_irq_restore(flags); return false; } // Change current buffer to next buffer line->buf_sel = (line->buf_sel == 0)? 1 : 0; // Start transfer line->b_trans_ongoing = true; cpu_irq_restore(flags); return uhd_ep_run( uhi_cdc_dev.dev->address, line->ep_data, true, buf->ptr, buf->nb, 1000, uhi_cdc_tx_send); }
/** * \brief Starts the reception of the HID gamepad report * * \param add USB address to use */ static void uhi_hid_start_trans_report(usb_add_t add) { // Start transfer on interrupt endpoint IN // print_dbg("\r\n HID device: running endpoint"); uhd_ep_run(add, uhi_hid_dev.ep_in, true, uhi_hid_dev.report, uhi_hid_dev.report_size, 0, uhi_hid_report_reception); }
static bool uhi_cdc_rx_update(uhi_cdc_line_t *line) { irqflags_t flags; uhi_cdc_buf_t *buf_nosel; uhi_cdc_buf_t *buf_sel; flags = cpu_irq_save(); // Check if transfer is already on-going if (line->b_trans_ongoing) { cpu_irq_restore(flags); return false; } // Search a empty buffer to start a transfer buf_sel = &line->buffer[line->buf_sel]; buf_nosel = &line->buffer[(line->buf_sel == 0)? 1 : 0]; if (buf_sel->pos >= buf_sel->nb) { // The current buffer has been read // then reset it buf_sel->pos = 0; buf_sel->nb = 0; } if (!buf_sel->nb && buf_nosel->nb) { // New data available then change current buffer line->buf_sel = (line->buf_sel == 0)? 1 : 0; buf_nosel = buf_sel; UHI_CDC_RX_NOTIFY(); } if (buf_nosel->nb) { // No empty buffer available to start a transfer cpu_irq_restore(flags); return false; } // Check if transfer must be delayed after the next SOF if (uhi_cdc_dev.dev->speed == UHD_SPEED_HIGH) { if (line->sof == uhd_get_microframe_number()) { cpu_irq_restore(flags); return false; } } else { if (line->sof == uhd_get_frame_number()) { cpu_irq_restore(flags); return false; } } // Start transfer on empty buffer line->b_trans_ongoing = true; cpu_irq_restore(flags); return uhd_ep_run( uhi_cdc_dev.dev->address, line->ep_data, true, buf_nosel->ptr, line->buffer_size, 10, uhi_cdc_rx_received); }
/** * \brief Starts the reception of the HID mouse report * * \param add USB address to use */ static void uhi_hid_mouse_start_trans_report(usb_add_t add) { // Start transfer on interrupt endpoint IN uhd_ep_run(add, uhi_hid_mouse_dev.ep_in, true, uhi_hid_mouse_dev.report, uhi_hid_mouse_dev.report_size, 0, uhi_hid_mouse_report_reception); }
static bool uhi_midi_rx_update(uhi_midi_line_t *line) { irqflags_t flags; uhi_midi_buf_t *buf_nosel; uhi_midi_buf_t *buf_sel; flags = cpu_irq_save(); // Check if transfer is already on-going if (line->b_trans_ongoing) { cpu_irq_restore(flags); return false; } // Search a empty buffer to start a transfer //this makes local variables for the buffers that relate to sel and nosel buf_sel = &line->buffer[line->buf_sel]; buf_nosel = &line->buffer[(line->buf_sel == 0)? 1 : 0]; //if the position in the buffer has gone above or is equal to the number of bytes that were last transferred, reset the number of bytes transferred and the position to 0. if (buf_sel->pos >= buf_sel->nb) { // The current buffer has been read // then reset it buf_sel->pos = 0; buf_sel->nb = 0; } //if the selected buffer is now empty and the other buffer has bytes to transfer, switch the selected and nonselected buffers, and assume there is new data to grab?? if (!buf_sel->nb && buf_nosel->nb) { // New data available then change current buffer line->buf_sel = (line->buf_sel == 0)? 1 : 0; buf_nosel = buf_sel; //LED_On(LED1); UHI_MIDI_RX_NOTIFY(); } // if the nonselected buffer has stuff in it (but the currently selected buffer isn't empty!) then throw an error because there isn't an empty buffer available to start a transfer. if (buf_nosel->nb) { // No empty buffer available to start a transfer cpu_irq_restore(flags); //LED_On(LED0); return false; } // Check if transfer must be delayed after the next SOF if (uhi_midi_dev.dev->speed == UHD_SPEED_HIGH) { if (line->sof == uhd_get_microframe_number()) { cpu_irq_restore(flags); return false; } } else { if (line->sof == uhd_get_frame_number()) { cpu_irq_restore(flags); return false; } } // Start transfer on empty buffer // ok, either both buffers are empty, or there is an empty buffer that we just re-assigned as "nonselected". // in this case, we are ready to set up an endpoint transfer into the empty buffer // let the system know that there is a transmission ongoing line->b_trans_ongoing = true; cpu_irq_restore(flags); //stupid test so that the LEDs show which buffer is selected /* if (line->buf_sel == 0) { LED_On(LED3); } else { LED_Off(LED3); } if (line->buf_sel == 1) { LED_On(LED2); } else { LED_Off(LED2); } */ /// /// it appears that the ep run function gets data from the endpoint and puts it in the "nosel" buffer. Then it runs the rx_received function once this has finished. // there was at one point an issue, where if it times out then it thinks it has new data. I lengthened the timeout, and also made the rx_received function ignore data in the event of a timeout. JS return uhd_ep_run( uhi_midi_dev.dev->address, line->ep_data, true, buf_nosel->ptr, line->buffer_size, 1000, uhi_midi_rx_received); //timeout was 10 originally /* //buf_sel = &line->buffer[0]; //buf_nosel = &line->buffer[0]; if (buf_sel->pos >= buf_sel->nb) { // The current buffer has been read // then reset it buf_sel->pos = 0; buf_sel->nb = 0; LED_On(LED0); } if (!buf_sel->nb && buf_nosel->nb) { // New data available then change current buffer line->buf_sel = (line->buf_sel == 0)? 1 : 0; //buf_nosel = buf_sel; LED_On(LED1); } if (buf_nosel->nb) { // No empty buffer available to start a transfer cpu_irq_restore(flags); LED_On(LED3); return false; } if(buf_sel->nb) { cpu_irq_restore(flags); LED_On(LED3); return false; } // Check if transfer must be delayed after the next SOF if (uhi_midi_dev.dev->speed == UHD_SPEED_HIGH) { if (line->sof == uhd_get_microframe_number()) { cpu_irq_restore(flags); return false; } } else { if (line->sof == uhd_get_frame_number()) { cpu_irq_restore(flags); return false; } } // Start transfer on empty buffer line->b_trans_ongoing = true; cpu_irq_restore(flags); return uhd_ep_run( uhi_midi_dev.dev->address, line->ep_data, true, buf_nosel->ptr, line->buffer_size, 10, uhi_midi_rx_received); */ }