void usb_endpoint_prime( const usb_endpoint_t* const endpoint, usb_transfer_descriptor_t* const first_td ) { usb_queue_head_t* const qh = usb_queue_head(endpoint->address, endpoint->device); qh->next_dtd_pointer = first_td; qh->total_bytes &= ~( USB_TD_DTD_TOKEN_STATUS_ACTIVE | USB_TD_DTD_TOKEN_STATUS_HALTED ) ; const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if(endpoint->device->controller == 0) { if( usb_endpoint_is_in(endpoint->address) ) { USB0_ENDPTPRIME = USB0_ENDPTPRIME_PETB(1 << endpoint_number); } else { USB0_ENDPTPRIME = USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } if(endpoint->device->controller == 1) { if( usb_endpoint_is_in(endpoint->address) ) { USB1_ENDPTPRIME = USB1_ENDPTPRIME_PETB(1 << endpoint_number); } else { USB1_ENDPTPRIME = USB1_ENDPTPRIME_PERB(1 << endpoint_number); } } }
static void usb_endpoint_set_type( const usb_endpoint_t* const endpoint, const usb_transfer_type_t transfer_type ) { // NOTE: UM10503 section 23.6.24 "Endpoint 1 to 5 control registers" says // that the disabled side of an endpoint must be set to a non-control type // (e.g. bulk, interrupt, or iso). const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if(endpoint->device->controller == 0) { USB0_ENDPTCTRL(endpoint_number) = ( USB0_ENDPTCTRL(endpoint_number) & ~(USB0_ENDPTCTRL_TXT1_0_MASK | USB0_ENDPTCTRL_RXT_MASK) ) | ( USB0_ENDPTCTRL_TXT1_0(transfer_type) | USB0_ENDPTCTRL_RXT(transfer_type) ); } if(endpoint->device->controller == 1) { USB0_ENDPTCTRL(endpoint_number) = ( USB1_ENDPTCTRL(endpoint_number) & ~(USB1_ENDPTCTRL_TXT1_0_MASK | USB1_ENDPTCTRL_RXT_MASK) ) | ( USB1_ENDPTCTRL_TXT1_0(transfer_type) | USB1_ENDPTCTRL_RXT(transfer_type) ); } }
void usb_endpoint_stall( const usb_endpoint_t* const endpoint ) { // Endpoint is to be stalled as a pair -- both OUT and IN. // See UM10503 section 23.10.5.2 "Stalling" const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_RXS | USB0_ENDPTCTRL_TXS); // TODO: Also need to reset data toggle in both directions? }
bool usb_endpoint_is_complete( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number); } else { return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number); } }
/* static bool usb_endpoint_is_flushing( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { return USB0_ENDPTFLUSH & USB0_ENDPTFLUSH_FETB(1 << endpoint_number); } else { return USB0_ENDPTFLUSH & USB0_ENDPTFLUSH_FERB(1 << endpoint_number); } } */ bool usb_endpoint_is_ready( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ETBR(1 << endpoint_number); } else { return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ERBR(1 << endpoint_number); } }
static bool usb_endpoint_is_priming( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number); } else { return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); } }
static void usb_endpoint_clear_pending_interrupts( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number)); } else { usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number)); } }
static void usb_endpoint_enable( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_TXE | USB0_ENDPTCTRL_TXR); } else { USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_RXE | USB0_ENDPTCTRL_RXR); } }
void usb_endpoint_flush( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); usb_queue_flush_endpoint(endpoint); if( usb_endpoint_is_in(endpoint->address) ) { usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FETB(1 << endpoint_number)); } else { usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FERB(1 << endpoint_number)); } }
void usb_endpoint_disable( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); if( usb_endpoint_is_in(endpoint->address) ) { USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_TXE); } else { USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_RXE); } usb_queue_flush_endpoint(endpoint); usb_endpoint_clear_pending_interrupts(endpoint); usb_endpoint_flush(endpoint); }