Ejemplo n.º 1
0
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes,
		uint16_t MaxEndpointSize)
{
	bool b_dir_in;
	uint16_t ep_allocated;
	uint8_t bank, i;

	b_dir_in = ep & USB_EP_DIR_IN;
	ep = ep & USB_EP_ADDR_MASK;

	if (ep > USB_DEVICE_MAX_EP) {
		return false;
	}
	if (Is_udd_endpoint_enabled(ep)) {
		return false;
	}

	// Bank choice
	switch(bmAttributes&USB_EP_TYPE_MASK) {
	case USB_EP_TYPE_ISOCHRONOUS:
		bank = UDD_ISOCHRONOUS_NB_BANK(ep);
		break;
	case USB_EP_TYPE_INTERRUPT:
		bank = UDD_INTERRUPT_NB_BANK(ep);
		break;
	case USB_EP_TYPE_BULK:
		bank = UDD_BULK_NB_BANK(ep);
		break;
	default:
		Assert(false);
		return false;
	}
	switch(bank) {
	case 1:
		bank = AVR32_USBB_UECFG0_EPBK_SINGLE;
		break;
	case 2:
		bank = AVR32_USBB_UECFG0_EPBK_DOUBLE;
		break;
	case 3:
		bank = AVR32_USBB_UECFG0_EPBK_TRIPLE;
		break;
	default:
		Assert(false);
		return false;
	}

	// Check if endpoint size is 8,16,32,64,128,256,512 or 1023
	Assert(MaxEndpointSize < 1024);
	Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1)));
	Assert(MaxEndpointSize >= 8);

	// Set configuration of new endpoint
	udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0),
			MaxEndpointSize, bank);
	ep_allocated = 1 << ep;

	// Unalloc endpoints superior
	for (i = USB_DEVICE_MAX_EP; i > ep; i--) {
		if (Is_udd_endpoint_enabled(i)) {
			ep_allocated |= 1 << i;
			udd_disable_endpoint(i);
			udd_unallocate_memory(i);
		}
	}

	// Realloc/Enable endpoints
	for (i = ep; i <= USB_DEVICE_MAX_EP; i++) {
		if (ep_allocated & (1 << i)) {
			udd_ep_job_t *ptr_job = &udd_ep_job[i - 1];
			bool b_restart = ptr_job->busy;
			ptr_job->busy = false;

			udd_allocate_memory(i);
			udd_enable_endpoint(i);
			if (!Is_udd_endpoint_configured(i)) {
				if (NULL == ptr_job->call_trans) {
					return false;
				}
				if (Is_udd_endpoint_in(i)) {
					i |= USB_EP_DIR_IN;
				}				
				ptr_job->call_trans(UDD_EP_TRANSFER_ABORT,
						ptr_job->buf_size, i);
				return false;
			}
			udd_enable_endpoint_bank_autoswitch(i);
			if (b_restart) {
				// Re-run the job
				udd_ep_run(i, ptr_job->b_shortpacket,
						ptr_job->buf,
						ptr_job->buf_size,
						ptr_job->call_trans);
			}
		}
	}
	return true;
}
Ejemplo n.º 2
0
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes,
		uint16_t MaxEndpointSize)
{
	bool b_dir_in;
	uint16_t ep_allocated;
	uint8_t nb_bank, bank, i;

	b_dir_in = ep & USB_EP_DIR_IN;
	ep = ep & USB_EP_ADDR_MASK;

	if (ep > USB_DEVICE_MAX_EP) {
		return false;
	}
	if (Is_udd_endpoint_enabled(ep)) {
		return false;
	}
	dbg_print("alloc(%x, %d) ", ep, MaxEndpointSize);

	// Bank choice
	switch (bmAttributes & USB_EP_TYPE_MASK) {
	case USB_EP_TYPE_ISOCHRONOUS:
		nb_bank = UDD_ISOCHRONOUS_NB_BANK(ep);
		break;
	case USB_EP_TYPE_INTERRUPT:
		nb_bank = UDD_INTERRUPT_NB_BANK(ep);
		break;
	case USB_EP_TYPE_BULK:
		nb_bank = UDD_BULK_NB_BANK(ep);
		break;
	default:
		Assert(false);
		return false;
	}
	switch (nb_bank) {
	case 1:
		bank = UOTGHS_DEVEPTCFG_EPBK_1_BANK >>
				UOTGHS_DEVEPTCFG_EPBK_Pos;
		break;
	case 2:
		bank = UOTGHS_DEVEPTCFG_EPBK_2_BANK >>
				UOTGHS_DEVEPTCFG_EPBK_Pos;
		break;
	case 3:
		bank = UOTGHS_DEVEPTCFG_EPBK_3_BANK >>
				UOTGHS_DEVEPTCFG_EPBK_Pos;
		break;
	default:
		Assert(false);
		return false;
	}

	// Check if endpoint size is 8,16,32,64,128,256,512 or 1023
	Assert(MaxEndpointSize < 1024);
	Assert((MaxEndpointSize == 1023)
		|| !(MaxEndpointSize & (MaxEndpointSize - 1)));
	Assert(MaxEndpointSize >= 8);

	// Set configuration of new endpoint
	udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0),
			MaxEndpointSize, bank);
	ep_allocated = 1 << ep;

	// Unalloc endpoints superior
	for (i = USB_DEVICE_MAX_EP; i > ep; i--) {
		if (Is_udd_endpoint_enabled(i)) {
			ep_allocated |= 1 << i;
			udd_disable_endpoint(i);
			udd_unallocate_memory(i);
		}
	}

	// Realloc/Enable endpoints
	for (i = ep; i <= USB_DEVICE_MAX_EP; i++) {
		if (ep_allocated & (1 << i)) {
			udd_ep_job_t *ptr_job = &udd_ep_job[i - 1];
			bool b_restart = ptr_job->busy;
			// Restart running job because
			// memory window slides up and its data is lost
			ptr_job->busy = false;
			// Re-allocate memory
			udd_allocate_memory(i);
			udd_enable_endpoint(i);
			if (!Is_udd_endpoint_configured(i)) {
				dbg_print("ErrRealloc%d ", i);
				if (NULL == ptr_job->call_trans) {
					return false;
				}
				if (Is_udd_endpoint_in(i)) {
					i |= USB_EP_DIR_IN;
				}
				ptr_job->call_trans(UDD_EP_TRANSFER_ABORT,
						ptr_job->buf_cnt, i);
				return false;
			}
			udd_enable_endpoint_bank_autoswitch(i);
			if (b_restart) {
				// Re-run the job remaining part
				ptr_job->buf_cnt -= ptr_job->buf_load;
				b_restart = udd_ep_run(Is_udd_endpoint_in(i) ?
							(i | USB_EP_DIR_IN) : i,
						ptr_job->b_shortpacket,
						&ptr_job->buf[ptr_job->buf_cnt],
						ptr_job->buf_size
							- ptr_job->buf_cnt,
						ptr_job->call_trans);
				if (!b_restart) {
					dbg_print("ErrReRun%d ", i);
					return false;
				}
			}
		}
	}
	return true;
}