Exemple #1
0
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);
				}
			}
		}
	}
}
Exemple #2
0
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);
		}
	}
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
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;
}