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

📄 usbdl_usb.c

📁 MTK 平台启动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			break;
		case USB_CMD_CONFIG:
			byConfig = (kal_uint8)(pcmd->wValue & 0x00FF);
			if (byConfig >= gUsbDevice.devdscr.bNumConfigurations)
			{
				bError = KAL_TRUE;
			}
			else 
			{
				/* Get pointer to request configuration descriptor */
				pcfg = (Usb_Cfg_Dscr*)gUsbDevice.conf;
				
				/* Prepare to return Configuration Descriptors */
				USB_Generate_EP0Data(pep0state, pcmd, pcfg, pcfg->wTotalLength);
			}
			break;    
		case USB_CMD_STRING:
			bystr = (kal_uint8)(pcmd->wValue & 0x00FF);
			if (bystr >= gUsbDevice.resource_string_number)
			{
				bError = KAL_TRUE;
			}
			else
			{
				/* Get pointer to requested string descriptor */
				USB_Generate_EP0Data(pep0state, pcmd, (void *)gUsbDevice.resource_string[bystr], 
							(*(kal_uint8 *)gUsbDevice.resource_string[bystr]));
			}
			break;
		default: 
			bError = KAL_TRUE;
			break;
		}
	}

	return bError;
}


/* Parse command Set Configuration */
static kal_bool USB_Cmd_SetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	kal_uint8 byConfig;
	
	byConfig = (kal_uint8)(pcmd->wValue & 0x00FF);

	if (gUsbDevice.nDevState == DEVSTATE_DEFAULT)
	{
		bError = KAL_TRUE;
	}	
	/* Assumes configurations are numbered from 1 to NumConfigurations */
	else 
	{
		if (byConfig > gUsbDevice.devdscr.bNumConfigurations)
		{
			bError = KAL_TRUE;
		}
		else if (byConfig == 0)
		{
			gUsbDevice.nDevState = DEVSTATE_ADDRESS;
			gUsbDevice.config_num = 0;
		}
		else 
		{
			gUsbDevice.nDevState = DEVSTATE_CONFIG;		
//			gUsbDevice.is_configured_now = KAL_TRUE;
			gUsbDevice.config_num = byConfig;	
		}
	}
	return bError;
}


/* parse command Get Configuration */
static kal_bool USB_Cmd_GetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool bError = KAL_FALSE;
	

	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;
	}
	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;
		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)
					{
							bError = KAL_TRUE;
					}
					else
					{
						USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_TX_EP_TYPE, bset, USB_CTRL_STALL_ENTRY_1);
					}
				}
				else
				{
					/* Out EP*/
					if((pcmd->wIndex& 0x0f) > MAX_INTR_EP_NUM)
					{
							bError = KAL_TRUE;
					}
					else
					{
						USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_RX_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;
	static kal_uint16 status = 0;
	switch (pcmd->bmRequestType) 
	{
	case USB_CMD_STDDEVIN:
		status = (kal_uint16)((gUsbDevice.remoteWk<<1)|(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_TX_EP_TYPE);
		}
		else
		{
			/* Out EP*/
			status = (kal_uint16)USB_Get_EP_Stall_Status((pcmd->wIndex & 0x000f), USB_RX_EP_TYPE);
		}
		USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
		break;
	default:
		bError = KAL_TRUE;
		break;
	}

	return bError;
}


static void USB_Stdcmd(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
	kal_bool   bError = KAL_FALSE;


	switch (pcmd->bRequest) 
	{
	case USB_SET_ADDRESS:
		USB_Dbg_Trace(USB_EP0_SET_ADDRESS, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_SetAddress(pep0state, pcmd);
		break;
	case USB_GET_DESCRIPTOR:
		USB_Dbg_Trace(USB_EP0_GET_DESCRIPTOR, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_GetDescriptor(pep0state, pcmd);
		break;
	case USB_SET_CONFIGURATION:
		USB_Dbg_Trace(USB_EP0_SET_CONFIGURATION, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_SetConfiguration(pep0state, pcmd);
		break;
	case USB_SET_INTERFACE:
		USB_Dbg_Trace(USB_EP0_SET_INTERFACE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_SetInterface(pep0state, pcmd);
		break;
	case USB_GET_CONFIGURATION:
		USB_Dbg_Trace(USB_EP0_GET_CONFIGURATION, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_GetConfiguration(pep0state, pcmd);
		break;
	case USB_GET_INTERFACE:
		USB_Dbg_Trace(USB_EP0_GET_INTERFACE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_GetInterface(pep0state, pcmd);
		break;
	case USB_SET_FEATURE:
		USB_Dbg_Trace(USB_EP0_SET_FEATURE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_SetFeature(pcmd, KAL_TRUE);
		break;
	case USB_CLEAR_FEATURE:
		USB_Dbg_Trace(USB_EP0_CLEAR_FEATURE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		bError = USB_Cmd_SetFeature(pcmd, KAL_FALSE);
		break;
	case USB_GET_STATUS:
		USB_Dbg_Trace(USB_EP0_GET_STATUS, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		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:
		USB_Dbg_Trace(USB_EP0_CMD_ERROR, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
		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);
		}	
*/
	}
	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
			{
				/* error occur, stall endpoint*/
				USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
			}
		}
		else
		{
			/* 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();
	}
}

#endif   /* __USB_DOWNLOAD__ */

⌨️ 快捷键说明

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