Пример #1
0
void udd_ep_free(udd_ep_id_t ep)
{
	UDD_EP_t *ep_ctrl;
	Assert(udd_ep_is_valid(ep));

	udd_ep_abort(ep);
	ep_ctrl = udd_ep_get_ctrl(ep);
	udd_endpoint_disable(ep_ctrl);
}
Пример #2
0
bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t * buf,
		iram_size_t buf_size, udd_callback_trans_t callback)
{
	udd_ep_job_t *ptr_job;
	irqflags_t flags;
	UDD_EP_t *ep_ctrl;

	Assert(udd_ep_is_valid(ep));

	// Get control & job about this endpoint
	ptr_job = udd_ep_get_job(ep);
	ep_ctrl = udd_ep_get_ctrl(ep);

	if (!udd_endpoint_is_enable(ep_ctrl)) {
		return false; // Endpoint not allocated
	}
	if (udd_endpoint_get_type(ep_ctrl)!=USB_EP_TYPE_ISOCHRONOUS_gc
		&& udd_endpoint_is_stall(ep_ctrl)) {
		return false; // Endpoint is halted
	}
	flags = cpu_irq_save();
	if (ptr_job->busy == true) {
		cpu_irq_restore(flags);
		return false; // Job already on going
	}
	ptr_job->busy = true;
	cpu_irq_restore(flags);


	// Update Job information
	ptr_job->buf = buf;
	ptr_job->buf_size = buf_size;
	ptr_job->nb_trans = 0;
	ptr_job->call_trans = callback;
	// Need to enable shortpacket to send a ZLP (buf_size==0)
	ptr_job->b_shortpacket = b_shortpacket || (buf_size==0);
	ptr_job->b_use_out_cache_buffer = false;

	// Initialize value to simulate a empty transfer
	if (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)) {
		udd_endpoint_in_reset_nb_sent(ep_ctrl);
	}
	else
	{
		if ((USB_EP_TYPE_ISOCHRONOUS_gc == udd_endpoint_get_type(ep_ctrl))
		&& (0 != (buf_size % udd_ep_get_size(ep_ctrl)))) {
			// The user must use a buffer size modulo endpoint size
			ptr_job->busy = false;
			return false;
		}
		udd_endpoint_out_reset_nb_received(ep_ctrl);
		udd_endpoint_out_set_nbbyte(ep_ctrl, 0);
	}
	// Request next transfer
	udd_ep_trans_complet(ep);
	return true;
}
bool udd_ep_set_halt(udd_ep_id_t ep)
{
	UDD_EP_t *ep_ctrl;
	Assert(udd_ep_is_valid(ep));

	ep_ctrl = udd_ep_get_ctrl(ep);
	udd_endpoint_enable_stall(ep_ctrl);

	udd_ep_abort(ep);
	return true;
}
Пример #4
0
bool udd_ep_clear_halt(udd_ep_id_t ep)
{
	udd_ep_job_t *ptr_job;
	UDD_EP_t *ep_ctrl;
	Assert(udd_ep_is_valid(ep));

	ep_ctrl = udd_ep_get_ctrl(ep);
	if (!udd_endpoint_is_stall(ep_ctrl)) {
		return true; // No stall on going
	}
	udd_endpoint_disable_stall(ep_ctrl);

	// If a job is register on clear halt action
	// then execute callback
	ptr_job = udd_ep_get_job(ep);
	if (ptr_job->busy == true) {
		ptr_job->busy = false;
		ptr_job->call_nohalt();
	}
	return true;
}
Пример #5
0
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes,
		uint16_t MaxEndpointSize)
{
	UDD_EP_t *ep_ctrl;
	Assert(udd_ep_is_valid(ep));

	ep_ctrl = udd_ep_get_ctrl(ep);
	if (udd_endpoint_is_enable(ep_ctrl)) {
		return false; // Already allocated
	}
	udd_ep_init(ep, bmAttributes, MaxEndpointSize);

	// Do not use multipacket mode with isochronous 1023 bytes endpoint
	if (udd_endpoint_get_type(ep_ctrl)==USB_EP_TYPE_ISOCHRONOUS_gc
			&& (udd_endpoint_get_size_field(ep_ctrl)
			==USB_EP_BUFSIZE_1023_gc)) {
		return true;
	}

	udd_endpoint_set_multipacket(ep_ctrl);
	return true;
}
Пример #6
0
bool udd_ep_wait_stall_clear(udd_ep_id_t ep,
		udd_callback_halt_cleared_t callback)
{
	udd_ep_job_t *ptr_job;
	UDD_EP_t *ep_ctrl;
	Assert(udd_ep_is_valid(ep));

	ep_ctrl = udd_ep_get_ctrl(ep);
	ptr_job = udd_ep_get_job(ep);

	if (udd_endpoint_is_stall(ep_ctrl)) {
		// Wait clear halt endpoint
		if (ptr_job->busy == true) {
			return false; // Job already on going
		}
		ptr_job->busy = true;
		ptr_job->call_nohalt = callback;
	} else {
		// endpoint not halted then call directly callback
		callback();
	}
	return true;
}
Пример #7
0
void udd_ep_abort(udd_ep_id_t ep)
{
	UDD_EP_t *ep_ctrl;
	udd_ep_job_t *ptr_job;
	Assert(udd_ep_is_valid(ep));

	ep_ctrl = udd_ep_get_ctrl(ep);
	ptr_job = udd_ep_get_job(ep);

	// Stop transfer
	udd_endpoint_set_NACK0(ep_ctrl);
	if (ptr_job->busy == false) {
		return; // No job on going
	}
	ptr_job->busy = false;
	if (NULL != ptr_job->call_trans) {
		ptr_job->call_trans(UDD_EP_TRANSFER_ABORT,
				(ep & USB_EP_DIR_IN) ?
				udd_endpoint_in_nb_sent(ep_ctrl)
				: udd_endpoint_out_nb_receiv(ep_ctrl),
				ep);
	}
}