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

📄 usb_hcd.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
			else
			{
				g_UsbHcdInfo.tx_curent_index = -1;
				/* next even odd */
				g_UsbHcdInfo.tx_even_odd = even_odd^1;
			}
			/* toggel data 01, return to original data 01*/
			g_UsbHcdInfo.ep_info[current_ep_index].data01^=1;

			/* fast mode timeout error */
			if(FastErrorStatus&(VUSB_FM_ERR_NAK_ERR|VUSB_FM_ERR_SUC_ERR))
			{
				USB_HCD_Stop_DMA_Channel();
				g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
				/* the actaul size that fast mode complete */
				g_UsbHcdInfo.fast_mode_data_size = 
					(DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8)) << 6;

				/* decide the next even/odd BDT*/
				if(direction==USB_BDT_RX)
				{
					fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_RX_ODD_SHIFT))>>VUSB_FM_CTL_EP_RX_ODD_SHIFT;
					g_UsbHcdInfo.rx_even_odd = fm_even_odd;
				}
				else
				{
					fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_TX_ODD_SHIFT))>>VUSB_FM_CTL_EP_TX_ODD_SHIFT;
					g_UsbHcdInfo.tx_even_odd = fm_even_odd;
				}
				/* this data01 is nak by device, so next data01 is this one*/
				g_UsbHcdInfo.ep_info[current_ep_index].data01 = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_TOG_BIT_SHIFT))>>VUSB_FM_CTL_EP_TOG_BIT_SHIFT;
					
				/* Since it is timeout, there should not be short error */
				if(FastErrorStatus&VUSB_FM_ERR_SHORT_ERR)
				{
					EXT_ASSERT(0, FastErrorStatus, g_UsbHcdInfo.fast_mode_data_size, 0);
				}	

				/* callback to application */
				if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
					g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_TIMEOUT, g_UsbHcdInfo.fast_mode_data_size);
			}	
			else if(status==VUSB_BDT_STALL_PID)
			{
				/* If in fast mode, stop DMA */
				if(g_UsbHcdInfo.dma_running==KAL_TRUE)
				{
					USB_HCD_Stop_DMA_Channel();
					g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
					
					/* the actaul size that fast mode complete */
					g_UsbHcdInfo.fast_mode_data_size = 
						(DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8)) << 6;

					b_fast_mode = KAL_TRUE;
						
					/* decide the next even/odd BDT*/
					if(direction==USB_BDT_RX)
					{
						fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_RX_ODD_SHIFT))>>VUSB_FM_CTL_EP_RX_ODD_SHIFT;
						g_UsbHcdInfo.rx_even_odd = fm_even_odd;
					}
					else
					{
						fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_TX_ODD_SHIFT))>>VUSB_FM_CTL_EP_TX_ODD_SHIFT;
						g_UsbHcdInfo.tx_even_odd = fm_even_odd;
					}
				}
				
				/* callback to USB stack, stall error*/
				if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
				{
					if(b_fast_mode==KAL_TRUE)
						g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_STALL, g_UsbHcdInfo.fast_mode_data_size);	
					else
						g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_STALL, g_UsbHcdInfo.ep_info[current_ep_index].sofar);
				}	
			}
			/* if ep0 dose not response*/
			else if(status==VUSB_BDT_BUS_TIMEOUT_PID)
			{
				/* When plug out cable and dma done but not doing DMA HISR , it may happen for fast mode*/
				if(g_UsbHcdInfo.dma_running==KAL_TRUE)
				{
					/*  g_UsbHcdInfo.processing_ep_id may be set to -1 in TOKEN_DONE intr handler */
					if(g_UsbHcdInfo.dma_index==-1)
						EXT_ASSERT(0, g_UsbHcdInfo.dma_index, g_UsbHcdInfo.processing_ep_id, 0);
					if(g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index]!=NULL)
						g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index](USB_HCD_NO_RESPONSE, 0);
					USB_HCD_Stop_DMA_Channel();
					g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
			 		g_UsbHcdInfo.processing_ep_id = -1;
				}
				else
				{
					g_UsbHcdInfo.ep_info[current_ep_index].no_response_count++;
					if(g_UsbHcdInfo.ep_info[current_ep_index].no_response_count>=3)
					{
						if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
							g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_NO_RESPONSE, g_UsbHcdInfo.ep_info[current_ep_index].sofar);
				
						/* do not queue this packet*/	
					}
					else
					{
						/* queue to the end */
						USB_HCD_Queue_Pkt(current_ep_index);
					}
				}	
			}
			else	 /* may be NAK */
			{
				if(g_UsbHcdInfo.dma_running==KAL_TRUE)
				{
					/*  g_UsbHcdInfo.processing_ep_id may be set to -1 in TOKEN_DONE intr handler */
					if(g_UsbHcdInfo.dma_index==-1)
						EXT_ASSERT(0, g_UsbHcdInfo.dma_index, g_UsbHcdInfo.processing_ep_id, 0);
					if(g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index]!=NULL)
						g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index](USB_HCD_NO_RESPONSE, 0);
					USB_HCD_Stop_DMA_Channel();
					g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
			 		g_UsbHcdInfo.processing_ep_id = -1;
				}	
				else
				{
					/* queue to the end */
					USB_HCD_Queue_Pkt(current_ep_index);
				}	
			}	
			
			//b_schedule = KAL_TRUE;
			b_dis_schedule = KAL_TRUE;
		}
		else	 /*VUSB_BDT_BUS_TIMEOUT_PID || VUSB_BDT_NAK_PID || VUSB_BDT_ERROR_PID */
		{
			/* Token done without error status */
			/* update status and copy to user memory*/
			if(direction==USB_BDT_RX)
			{
				if(g_UsbHcdInfo.rx_curent_index==-1)
					EXT_ASSERT(0, 0, 0, 0);
				current_ep_index = g_UsbHcdInfo.rx_curent_index;
				g_UsbHcdInfo.rx_curent_index = -1;

				if(current_ep_index == g_UsbHcdInfo.dma_index)
				{
					/* fast mode packet */
					if(g_UsbHcdInfo.dma_dir!=USB_IN_EP_TYPE)
						EXT_ASSERT(0, g_UsbHcdInfo.dma_dir, g_UsbHcdInfo.dma_index, 0);

					/* decide the next even/odd BDT*/
					fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_RX_ODD_SHIFT))>>VUSB_FM_CTL_EP_RX_ODD_SHIFT;
					g_UsbHcdInfo.rx_even_odd = fm_even_odd;

					/* calculate the received packet size */
					/* fast mode size = fast count *64*/
					g_UsbHcdInfo.fast_mode_data_size = 
								(DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8)) << 6;
					/* the last received packet size */
					if(FastErrorStatus&VUSB_FM_ERR_SHORT_ERR)
					{
						/* got the short packet length according to current BDT */
						pkt_length = (READ_EP0_BDT_PID(USB_BDT_RX, fm_even_odd^1)&VUSB_BDT_BC_MASK)
									>>VUSB_BDT_BC_SHIFT;
						/* The short one should be subtracted */
						g_UsbHcdInfo.fast_mode_data_size -= 64;
						g_UsbHcdInfo.fast_mode_data_size += pkt_length;

						/* this data01 is sent by device, so next data01 is this one*/
						g_UsbHcdInfo.ep_info[current_ep_index].data01 = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_TOG_BIT_SHIFT))>>VUSB_FM_CTL_EP_TOG_BIT_SHIFT;
					}	

					if(g_UsbHcdInfo.fast_mode_data_size==0)
					{
						/* no need DMA, stop it. Otherwise it will hang */
						USB_HCD_Stop_DMA_Channel();
						g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
					}
											
					if( (DRV_Reg8(USB_FM_PKT_NUML) + (DRV_Reg8(USB_FM_PKT_NUMH)<<8))
						!=(DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8)) )
					{
						/* no need DMA, stop it. Otherwise it will hang */
						USB_HCD_Stop_DMA_Channel();
						g_UsbHcdInfo.b_wait_dma = KAL_FALSE;
							
					}
											
					if(g_UsbHcdInfo.b_wait_dma == KAL_FALSE)
					{
						if(g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index]!=NULL)
							g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index](USB_HCD_OK, g_UsbHcdInfo.fast_mode_data_size );

						//b_schedule = KAL_TRUE;
						b_dis_schedule = KAL_TRUE;
					}
					g_UsbHcdInfo.b_wait_fm_done = KAL_FALSE;
				}
				else
				{
					/* normal mode, copy to user memory */
					pkt_length = (READ_EP0_BDT_PID(USB_BDT_RX, even_odd)&VUSB_BDT_BC_MASK)
								>>VUSB_BDT_BC_SHIFT;
					if(pkt_length>g_UsbHcdInfo.ep_info[current_ep_index].data_length)
					{
						EXT_ASSERT(0, current_ep_index, pkt_length, 
									g_UsbHcdInfo.ep_info[current_ep_index].data_length);
					}
					if((g_UsbHcdInfo.ep_info[current_ep_index].sofar+pkt_length)>g_UsbHcdInfo.ep_info[current_ep_index].data_length)
					{
						EXT_ASSERT(0, current_ep_index, g_UsbHcdInfo.ep_info[current_ep_index].sofar, 
									g_UsbHcdInfo.ep_info[current_ep_index].data_length);
					}

					kal_mem_cpy(&g_UsbHcdInfo.ep_info[current_ep_index].p_data[g_UsbHcdInfo.ep_info[current_ep_index].sofar], 
					(void*)READ_EP0_BDT_ADDR(USB_BDT_RX, even_odd), pkt_length);	

					g_UsbHcdInfo.ep_info[current_ep_index].sofar+=pkt_length;
					
					/* This one is recvd, software will fill next packet*/
					g_UsbHcdInfo.rx_even_odd = even_odd^1;

					if((g_UsbHcdInfo.ep_info[current_ep_index].sofar==g_UsbHcdInfo.ep_info[current_ep_index].data_length)
						|| (pkt_length<g_UsbHcdInfo.ep_info[current_ep_index].max_packet_size))
					{
						/* callback to USB stack*/
						if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
							g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_OK, g_UsbHcdInfo.ep_info[current_ep_index].sofar);
					}
					else
					{
						//queue to scheduler
						USB_HCD_Queue_Pkt(current_ep_index);
					}
					//b_schedule = KAL_TRUE;
					b_dis_schedule = KAL_TRUE;
				}	
			}
			else
			{
				if(g_UsbHcdInfo.tx_curent_index==-1)
					EXT_ASSERT(0, 0, 0, 0);
				current_ep_index = g_UsbHcdInfo.tx_curent_index;
				g_UsbHcdInfo.tx_curent_index = -1;

				if(current_ep_index == g_UsbHcdInfo.dma_index)
				{
					/* fast mode packet */
					if(g_UsbHcdInfo.dma_dir!=USB_OUT_EP_TYPE)
						EXT_ASSERT(0, g_UsbHcdInfo.dma_dir, g_UsbHcdInfo.dma_index, 0);

					if(g_UsbHcdInfo.fast_mode_tx_ep != 0)
					{
						/* This is Fast mode token done intr */
						g_UsbHcdInfo.fast_mode_tx_ep = 0;

						/* calculate the sent packet size */
						/* fast mode size = fast count *64*/
						g_UsbHcdInfo.fast_mode_data_size = 
									(DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8)) << 6;
						/* tx should not send short pkt, the last one should use tx_res method */
						if(FastErrorStatus&VUSB_FM_ERR_SHORT_ERR)
						{
							EXT_ASSERT(0, FastErrorStatus, g_UsbHcdInfo.fast_mode_data_size, current_ep_index);
						}
	
						if(g_UsbHcdInfo.dma_res_tx_ep==0)
						{
							/* No TX data residue */

							/* decide the next even odd */
							fm_even_odd = (DRV_Reg8(USB_FM_CTL)&(1<<VUSB_FM_CTL_EP_TX_ODD_SHIFT))>>VUSB_FM_CTL_EP_TX_ODD_SHIFT;
							g_UsbHcdInfo.tx_even_odd = fm_even_odd;	

							if(g_UsbHcdInfo.b_wait_dma == KAL_FALSE)
							{
								if(g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index]!=NULL)
									g_UsbHcdInfo.ep_hdlr[g_UsbHcdInfo.dma_index](USB_HCD_OK, g_UsbHcdInfo.fast_mode_data_size );
								//b_schedule = KAL_TRUE;
								b_dis_schedule = KAL_TRUE;
							}
							g_UsbHcdInfo.b_wait_fm_done = KAL_FALSE;
						}
					}
					else if(g_UsbHcdInfo.dma_res_tx_ep != 0)
					{
						/* This is the last residue packet token done intr*/
						g_UsbHcdInfo.dma_res_tx_ep = 0;
				
						//read the sent packet length
						pkt_length = (READ_EP0_BDT_PID(USB_BDT_TX, even_odd)&VUSB_BDT_BC_MASK)
									>>VUSB_BDT_BC_SHIFT;
						g_UsbHcdInfo.fast_mode_data_size+=pkt_length;
						if(g_UsbHcdInfo.fast_mode_data_size>g_UsbHcdInfo.ep_info[current_ep_index].data_length)
						{
							EXT_ASSERT(0, current_ep_index, pkt_length, 
										g_UsbHcdInfo.ep_info[current_ep_index].data_length);
						}	

						/* This one is transmitted, software will fill next packet*/
						/* Note that the last res packet is sent in normal mode so use BDT even odd indication*/
						g_UsbHcdInfo.tx_even_odd = even_odd^1;
							
						if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
							g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_OK, g_UsbHcdInfo.fast_mode_data_size);
						
						//b_schedule = KAL_TRUE;
						b_dis_schedule = KAL_TRUE;
					}
				}
				else
				{
					/* Normal mode */
					
					//read the sent packet length
					pkt_length = (READ_EP0_BDT_PID(USB_BDT_TX, even_odd)&VUSB_BDT_BC_MASK)
								>>VUSB_BDT_BC_SHIFT;
					if(pkt_length>g_UsbHcdInfo.ep_info[current_ep_index].data_length)
					{
						EXT_ASSERT(0, current_ep_index, pkt_length, 
									g_UsbHcdInfo.ep_info[current_ep_index].data_length);
					}	
					if((g_UsbHcdInfo.ep_info[current_ep_index].sofar+pkt_length)>g_UsbHcdInfo.ep_info[current_ep_index].data_length)
					{
						EXT_ASSERT(0, current_ep_index, g_UsbHcdInfo.ep_info[current_ep_index].sofar, 
									g_UsbHcdInfo.ep_info[current_ep_index].data_length);
					}

					g_UsbHcdInfo.ep_info[current_ep_index].sofar+=pkt_length;
					
					/* This one is transmitted, software will fill next packet*/
					g_UsbHcdInfo.tx_even_odd = even_odd^1;

					if((g_UsbHcdInfo.ep_info[current_ep_index].sofar==g_UsbHcdInfo.ep_info[current_ep_index].data_length)
						|| (pkt_length<g_UsbHcdInfo.ep_info[current_ep_index].max_packet_size))
					{
						/* callback to USB stack*/
						if(g_UsbHcdInfo.ep_hdlr[current_ep_index]!=NULL)
							g_UsbHcdInfo.ep_hdlr[current_ep_index](USB_HCD_OK, g_UsbHcdInfo.ep_info[current_ep_index].sofar);
					}
					else
					{
						//queue to scheduler
						USB_HCD_Queue_Pkt(current_ep_index);
					}
					
					//b_schedule = KAL_TRUE;
					b_dis_schedule = KAL_TRUE;
				}	
			}
		}	/* End  VUSB_BDT_BUS_TIMEOUT_PID || VUSB_BDT_NAK_PID || VUSB_BDT_ERROR_PID */
	} /* End VUSB_INT_STAT_TOKEN_DONE*/

	if(IntrStatus&VUSB_INT_STAT_SOF)
	{
		 USB_HCD_Update_Interval();
		if((g_UsbHcdInfo.processing_ep_id==-1) 
			&& (g_UsbHcdInfo.b_wait_dma==KAL_FALSE) && (g_UsbHcdInfo.b_wait_fm_done == KAL_FALSE))
		{
			b_schedule = KAL_TRUE;
		}	
	} /* End VUSB_INT_STAT_SOF*/

	if((OTG_Get_State()==OTG_STATE_A_WAIT_BCON) || (OTG_Get_State()==OTG_STATE_B_WAIT_ACON))
	{
		if(IntrStatus&VUSB_INT_STAT_ATTACH)
		{
			if(DRV_Reg8(USB_CTL)&VUSB_CTL_JSTATE)
			{
				DRV_WriteReg8(USB_INT_ENB, DRV_Reg8(USB_INT_ENB)&(~VUSB_INT_ENB_ATTACH));
				USB_HCD_Process_Attach();
			}	
			g_UsbHcdInfo.rx_curent_index = -1;
			g_UsbHcdInfo.tx_curent_index = -1;
			g_UsbHcdInfo.processing_ep_id = -1;
		} /* End VUSB_INT_STAT_ATTACH*/
	}
	
	if(IntrStatus&VUSB_INT_STAT_RESUME)
	{
		USB_HCD_Resume();
	} /* End VUSB_INT_STAT_RESUME*/
	
	if (IntrStatus & VUSB_INT_STAT_SLEEP)
	{
		USB_HCD_Suspend();
	} /* End VUSB_INT_STAT_SLEEP */

	if (IntrStatus & VUSB_INT_STAT_ERROR)
	{
	
	}/* End VUSB_INT_STAT_ERROR */


	if((b_schedule==KAL_TRUE) &&(b_dis_schedule==KAL_FALSE))
		USB_HCD_Sched_Pending_Pkts();

}

#endif	/* __OTG_ENABLE__ */
 

⌨️ 快捷键说明

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