bool udd_ep_is_halted(udd_ep_id_t ep) { uint8_t ep_index = ep & USB_EP_ADDR_MASK; return Is_udd_endpoint_stall_requested(ep_index); }
bool udd_ep_is_halted(udd_ep_id_t ep) { return Is_udd_endpoint_stall_requested(ep & USB_EP_ADDR_MASK); }
bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t * buf, iram_size_t buf_size, udd_callback_trans_t callback) { uint16_t ep_size, trans_size, short_packet; bool b_dir_in; udd_ep_job_t *ptr_job; irqflags_t flags; b_dir_in = (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)); ep &= USB_EP_ADDR_MASK; if (USB_DEVICE_MAX_EP < ep) return false; // Get job about endpoint ptr_job = &udd_ep_job[ep - 1]; if ((!Is_udd_endpoint_enabled(ep)) || Is_udd_endpoint_stall_requested(ep)) return false; // Endpoint is halted flags = cpu_irq_save(); if (ptr_job->busy == true) { cpu_irq_restore(flags); return false; // Job already on going } ptr_job->busy = true; cpu_irq_restore(flags); // No job running. Let's setup a new one. // // The USB hardware support a maximum transfer size of 0x7FFF Bytes ep_size = udd_get_endpoint_size(ep); if (0x7FFF < buf_size) { trans_size = 0x7FFF - (0x7FFF % ep_size); short_packet = 0; } else { trans_size = buf_size; short_packet = trans_size % ep_size; } if (b_dir_in) { // Need ZLP, if requested and last packet is not a short packet udd_udesc_set_buf0_autozlp(ep, b_shortpacket); udd_udesc_set_buf0_ctn(ep, trans_size); udd_udesc_rst_buf0_size(ep); // Link the user buffer directly on USB hardware DMA udd_udesc_set_buf0_addr(ep, buf); } else { udd_udesc_rst_buf0_ctn(ep); ptr_job->nb_trans = 0; if (trans_size < ep_size) { // The user buffer is smaller than endpoint size if (AVR32_USBC_PTYPE_ISOCHRONOUS == udd_get_endpoint_type(ep)) { ptr_job->busy = false; return false; // The user must use a buffer corresponding at isochrnous endpoint size } // Use the cache buffer for Bulk or Interrupt size endpoint ptr_job->b_use_out_cache_buffer = true; udd_udesc_set_buf0_addr(ep, udd_ep_out_cache_buffer[ep - 1]); udd_udesc_set_buf0_size(ep, ep_size); } else { // Link the user buffer directly on USB hardware DMA ptr_job->b_use_out_cache_buffer = false; udd_udesc_set_buf0_addr(ep, buf); udd_udesc_set_buf0_size(ep, trans_size - short_packet); } } // Update Job information ptr_job->buf = buf; ptr_job->buf_size = trans_size; ptr_job->call_trans = callback; ptr_job->busy = true; // Start transfer udd_disable_busy_bank0(ep); // Enable interrupt flags = cpu_irq_save(); if (b_dir_in) { udd_ack_fifocon(ep); udd_ack_in_send(ep); udd_enable_in_send_interrupt(ep); } else { udd_enable_out_received_interrupt(ep); } udd_enable_endpoint_interrupt(ep); cpu_irq_restore(flags); return true; }