static bool udd_ep_interrupt(void) { udd_ep_id_t ep; udd_ep_job_t *ptr_job; // For each endpoint different of control endpoint (0) for (ep = 1; ep <= USB_DEVICE_MAX_EP; ep++) { // Get job corresponding at endpoint ptr_job = &udd_ep_job[ep - 1]; // Check DMA event if (Is_udd_endpoint_dma_interrupt_enabled(ep) && Is_udd_endpoint_dma_interrupt(ep)) { uint32_t nb_remaining; if( udd_endpoint_dma_get_status(ep) & AVR32_USBB_UDDMA1_STATUS_CH_EN_MASK) { return true; // Ignore EOT_STA interrupt } udd_disable_endpoint_dma_interrupt(ep); // Save number of data no transfered nb_remaining = (udd_endpoint_dma_get_status(ep) & AVR32_USBB_UDDMA1_STATUS_CH_BYTE_CNT_MASK) >> AVR32_USBB_UDDMA1_STATUS_CH_BYTE_CNT_OFFSET; if (nb_remaining) { // Transfer no complete (short packet or ZLP) then: // Update number of data transfered ptr_job->nb_trans -= nb_remaining; // Set transfer complete to stop the transfer ptr_job->buf_size = ptr_job->nb_trans; } udd_ep_trans_done(ep); return true; } // Check empty bank interrupt event if (Is_udd_endpoint_interrupt_enabled(ep)) { if (Is_udd_in_send_interrupt_enabled(ep) && Is_udd_in_send(ep)) { udd_disable_in_send_interrupt(ep); // One bank is free then send a ZLP udd_ack_in_send(ep); udd_ack_fifocon(ep); udd_ep_finish_job(ptr_job, false, ep); return true; } if (Is_udd_bank_interrupt_enabled(ep) && (0 == udd_nb_busy_bank(ep))) { // End of background transfer on IN endpoint udd_disable_bank_interrupt(ep); udd_disable_endpoint_interrupt(ep); Assert(ptr_job->stall_requested); // A stall has been requested during background transfer ptr_job->stall_requested = false; udd_disable_endpoint_bank_autoswitch(ep); udd_enable_stall_handshake(ep); udd_reset_data_toggle(ep); return true; } } }
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) { udd_ep_id_t ep_num; udd_ep_job_t *ptr_job; irqflags_t flags; ep_num = ep & USB_EP_ADDR_MASK; if (USB_DEVICE_MAX_EP < ep_num) { return false; } if ((!Is_udd_endpoint_enabled(ep_num)) || Is_udd_endpoint_stall_requested(ep_num)) { return false; // Endpoint is halted } // Get job about endpoint ptr_job = &udd_ep_job[ep_num - 1]; 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. // ptr_job->buf = buf; ptr_job->buf_size = buf_size; ptr_job->nb_trans = 0; ptr_job->call_trans = callback; ptr_job->b_shortpacket = b_shortpacket; ptr_job->b_use_out_cache_buffer = false; if ( (USB_EP_DIR_IN != (ep & USB_EP_DIR_IN)) && (AVR32_USBC_PTYPE_ISOCHRONOUS == udd_get_endpoint_type(ep_num)) && (0 != (buf_size % udd_get_endpoint_size(ep_num)))) { // The user must use a buffer size modulo endpoint size // for an isochronous IN endpoint ptr_job->busy = false; return false; } // Initialize value to simulate a empty transfer udd_udesc_rst_buf0_ctn(ep_num); udd_udesc_rst_buf0_size(ep_num); // Request next transfer udd_ep_trans_done(ep); return true; }
static bool udd_ep_interrupt(void) { udd_ep_id_t ep, ep_addr; // For each endpoint different of control endpoint (0) for (ep = 1; ep <= USB_DEVICE_MAX_EP; ep++) { if (!Is_udd_endpoint_interrupt_enabled(ep) || !Is_udd_endpoint_interrupt(ep)) { continue; } ep_addr = Is_udd_endpoint_in(ep) ? (ep | USB_EP_DIR_IN) : ep; udd_ep_trans_done(ep_addr); return true; } return false; }
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) { udd_ep_job_t *ptr_job; irqflags_t flags; 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) || ptr_job->stall_requested) { 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. // ptr_job->buf = buf; ptr_job->buf_size = buf_size; ptr_job->nb_trans = 0; ptr_job->call_trans = callback; ptr_job->b_shortpacket = b_shortpacket; // Request first transfer udd_ep_trans_done(ep); return true; }