/** * \brief Allocation of the control endpoint * * \param address USB address of endpoint * \param ep_size control endpoint size */ static void main_usb_enable_ctrl_ep(uint8_t address, uint8_t ep_size) { // Configure USB address udd_disable_address(); udd_configure_address(address); udd_enable_address(); // Alloc and configure control endpoint udd_disable_endpoint(0); udd_unallocate_memory(0); #if SAM3XA udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0, ep_size, UOTGHS_DEVEPTCFG_EPBK_1_BANK); #else udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0, ep_size, AVR32_USBB_UECFG0_EPBK_SINGLE); #endif udd_allocate_memory(0); udd_enable_endpoint(0); }
void udd_test_mode_packet(void) { irqflags_t flags; const uint8_t test_packet[] = { // 00000000 * 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 01010101 * 8 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // 01110111 * 8 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, // 0, {111111S * 15}, 111111 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // S, 111111S, {0111111S * 7} 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, // 00111111, {S0111111 * 9}, S0 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E }; // Reconfigure control endpoint to bulk IN endpoint udd_disable_endpoint(0); udd_configure_endpoint(0, USB_EP_TYPE_BULK, 1, 64, AVR32_USBC_UECFG0_EPBK_SINGLE); udd_enable_hs_test_mode(); udd_enable_hs_test_mode_packet(); // Send packet on endpoint 0 udd_udesc_set_buf0_addr(0, (uint8_t *) test_packet); flags = cpu_irq_save(); udd_enable_in_send_interrupt(0); cpu_irq_restore(flags); udd_ack_in_send(0); }
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { uint8_t ep_addr = ep & USB_EP_ADDR_MASK; if (Is_udd_endpoint_enabled(ep_addr)) { return false; } // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 Assert(MaxEndpointSize < 1024); Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1))); Assert(MaxEndpointSize >= 8); // Check endpoint type Assert(((bmAttributes & USB_EP_TYPE_MASK) == USB_EP_TYPE_ISOCHRONOUS) || ((bmAttributes & USB_EP_TYPE_MASK) == USB_EP_TYPE_BULK) || ((bmAttributes & USB_EP_TYPE_MASK) == USB_EP_TYPE_INTERRUPT)); udd_configure_endpoint(ep_addr, bmAttributes, ((ep & USB_EP_DIR_IN) ? 1 : 0), MaxEndpointSize, AVR32_USBC_UECFG0_EPBK_SINGLE); udd_enable_busy_bank0(ep_addr); udd_enable_endpoint(ep_addr); #if (defined USB_DISABLE_NYET_FOR_OUT_ENDPOINT) // Disable the NYET feature for OUT endpoint. Using OUT multipacket, each // OUT packet are always NYET. if (!(ep & USB_EP_DIR_IN)) { udd_disable_nyet(ep_addr); } #endif return true; }
static void udd_reset_ep_ctrl(void) { irqflags_t flags; // Reset USB address to 0 udd_configure_address(0); udd_enable_address(); // Alloc and configure control endpoint udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0, USB_DEVICE_EP_CTRL_SIZE, AVR32_USBC_UECFG0_EPBK_SINGLE); // Use internal buffer for endpoint control udd_udesc_set_buf0_addr(0, udd_ctrl_buffer); // don't use multipacket on endpoint control udd_udesc_rst_buf0_size(0); udd_enable_endpoint(0); udd_disable_busy_bank0(0); flags = cpu_irq_save(); udd_enable_setup_received_interrupt(0); udd_enable_out_received_interrupt(0); udd_enable_endpoint_interrupt(0); cpu_irq_restore(flags); }
static void udd_reset_ep_ctrl(void) { irqflags_t flags; // Reset USB address to 0 udd_enable_address(); udd_configure_address(0); // Alloc and configure control endpoint in OUT direction udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0); udd_enable_endpoint(0); flags = cpu_irq_save(); udd_enable_endpoint_interrupt(0); cpu_irq_restore(flags); }
void udd_test_mode_packet(void) { uint8_t i; uint8_t *ptr_dest; const uint8_t *ptr_src; irqflags_t flags; const uint8_t test_packet[] = { // 00000000 * 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 01010101 * 8 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, // 01110111 * 8 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, // 0, {111111S * 15}, 111111 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // S, 111111S, {0111111S * 7} 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, // 00111111, {S0111111 * 9}, S0 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E }; // Reconfigure control endpoint to bulk IN endpoint udd_disable_endpoint(0); udd_configure_endpoint(0, USB_EP_TYPE_BULK, 1, 64, AVR32_USBB_UECFG0_EPBK_SINGLE); udd_allocate_memory(0); udd_enable_endpoint(0); udd_enable_hs_test_mode(); udd_enable_hs_test_mode_packet(); // Send packet on endpoint 0 ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); ptr_src = test_packet; for (i = 0; i < sizeof(test_packet); i++) { *ptr_dest++ = *ptr_src++; } flags = cpu_irq_save(); udd_enable_in_send_interrupt(0); cpu_irq_restore(flags); udd_ack_in_send(0); }
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { udd_ep_job_t *ptr_job; bool b_dir_in; bool b_iso; b_dir_in = ep & USB_EP_DIR_IN; b_iso = (bmAttributes&USB_EP_TYPE_MASK) == USB_EP_TYPE_ISOCHRONOUS; ep = ep & USB_EP_ADDR_MASK; if (ep > USB_DEVICE_MAX_EP) { return false; } if (Is_udd_endpoint_enabled(ep)) { return false; } // Check parameters if (b_iso && (!udd_is_endpoint_support_iso(ep))) { return false; } if (MaxEndpointSize > udd_get_endpoint_size_max(ep)) { return false; } ptr_job = &udd_ep_job[ep - 1]; // Set endpoint size ptr_job->size = MaxEndpointSize; ptr_job->b_buf_end = false; ptr_job->b_stall_requested = false; if (b_dir_in) { // No data buffered in FIFO ptr_job->bank = 0; } // Reset FIFOs udd_reset_endpoint(ep); // Set configuration of new endpoint udd_configure_endpoint(ep, (b_dir_in ? (bmAttributes | 0x4) : bmAttributes), 0); return true; }
static void udd_reset_ep_ctrl(void) { irqflags_t flags; // Reset USB address to 0 udd_configure_address(0); udd_enable_address(); // Alloc and configure control endpoint udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0, USB_DEVICE_EP_CTRL_SIZE, AVR32_USBB_UECFG0_EPBK_SINGLE); udd_allocate_memory(0); udd_enable_endpoint(0); flags = cpu_irq_save(); udd_enable_setup_received_interrupt(0); udd_enable_out_received_interrupt(0); udd_enable_endpoint_interrupt(0); cpu_irq_restore(flags); }
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { bool b_dir_in; uint16_t ep_allocated; uint8_t bank, i; b_dir_in = ep & USB_EP_DIR_IN; ep = ep & USB_EP_ADDR_MASK; if (ep > USB_DEVICE_MAX_EP) { return false; } if (Is_udd_endpoint_enabled(ep)) { return false; } // Bank choice switch(bmAttributes&USB_EP_TYPE_MASK) { case USB_EP_TYPE_ISOCHRONOUS: bank = UDD_ISOCHRONOUS_NB_BANK(ep); break; case USB_EP_TYPE_INTERRUPT: bank = UDD_INTERRUPT_NB_BANK(ep); break; case USB_EP_TYPE_BULK: bank = UDD_BULK_NB_BANK(ep); break; default: Assert(false); return false; } switch(bank) { case 1: bank = AVR32_USBB_UECFG0_EPBK_SINGLE; break; case 2: bank = AVR32_USBB_UECFG0_EPBK_DOUBLE; break; case 3: bank = AVR32_USBB_UECFG0_EPBK_TRIPLE; break; default: Assert(false); return false; } // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 Assert(MaxEndpointSize < 1024); Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1))); Assert(MaxEndpointSize >= 8); // Set configuration of new endpoint udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0), MaxEndpointSize, bank); ep_allocated = 1 << ep; // Unalloc endpoints superior for (i = USB_DEVICE_MAX_EP; i > ep; i--) { if (Is_udd_endpoint_enabled(i)) { ep_allocated |= 1 << i; udd_disable_endpoint(i); udd_unallocate_memory(i); } } // Realloc/Enable endpoints for (i = ep; i <= USB_DEVICE_MAX_EP; i++) { if (ep_allocated & (1 << i)) { udd_ep_job_t *ptr_job = &udd_ep_job[i - 1]; bool b_restart = ptr_job->busy; ptr_job->busy = false; udd_allocate_memory(i); udd_enable_endpoint(i); if (!Is_udd_endpoint_configured(i)) { if (NULL == ptr_job->call_trans) { return false; } if (Is_udd_endpoint_in(i)) { i |= USB_EP_DIR_IN; } ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, ptr_job->buf_size, i); return false; } udd_enable_endpoint_bank_autoswitch(i); if (b_restart) { // Re-run the job udd_ep_run(i, ptr_job->b_shortpacket, ptr_job->buf, ptr_job->buf_size, ptr_job->call_trans); } } } return true; }
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { bool b_dir_in; uint16_t ep_allocated; uint8_t bank, i; b_dir_in = ep & USB_EP_DIR_IN; ep = ep & USB_EP_ADDR_MASK; if (ep > USB_DEVICE_MAX_EP) return false; if (Is_udd_endpoint_enabled(ep)) return false; // Bank choise switch(bmAttributes&USB_EP_TYPE_MASK) { case USB_EP_TYPE_ISOCHRONOUS: bank = UDD_ISOCHRONOUS_NB_BANK; break; case USB_EP_TYPE_INTERRUPT: bank = UDD_INTERRUPT_NB_BANK; break; case USB_EP_TYPE_BULK: bank = UDD_BULK_NB_BANK; break; default: Assert(false); return false; } switch(bank) { case 1: bank = AVR32_USBB_UECFG0_EPBK_SINGLE; break; case 2: bank = AVR32_USBB_UECFG0_EPBK_DOUBLE; break; case 3: bank = AVR32_USBB_UECFG0_EPBK_TRIPLE; break; } // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 Assert(MaxEndpointSize < 1024); Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1))); Assert(MaxEndpointSize >= 8); // Set configuration of new endpoint udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0), MaxEndpointSize, bank); ep_allocated = 1 << ep; // Unalloc endpoints superior for (i = USB_DEVICE_MAX_EP; i > ep; i--) { if (Is_udd_endpoint_enabled(i)) { ep_allocated |= 1 << i; udd_disable_endpoint(i); udd_unallocate_memory(i); } } // Realloc/Enable endpoints for (i = ep; i <= USB_DEVICE_MAX_EP; i++) { if (ep_allocated & (1 << i)) { udd_allocate_memory(i); udd_enable_endpoint(i); if (!Is_udd_endpoint_configured(i)) return false; } } return true; }
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, uint16_t MaxEndpointSize) { bool b_dir_in; uint16_t ep_allocated; uint8_t nb_bank, bank, i; b_dir_in = ep & USB_EP_DIR_IN; ep = ep & USB_EP_ADDR_MASK; if (ep > USB_DEVICE_MAX_EP) { return false; } if (Is_udd_endpoint_enabled(ep)) { return false; } dbg_print("alloc(%x, %d) ", ep, MaxEndpointSize); // Bank choice switch (bmAttributes & USB_EP_TYPE_MASK) { case USB_EP_TYPE_ISOCHRONOUS: nb_bank = UDD_ISOCHRONOUS_NB_BANK(ep); break; case USB_EP_TYPE_INTERRUPT: nb_bank = UDD_INTERRUPT_NB_BANK(ep); break; case USB_EP_TYPE_BULK: nb_bank = UDD_BULK_NB_BANK(ep); break; default: Assert(false); return false; } switch (nb_bank) { case 1: bank = UOTGHS_DEVEPTCFG_EPBK_1_BANK >> UOTGHS_DEVEPTCFG_EPBK_Pos; break; case 2: bank = UOTGHS_DEVEPTCFG_EPBK_2_BANK >> UOTGHS_DEVEPTCFG_EPBK_Pos; break; case 3: bank = UOTGHS_DEVEPTCFG_EPBK_3_BANK >> UOTGHS_DEVEPTCFG_EPBK_Pos; break; default: Assert(false); return false; } // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 Assert(MaxEndpointSize < 1024); Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1))); Assert(MaxEndpointSize >= 8); // Set configuration of new endpoint udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0), MaxEndpointSize, bank); ep_allocated = 1 << ep; // Unalloc endpoints superior for (i = USB_DEVICE_MAX_EP; i > ep; i--) { if (Is_udd_endpoint_enabled(i)) { ep_allocated |= 1 << i; udd_disable_endpoint(i); udd_unallocate_memory(i); } } // Realloc/Enable endpoints for (i = ep; i <= USB_DEVICE_MAX_EP; i++) { if (ep_allocated & (1 << i)) { udd_ep_job_t *ptr_job = &udd_ep_job[i - 1]; bool b_restart = ptr_job->busy; // Restart running job because // memory window slides up and its data is lost ptr_job->busy = false; // Re-allocate memory udd_allocate_memory(i); udd_enable_endpoint(i); if (!Is_udd_endpoint_configured(i)) { dbg_print("ErrRealloc%d ", i); if (NULL == ptr_job->call_trans) { return false; } if (Is_udd_endpoint_in(i)) { i |= USB_EP_DIR_IN; } ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, ptr_job->buf_cnt, i); return false; } udd_enable_endpoint_bank_autoswitch(i); if (b_restart) { // Re-run the job remaining part ptr_job->buf_cnt -= ptr_job->buf_load; b_restart = udd_ep_run(Is_udd_endpoint_in(i) ? (i | USB_EP_DIR_IN) : i, ptr_job->b_shortpacket, &ptr_job->buf[ptr_job->buf_cnt], ptr_job->buf_size - ptr_job->buf_cnt, ptr_job->call_trans); if (!b_restart) { dbg_print("ErrReRun%d ", i); return false; } } } } return true; }