static void usb_check_for_setup_events(const usb_device_t* const device) { const uint32_t endptsetupstat = usb_get_endpoint_setup_status(device); if( endptsetupstat ) { for( uint_fast8_t i=0; i<6; i++ ) { const uint32_t endptsetupstat_bit = USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(1 << i); if( endptsetupstat & endptsetupstat_bit ) { usb_endpoint_t* const endpoint = usb_endpoint_from_address( usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i), device); if( endpoint && endpoint->setup_complete ) { copy_setup(&endpoint->setup, usb_queue_head(endpoint->address, endpoint->device)->setup); // TODO: Clean up this duplicated effort by providing // a cleaner way to get the SETUP data. copy_setup(&endpoint->in->setup, usb_queue_head(endpoint->address, endpoint->device)->setup); usb_clear_endpoint_setup_status(endptsetupstat_bit, device); endpoint->setup_complete(endpoint); } else { usb_clear_endpoint_setup_status(endptsetupstat_bit, device); } } } } }
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); } } }
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); }
static usb_endpoint_t* usb_endpoint_from_address( const uint_fast8_t endpoint_address, const usb_device_t* const device ) { return (usb_endpoint_t*)usb_queue_head(endpoint_address, device)->_reserved_0; }
static usb_endpoint_t* usb_endpoint_from_address( const uint_fast8_t endpoint_address ) { return (usb_endpoint_t*)usb_queue_head(endpoint_address)->_reserved_0; }