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

📄 usb.c

📁 mtk 6225平台的usb程序! 对想了解mtk平台usb的朋友会有帮助!
💻 C
📖 第 1 页 / 共 3 页
字号:
						MOD_DRV_HISR,
						USB2UARTPort.ownerid,
						MSG_ID_UART_PLUGIN_IND,
						ilm_uart_plug_in);
				msg_send_ext_queue(ilm);
				g_UsbACM.send_UARTilm = KAL_TRUE;
	
				if (g_UsbACM.config_send_Txilm == KAL_TRUE )
				{
					g_UsbACM.send_Txilm = KAL_TRUE;
					/* if someone PutBytes once, then issue ready-to-write message */
					if(USB2UARTPort.tx_cb!=NULL)
						USB2UARTPort.tx_cb(uart_port_usb);
				}
				else
				{
					g_UsbACM.send_Txilm = KAL_FALSE;
				}
			}
		}	
	}	
	return bError;
}


/* parse command Get Configuration */
static kal_bool USB_Cmd_GetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	
#ifdef __OTG_ENABLE__
	/* Prepare to return configuration value */
	USB_Generate_EP0Data(pep0state, pcmd, &gUsbDevice.config_num, 1);	
#else
//	Usb_Cfg_Dscr *pcfg;

	if( (gUsbDevice.nDevState == DEVSTATE_ADDRESS) && (!pcmd->wValue))
	{
		/* Prepare to return zero */
		USB_Generate_EP0Data(pep0state, pcmd, &pcmd->wValue, 1);
	}
	else if( gUsbDevice.nDevState == DEVSTATE_CONFIG) 
	{
		/* Prepare to return configuration value */
		//pcfg = (Usb_Cfg_Dscr *)gUsbDevice.pCurCfg;
		//USB_Generate_EP0Data(pep0state, pcmd, &pcfg->bConfigurationValue, 1);
		USB_Generate_EP0Data(pep0state, pcmd, &gUsbDevice.config_num, 1);
	}
	else
	{
		bError = KAL_TRUE;
	}
#endif
	return bError;
}

/* parse command Set Interface */
static kal_bool USB_Cmd_SetInterface(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	
	gUsbDevice.interface_num = pcmd->wValue & 0x00FF;
	
	return bError;
}

/* parse command Get Interface */
static kal_bool USB_Cmd_GetInterface(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	
	USB_Generate_EP0Data(pep0state, pcmd, &gUsbDevice.interface_num, 1);
	
	return bError;
}


/* parse command Set/Clear Feature */
/* bset  true means command SET_FETURE, false means command CLEAR_FEATURE */
static kal_bool USB_Cmd_SetFeature(Usb_Command *pcmd, kal_bool bset)
{
	kal_bool bError = KAL_FALSE;
	
	switch (pcmd->bmRequestType) 
	{
	/* device */
	case USB_CMD_STDDEVOUT:
		switch (pcmd->wValue) 
		{
		case USB_FTR_DEVREMWAKE:
			gUsbDevice.remoteWk = bset;
			break;
#ifdef __OTG_ENABLE__
	case USB_FTR_B_HNP_ENB:	
			OTG_B_EnDis_HNP(KAL_TRUE);
			break;
	case USB_FTR_A_HNP_SUPPORT:	
	case USB_FTR_A_ALT_HNP_SUPPORT:	
			break;
#endif
		default:
			bError = KAL_TRUE;
			break;
		}
		break;
	/* endpoint */	
	case USB_CMD_STDEPOUT:
		switch (pcmd->wValue) 
		{
		case USB_FTR_EPHALT:
			if (pcmd->wIndex == 0)
			{
				/* endpoint 0 */
                     	;
                     }
			else
                     {
                     	/* command EP direction zero indicate OUT EP */
				if(pcmd->wIndex & 0x80)
				{
					/* In EP*/
					if((pcmd->wIndex& 0x0f) > MAX_INTR_EP_NUM)
					{
						#ifdef  __PRODUCTION_RELEASE__	
							bError = KAL_TRUE;
						#else
							EXT_ASSERT(0, (pcmd->wIndex& 0x0f), gUsbDevice.resource_ep_bulkin_number, 0)	
						#endif
					}
					else
					{
						USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_IN_EP_TYPE, bset, USB_CTRL_STALL_ENTRY_1);
					}
				}
				else
				{
					/* Out EP*/
					if((pcmd->wIndex& 0x0f) > MAX_INTR_EP_NUM)
					{
						#ifdef  __PRODUCTION_RELEASE__	
							bError = KAL_TRUE;
						#else
							EXT_ASSERT(0, (pcmd->wIndex& 0x0f), gUsbDevice.resource_ep_bulkout_number, 0)	
						#endif
					}
					else
					{
						USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_OUT_EP_TYPE, bset, USB_CTRL_STALL_ENTRY_1);
					}
				}
			}
			break;
		default:
			bError = KAL_TRUE;
			break;
		}
		break;
	case USB_CMD_STDIFOUT:
	default:
		bError = KAL_TRUE;
		break;
	}

	return bError;
}

/* parse command Get Status */
static kal_bool USB_Cmd_GetStatus(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	kal_uint16 status = 0;
	switch (pcmd->bmRequestType) 
	{
	case USB_CMD_STDDEVIN:
		status = ( (kal_uint16)(gUsbDevice.remoteWk << 1) | (kal_uint16)(gUsbDevice.self_powered) );
		USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
		break;
	case USB_CMD_STDIFIN:
		USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
		break; 
	case USB_CMD_STDEPIN:
		if(pcmd->wIndex & 0x80)
		{
			/* In EP*/
			status = (kal_uint16)USB_Get_EP_Stall_Status((pcmd->wIndex & 0x000f), USB_IN_EP_TYPE);
		}
		else
		{
			/* Out EP*/
			status = (kal_uint16)USB_Get_EP_Stall_Status((pcmd->wIndex & 0x000f), USB_OUT_EP_TYPE);
		}
		USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
		break;
	default:
		bError = KAL_TRUE;
		break;
	}

	return bError;
}

/* parse usb standard command */
static void USB_Stdcmd(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool   bError = KAL_FALSE;

	switch (pcmd->bRequest) 
	{
	case USB_SET_ADDRESS:
		bError = USB_Cmd_SetAddress(pep0state, pcmd);
		break;
	case USB_GET_DESCRIPTOR:
		bError = USB_Cmd_GetDescriptor(pep0state, pcmd);
		break;
	case USB_SET_CONFIGURATION:
		bError = USB_Cmd_SetConfiguration(pep0state, pcmd);
		break;
	case USB_SET_INTERFACE:
		bError = USB_Cmd_SetInterface(pep0state, pcmd);
		break;
	case USB_GET_CONFIGURATION:
		bError = USB_Cmd_GetConfiguration(pep0state, pcmd);
		break;
	case USB_GET_INTERFACE:
		bError = USB_Cmd_GetInterface(pep0state, pcmd);
		break;
	case USB_SET_FEATURE:
		bError = USB_Cmd_SetFeature(pcmd, KAL_TRUE);
		break;
	case USB_CLEAR_FEATURE:
		bError = USB_Cmd_SetFeature(pcmd, KAL_FALSE);
		break;
	case USB_GET_STATUS:
		bError = USB_Cmd_GetStatus(pep0state, pcmd);
		break;
	/* Stall the command if an unrecognized request is received */	
	case USB_SYNCH_FRAME:   /*Only support for Isoc traffic*/
	case USB_SET_DESCRIPTOR:
	default:
		bError = KAL_TRUE;
		ASSERT(0);
		break;
	}


	if (gUsbDevice.ep0_state == USB_EP0_IDLE)	/* no data to transmit */
	{
		gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
		USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_TRUE);
		if((gUsbDevice.ep0_class_cmd_handler.b_enable == KAL_TRUE) &&
			(gUsbDevice.ep0_class_cmd_handler.cmd == pcmd->bRequest) ) 
		{
			gUsbDevice.ep0_class_cmd_handler.ep0_cmd_hdlr(pcmd);/* Besides standard cmd, still need to do extra this*/
		}	
	}
	else
		USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_FALSE);
}


/* parse EP0 requested command */
static void USB_Endpoint0_Idle (void)
{
	/* read ep0 data*/
	USB_EPFIFORead(0, 8, &gUsbDevice.cmd);
	
	/* Check request type */
	switch (gUsbDevice.cmd.bmRequestType & USB_CMD_TYPEMASK) 
	{
	case USB_CMD_STDREQ:
		/* standard request */
		USB_Stdcmd(&gUsbDevice.ep0info, &gUsbDevice.cmd);
		break;
	case USB_CMD_CLASSREQ:
		/* class specific request */
		if((gUsbDevice.cmd.bmRequestType == USB_CMD_CLASSIFIN) || (gUsbDevice.cmd.bmRequestType == USB_CMD_CLASSIFOUT))
		{
			if(gUsbDevice.if_info[(gUsbDevice.cmd.wIndex & 0xff)].if_class_specific_hdlr != NULL)
			{
				gUsbDevice.if_info[(gUsbDevice.cmd.wIndex & 0xff)].if_class_specific_hdlr(&gUsbDevice.ep0info, &gUsbDevice.cmd);
			}
			else
			{
			#ifndef  __PRODUCTION_RELEASE__	
				/* not support now*/
				EXT_ASSERT(0, gUsbDevice.cmd.wIndex, 0, 0);
			#endif
				/* error occur, stall endpoint*/
				USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
			}
		}
		else
		{
		#ifndef  __PRODUCTION_RELEASE__	
			/* not support now*/
			EXT_ASSERT(0, gUsbDevice.cmd.bmRequestType, 0, 0);
		#endif
			/* error occur, stall endpoint*/
			USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
		}
		break;
	case USB_CMD_VENDREQ:
	default:
		/* Stall the command if a reserved request is received */
		USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
		break;
	}
}


/* EP0 RX handler, called when EP0 interrupt happened and in RX state */
static void USB_Endpoint0_Rx(void)
{
	if (gUsbDevice.ep0_rx_handler != NULL)
	{
		/* called rx handler to get data*/
		gUsbDevice.ep0_rx_handler(&gUsbDevice.ep0info);
	}
	else
	{
		/* this should not happened, user should register rx handler when set EP0 into RX state */
		/* error occur, stall endpoint*/
		ASSERT(0);
//		USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
	}
}


/* EP0 TX handler, called when EP0 interrupt happened and in TX state, 
     or EP0 just translate from IDLE to TX state */
static void USB_Endpoint0_Tx(void)
{
	kal_int32 nBytes;

	/* Determine number of bytes to send */
	if (gUsbDevice.ep0info.nBytesLeft <= USB_EP0_MAXP) 
	{
		nBytes = gUsbDevice.ep0info.nBytesLeft;
		gUsbDevice.ep0info.nBytesLeft = 0;
	}
	else 
	{
		nBytes = USB_EP0_MAXP;
		gUsbDevice.ep0info.nBytesLeft -= USB_EP0_MAXP;
	}

	/* send out data */
	USB_EPFIFOWrite (0, nBytes, gUsbDevice.ep0info.pData);

	/* update data pointer and  prepare for next transaction */
	gUsbDevice.ep0info.pData = (kal_uint8 *)gUsbDevice.ep0info.pData + nBytes;
	
	if (nBytes < USB_EP0_MAXP) 
	{
		gUsbDevice.ep0_state = USB_EP0_IDLE;
		/* last data, set end as true*/
		USB_Update_EP0_State(USB_EP0_DRV_STATE_WRITE_RDY, KAL_FALSE, KAL_TRUE);
	}
	else
	{
		USB_Update_EP0_State(USB_EP0_DRV_STATE_WRITE_RDY, KAL_FALSE, KAL_FALSE);
	}
}


/* EP0 interrupt handler called by USB_HISR */
static void USB_Endpoint0_Hdlr(void)
{
	kal_bool b_transaction_end;
	kal_bool b_sent_stall;
	kal_uint32 nCount;

	USB_Get_EP0_Status(&b_transaction_end, &b_sent_stall);

	/* Check for SentStall */
	/* SentStall && SetupEnd are impossible to occur together*/
	if (b_sent_stall == KAL_TRUE) 
	{
		USB_Update_EP0_State(USB_EP0_DRV_STATE_CLEAR_SENT_STALL, KAL_FALSE, KAL_FALSE);
		gUsbDevice.ep0_state = USB_EP0_IDLE;
	}

	/* Check for SetupEnd */
	if (b_transaction_end == KAL_TRUE) 
	{
		USB_Update_EP0_State(USB_EP0_DRV_STATE_TRANSACTION_END, KAL_FALSE, KAL_FALSE);
		gUsbDevice.ep0_state = USB_EP0_IDLE;
	}

	/* Call relevant routines for endpoint 0 state */
	if (gUsbDevice.ep0_state == USB_EP0_IDLE)
	{
		/* receive command request */
		nCount = USB_EP0_Pkt_Len();
		if (nCount > 0) 
		{
			/* idle state handler */
			USB_Endpoint0_Idle();
		}
	}
	else if (gUsbDevice.ep0_state == USB_EP0_RX)
	{
		/* Rx state handler */
		USB_Endpoint0_Rx();
	}
	else if (gUsbDevice.ep0_state == USB_EP0_RX_STATUS)
	{
		/* Data stage is RX, status stage is TX*/
		if(gUsbDevice.nDevState == DEVSTATE_SET_ADDRESS)
		{
			USB_SetAddress(gUsbDevice.ep0info.byFAddr, USB_SET_ADDR_STATUS);
			gUsbDevice.nDevState = DEVSTATE_ADDRESS;
		}
		gUsbDevice.ep0_state = USB_EP0_IDLE;
		
		/* In case next setup followed the previous status very fast and interrupt only happens once*/
		/* receive command request */
		nCount = USB_EP0_Pkt_Len();
		if (nCount > 0) 
		{
			/* idle state handler */
			USB_Endpoint0_Idle();
		}
	}

	/* must use if, not else if, EP0 may enter TX state in previous IDLE state handler */
	if (gUsbDevice.ep0_state == USB_EP0_TX)
	{
		/* Tx state handler */
		USB_Endpoint0_Tx();
	}

	return;
}




⌨️ 快捷键说明

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