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); }
void usb_endpoint_init( const usb_endpoint_t* const endpoint ) { usb_endpoint_flush(endpoint); uint_fast16_t max_packet_size = endpoint->device->descriptor[7]; usb_transfer_type_t transfer_type = USB_TRANSFER_TYPE_CONTROL; const uint8_t* const endpoint_descriptor = usb_endpoint_descriptor(endpoint); if( endpoint_descriptor ) { max_packet_size = usb_endpoint_descriptor_max_packet_size(endpoint_descriptor); transfer_type = usb_endpoint_descriptor_transfer_type(endpoint_descriptor); } // TODO: There are more capabilities to adjust based on the endpoint // descriptor. usb_queue_head_t* const qh = usb_queue_head(endpoint->address, endpoint->device); qh->capabilities = USB_QH_CAPABILITIES_MULT(0) | USB_QH_CAPABILITIES_ZLT | USB_QH_CAPABILITIES_MPL(max_packet_size) | ((transfer_type == USB_TRANSFER_TYPE_CONTROL) ? USB_QH_CAPABILITIES_IOS : 0) ; qh->current_dtd_pointer = 0; qh->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; qh->total_bytes = USB_TD_DTD_TOKEN_TOTAL_BYTES(0) | USB_TD_DTD_TOKEN_MULTO(0) ; qh->buffer_pointer_page[0] = 0; qh->buffer_pointer_page[1] = 0; qh->buffer_pointer_page[2] = 0; qh->buffer_pointer_page[3] = 0; qh->buffer_pointer_page[4] = 0; // This is how we look up an endpoint structure from an endpoint address: qh->_reserved_0 = (uint32_t)endpoint; // TODO: Should NAK be enabled? I'm kinda squishy on this... //USB0_ENDPTNAKEN |= // USB0_ENDPTNAKEN_EPRNE(1 << endpoint_out->number); usb_endpoint_set_type(endpoint, transfer_type); usb_endpoint_enable(endpoint); }