⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_hcd.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* toggel data01*/
	g_UsbHcdInfo.ep_info[index].data01^=1;

	/* determine endpoint control type*/
	if(g_UsbHcdInfo.ep_info[index].ep_type!=USB_HCD_ENDPT_CTRL)
		EXT_ASSERT(0, index, g_UsbHcdInfo.ep_info[index].ep_type, 0);

	ep_ctrl_type = VUSB_ENDPT_CONTROL;

	DRV_WriteReg8(USB_ENDPT_CTL(0), ep_ctrl_type);

	/* send token in the last step*/
	DRV_WriteReg8(USB_TOKEN, VUSB_TOKEN_SETUP|(g_UsbHcdInfo.ep_info[index].ep_num&VUSB_TOKEN_ENDPT));
}

static void USB_HCD_Send_Data (kal_uint8 index)
{
	kal_uint8 ep_ctrl_type;
	kal_uint16 todo;

#ifdef  __PRODUCTION_RELEASE__	
	while(DRV_Reg8(USB_CTL)&VUSB_CTL_TOKEN_BUSY)
	{
		/* wait until the previous done*/
	}
#else
	if(DRV_Reg8(USB_CTL)&VUSB_CTL_TOKEN_BUSY)
	{
		// token should be sent only when the previous has been completed
		ASSERT(0);
	}	
#endif

	/* make sure no other tx EP is processing*/
	if(g_UsbHcdInfo.tx_curent_index != -1)
		EXT_ASSERT(0, g_UsbHcdInfo.tx_curent_index, 0, 0);

	g_UsbHcdInfo.tx_curent_index = index;

	if(g_UsbHcdInfo.ep_info[index].b_fast_mode_enable==KAL_TRUE)
	{
		USB_HCD_DMA_Setup(index, USB_OUT_EP_TYPE, (kal_uint32)g_UsbHcdInfo.ep_info[index].p_data, 
							g_UsbHcdInfo.ep_info[index].data_length, KAL_FALSE);
	}
	else
	{
		if((g_UsbHcdInfo.ep_info[index].data_length-g_UsbHcdInfo.ep_info[index].sofar)
			>g_UsbHcdInfo.ep_info[index].max_packet_size)
			todo = g_UsbHcdInfo.ep_info[index].max_packet_size;
		else
			todo = g_UsbHcdInfo.ep_info[index].data_length-g_UsbHcdInfo.ep_info[index].sofar;

		/* copy data to FIFO*/
		kal_mem_cpy((void*)READ_EP0_BDT_ADDR(USB_BDT_TX, g_UsbHcdInfo.tx_even_odd),
						&g_UsbHcdInfo.ep_info[index].p_data[g_UsbHcdInfo.ep_info[index].sofar], todo);

		/* setup bdt. include own bit. */
		WRITE_EP0_BDT_PID(USB_BDT_TX, g_UsbHcdInfo.tx_even_odd,
							(todo<<VUSB_BDT_BC_SHIFT)
							|(g_UsbHcdInfo.ep_info[index].data01<<VUSB_BDT_DATA01_SHIFT)|VUSB_BDT_OWNS_BIT);

		/* toggel data01*/
		g_UsbHcdInfo.ep_info[index].data01^=1;

		/* determine endpoint control type*/
		switch(g_UsbHcdInfo.ep_info[index].ep_type)
		{
		case USB_HCD_ENDPT_CTRL:
			ep_ctrl_type = VUSB_ENDPT_CONTROL;
			break;
		case USB_HCD_ENDPT_BULK:
			ep_ctrl_type = VUSB_ENDPT_BULK_TX;
			break;
		case USB_HCD_ENDPT_INTR:
			ep_ctrl_type = VUSB_ENDPT_BULK_TX;
			break;
		case USB_HCD_ENDPT_ISO:
			ep_ctrl_type = VUSB_ENDPT_ISO_TX;
			break;	
		default:
			ep_ctrl_type = 0;
			ASSERT(0);	
			break;
		}

		DRV_WriteReg8(USB_ENDPT_CTL(0), ep_ctrl_type);

		/* send token in the last step*/
		DRV_WriteReg8(USB_TOKEN, VUSB_TOKEN_OUT|(g_UsbHcdInfo.ep_info[index].ep_num&VUSB_TOKEN_ENDPT));
	}
}

static void USB_HCD_Recv_Data (kal_uint8 index)
{
	kal_uint8 ep_ctrl_type;
	kal_uint16 todo;

#ifdef  __PRODUCTION_RELEASE__	
	while(DRV_Reg8(USB_CTL)&VUSB_CTL_TOKEN_BUSY)
	{
		/* wait until the previous done*/
	}
#else
	if(DRV_Reg8(USB_CTL)&VUSB_CTL_TOKEN_BUSY)
	{
		// token should be sent only when the previous has been completed
		ASSERT(0);
	}	
#endif

	/* make sure no other tx EP is processing*/
	if(g_UsbHcdInfo.rx_curent_index != -1)
		EXT_ASSERT(0, g_UsbHcdInfo.rx_curent_index, 0, 0);

	g_UsbHcdInfo.rx_curent_index = index;


	if(g_UsbHcdInfo.ep_info[index].b_fast_mode_enable==KAL_TRUE)
	{
		USB_HCD_DMA_Setup(index, USB_IN_EP_TYPE, (kal_uint32)g_UsbHcdInfo.ep_info[index].p_data, 
							g_UsbHcdInfo.ep_info[index].data_length, KAL_FALSE);
	}
	else
	{
		if((g_UsbHcdInfo.ep_info[index].data_length-g_UsbHcdInfo.ep_info[index].sofar)
			>g_UsbHcdInfo.ep_info[index].max_packet_size)
			todo = g_UsbHcdInfo.ep_info[index].max_packet_size;
		else
			todo = g_UsbHcdInfo.ep_info[index].data_length-g_UsbHcdInfo.ep_info[index].sofar;
		
		/* setup bdt. include own bit. */
		WRITE_EP0_BDT_PID(USB_BDT_RX, g_UsbHcdInfo.rx_even_odd,
							(todo<<VUSB_BDT_BC_SHIFT)
							|(g_UsbHcdInfo.ep_info[index].data01<<VUSB_BDT_DATA01_SHIFT)|VUSB_BDT_OWNS_BIT);

		/* toggel data01*/
		g_UsbHcdInfo.ep_info[index].data01^=1;

		/* determine endpoint control type*/
		switch(g_UsbHcdInfo.ep_info[index].ep_type)
		{
		case USB_HCD_ENDPT_CTRL:
			ep_ctrl_type = VUSB_ENDPT_CONTROL;
			break;
		case USB_HCD_ENDPT_BULK:
			ep_ctrl_type = VUSB_ENDPT_BULK_RX;
			break;
		case USB_HCD_ENDPT_INTR:
			ep_ctrl_type = VUSB_ENDPT_BULK_RX;
			break;
		case USB_HCD_ENDPT_ISO:
			ep_ctrl_type = VUSB_ENDPT_ISO_RX;
			break;	
		default:
			ep_ctrl_type = 0;
			ASSERT(0);	
			break;
		}

		DRV_WriteReg8(USB_ENDPT_CTL(0), ep_ctrl_type);

		/* send token in the last step*/
		DRV_WriteReg8(USB_TOKEN, VUSB_TOKEN_IN|(g_UsbHcdInfo.ep_info[index].ep_num&VUSB_TOKEN_ENDPT));
	}
}


static void USB_HCD_Queue_Pkt(kal_uint8 index)
{
	kal_int8 *p_head;
	kal_int8 *p_tail;
	
	switch(g_UsbHcdInfo.ep_info[index].ep_type)
	{
	case USB_HCD_ENDPT_BULK:
		p_head = &g_UsbHcdInfo.bulk_pipe_head;
		p_tail = &g_UsbHcdInfo.bulk_pipe_tail;
		break;
	case USB_HCD_ENDPT_CTRL:
		p_head = &g_UsbHcdInfo.ctrl_pipe_head;
		p_tail = &g_UsbHcdInfo.ctrl_pipe_tail;
		break;	
	case USB_HCD_ENDPT_INTR:
		p_head = &g_UsbHcdInfo.intr_pipe_head;
		p_tail = &g_UsbHcdInfo.intr_pipe_tail;
		break;
	case USB_HCD_ENDPT_ISO:
		p_head = &g_UsbHcdInfo.iso_pipe_head;
		p_tail = &g_UsbHcdInfo.iso_pipe_tail;
		break;	
	default:
		p_head = 0;
		p_tail = 0;
		EXT_ASSERT(0, index, g_UsbHcdInfo.ep_info[index].ep_type, 0);
		break;
	}

	if((*p_head)==-1)
	{
		g_UsbHcdInfo.ep_info[index].next_ep_id = -1;
		*p_head = index;
		*p_tail = index;
	}
	else
	{
		g_UsbHcdInfo.ep_info[*p_tail].next_ep_id = index;
		g_UsbHcdInfo.ep_info[index].next_ep_id = -1;
		*p_tail = index;
	}
}

static void USB_HCD_Remove_Pkt(kal_uint8 index)
{
	kal_int8 *p_head;
	kal_int8 *p_tail;
	
	switch(g_UsbHcdInfo.ep_info[index].ep_type)
	{
	case USB_HCD_ENDPT_BULK:
		p_head = &g_UsbHcdInfo.bulk_pipe_head;
		p_tail = &g_UsbHcdInfo.bulk_pipe_tail;
		break;
	case USB_HCD_ENDPT_CTRL:
		p_head = &g_UsbHcdInfo.ctrl_pipe_head;
		p_tail = &g_UsbHcdInfo.ctrl_pipe_tail;
		break;	
	case USB_HCD_ENDPT_INTR:
		p_head = &g_UsbHcdInfo.intr_pipe_head;
		p_tail = &g_UsbHcdInfo.intr_pipe_tail;
		break;
	case USB_HCD_ENDPT_ISO:
		p_head = &g_UsbHcdInfo.iso_pipe_head;
		p_tail = &g_UsbHcdInfo.iso_pipe_tail;
		break;	
	default:
		p_head = 0;
		p_tail = 0;
		EXT_ASSERT(0, index, g_UsbHcdInfo.ep_info[index].ep_type, 0);
		break;
	}

	if(g_UsbHcdInfo.ep_info[index].next_ep_id==-1)
	{
		*p_head = -1;
		*p_tail = -1;
	}
	else
	{
		*p_head = g_UsbHcdInfo.ep_info[index].next_ep_id;
		g_UsbHcdInfo.ep_info[index].next_ep_id = -1;
	}
}

static kal_int8 USB_HCD_Get_Pending_Pkts(void)
{
	kal_int8	head = -1;

	if(g_UsbHcdInfo.iso_pipe_head!=-1)
	{
		head = g_UsbHcdInfo.iso_pipe_head;
		// note that it needs to modified if more than one iso pipe	
		if(head!=-1)
		{
			if(g_UsbHcdInfo.ep_info[head].current_interval!=0)
				head = -1;
		}
	}
	else if(g_UsbHcdInfo.intr_pipe_head!=-1)
	{
		// note that it needs to modified if more than one intr pipe
		head = g_UsbHcdInfo.intr_pipe_head;
		if(head!=-1)
		{
			if(g_UsbHcdInfo.ep_info[head].current_interval!=0)
				head = -1;
		}
	}
	else if(g_UsbHcdInfo.ctrl_pipe_head!=-1)
	{
		head = g_UsbHcdInfo.ctrl_pipe_head;
		if(head!=-1)
		{
			if(g_UsbHcdInfo.ep_info[head].current_interval==0)
			{
				USB_HCD_Remove_Pkt(head);
				/* callback to USB stack, timeout error*/
				if(g_UsbHcdInfo.ep_hdlr[head]!=NULL)
					g_UsbHcdInfo.ep_hdlr[head](USB_HCD_TIMEOUT, g_UsbHcdInfo.ep_info[head].sofar);
				head = -1;
			}	
		}
	}
	else if(g_UsbHcdInfo.bulk_pipe_head!=-1)
	{
		head = g_UsbHcdInfo.bulk_pipe_head;
		if(head!=-1)
		{
			if((g_UsbHcdInfo.ep_info[head].current_interval==0) && (g_UsbHcdInfo.ep_info[head].b_fast_mode_enable==KAL_FALSE))
			{
				USB_HCD_Remove_Pkt(head);
				/* callback to USB stack, timeout error*/
				if(g_UsbHcdInfo.ep_hdlr[head]!=NULL)
					g_UsbHcdInfo.ep_hdlr[head](USB_HCD_TIMEOUT, g_UsbHcdInfo.ep_info[head].sofar);
				head = -1;
			}	
		}
	}

	return head;
}

static void USB_HCD_Sched_Pending_Pkts(void)
{
	kal_int8	head = -1;

	head = USB_HCD_Get_Pending_Pkts();
	
	g_UsbHcdInfo.processing_ep_id = head;

	if((head==0) && (g_UsbHcdInfo.ep0_setup==KAL_TRUE))
	{
		USB_HCD_Send_Setup(head);
	}
	else if(head!=-1)
	{
		if(g_UsbHcdInfo.ep_info[head].direction==USB_HCD_PIPE_DIR_IN)
		{
			USB_HCD_Recv_Data(head);
		}
		else
		{
			USB_HCD_Send_Data(head);
		}
	}
}

/* return value means if there is any pipe timeout*/
static void USB_HCD_Update_Interval(void)
{
	kal_int8	pipe_id;

	pipe_id = g_UsbHcdInfo.iso_pipe_head;
	while(pipe_id!=-1)
	{
		if(g_UsbHcdInfo.ep_info[pipe_id].current_interval!=0)
		{
			g_UsbHcdInfo.ep_info[pipe_id].current_interval--;
		}
		pipe_id = g_UsbHcdInfo.ep_info[pipe_id].next_ep_id;
	}

	pipe_id = g_UsbHcdInfo.intr_pipe_head;
	while(pipe_id!=-1)
	{
		if(g_UsbHcdInfo.ep_info[pipe_id].current_interval!=0)
		{
			g_UsbHcdInfo.ep_info[pipe_id].current_interval--;
		}
		pipe_id = g_UsbHcdInfo.ep_info[pipe_id].next_ep_id;
	}

	pipe_id = g_UsbHcdInfo.ctrl_pipe_head;
	while(pipe_id!=-1)
	{
		if(g_UsbHcdInfo.ep_info[pipe_id].current_interval!=0)
		{
			g_UsbHcdInfo.ep_info[pipe_id].current_interval--;
		}
		pipe_id = g_UsbHcdInfo.ep_info[pipe_id].next_ep_id;
	}

	pipe_id = g_UsbHcdInfo.bulk_pipe_head;
	while(pipe_id!=-1)
	{
		if(g_UsbHcdInfo.ep_info[pipe_id].current_interval!=0)
		{
			g_UsbHcdInfo.ep_info[pipe_id].current_interval--;
		}
		pipe_id = g_UsbHcdInfo.ep_info[pipe_id].next_ep_id;
	}

}


/************************************************************
	Fast mode (DMA) functions
*************************************************************/

/* get dma channel for logical endpoint. Only one channel is needed becuase host knows each transfer direction */
void USB_HCD_Get_DMA_Channel(void)
{
	g_UsbHcdInfo.dma_port = DMA_GetChannel(DMA_USB1TX);
}

/* stop DMA channel*/
void USB_HCD_Stop_DMA_Channel(void)
{
	kal_uint32 savedMask;
	kal_uint32 fm_dma_index;

	/* Stop generic DMA */
	if(g_UsbHcdInfo.dma_port != 0)
	{
		if (DMA_CheckRunStat(g_UsbHcdInfo.dma_port))
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -