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

📄 usbd.c

📁 W90P910的BOOTLOADER,难找呀,我想应该是第一份吧.
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
 *
 * Copyright (c) 2008 Nuvoton Electronics Corp.
 * All rights reserved.
 *
 * File name: usbd.c
 *
 * 
 ******************************************************************************/

#include <string.h>
#include "platform.h"
#include "usbd.h"
#include "uprintf.h"

#if 1
#define MSG_DEBUG(...)
#define MSG_WARNING(...)
#define MSG_ERROR(...)
#else
#define MSG_DEBUG			printf
#define MSG_WARNING		printf
#define MSG_ERROR			printf		
#endif

typedef void (*fptr)();  // function pointer
//static fptr IRQ_HandlerTable[31];
extern fptr IRQ_HandlerTable[31];

#define USE_TOKEN	0

/* The interface number of mass storage interface */
#define MASS_INF_NUM		1

/* The endpoint number of mass storage interface's endpoint */ 
#define EP_NUM_ISO			1
#define EP_NUM_BKO			2
#define EP_NUM_INT			3

/* length of descriptors */
#define DEVICE_DSCPT_LEN	0x12
#define CONFIG_DSCPT_LEN	0x20
#define STR0_DSCPT_LEN		0x04
#define STR1_DSCPT_LEN		0x16
#define STR2_DSCPT_LEN		0x34

#define QUALIFIER_DSCPT_LEN		0x0a
#define OSCONFIG_DSCPT_LEN		0x20

/* Vitual_Com command base address */
#define Vitual_Com_Addr_Out 0x80400000
#define Vitual_Com_Addr_In 0x80200000
UINT8 volatile *Inptr;

UINT8 volatile USBModeFlag=0;    //way
UINT32 volatile Bulk_Out_Transfer_Size=0;
UINT32 volatile Bulk_In_Transfer_Size=1;
UINT32 volatile Out_Count=0;
UINT32 volatile Compare_Length=0;

/* for USB */
USB_CMD_T	_usb_cmd_pkt;
UINT32 volatile _usbd_remlen=0;
BOOL volatile _usbd_remlen_flag=0;
UINT16 *_usbd_ptr;

UINT8 volatile Bulk_First_Flag=0;
UINT8 volatile CLASS_CMD_Flag=0;
UINT8 volatile GET_DEV_Flag=0;
UINT8 volatile GET_CFG_Flag=0;
UINT8 volatile GET_QUL_Flag=0;
UINT8 volatile GET_OSCFG_Flag=0;
UINT8 volatile GET_STR_Flag=0;
UINT8 volatile GET_VEN_Flag=0;
UINT8 volatile GET_VENO_Flag=0;
UINT8 volatile usbdGetConfig=0;
UINT8 volatile usbdGetInterface=0;
UINT8 volatile usbdGetStatus=0;

// for DMA state flag
UINT8 volatile _usbd_DMA_Flag=0;
UINT8 volatile _usbd_Less_MPS=0;
UINT8 volatile _usbd_DMA_Dir;

UINT8 volatile bulkonlycmd=0;
UINT8 volatile ResetFlag=0;
UINT8 volatile _usbd_resume=0;

UINT32 volatile usbdMaxPacketSize;
// _usbd_devstate:	1.default state 2.addressed state 3.configured state
UINT32	_usbd_devstate;
UINT32	_usbd_address;
UINT32	_usbd_speedset;
UINT16	_usbd_confsel;
UINT16	_usbd_altsel;
INT		_usbd_haltep=0;
INT		_usbd_unhaltep;

INT		remotewakeup=0;
INT		enableremotewakeup;
INT		enabletestmode;
INT		disableremotewakeup;
INT		testselector;
UINT32	usbdGetStatusData;


static UINT16 _DeviceDescriptor[10] =
{
 0x0112, 0x0200, 0x0000, 0x4000, 0x0416, 0x5963, 0x0100, 0x0201, 0x0100, 0x0000
};
 
static UINT16 _QualifierDescriptor[6] = 
{
 0x060a, 0x0200, 0x0000, 0x4000, 0x0001, 0x0000
};
 
static UINT16 _ConfigurationBlock[16] =
{
 0x0209, 0x0020, 0x0101, 0xC000, 0x0932, 0x0004, 0x0200, 0x0000, 0x0000, 0x0507,
 0x0281, 0x0200, 0x0701, 0x0205, 0x0002, 0x0102
};
 
static UINT16 _ConfigurationBlockFull[16] =
{
 0x0209, 0x0020, 0x0101, 0xc000, 0x0932, 0x0004, 0x0200, 0x0000, 0x0000, 0x0507,
 0x0281, 0x0040, 0x0701, 0x0205, 0x4002, 0x0100
};
 
static UINT16 _OSConfigurationBlock[16] =
{
 0x0709, 0x0020, 0x0101, 0xc000, 0x0932, 0x0004, 0x0200, 0x0000, 0x0000, 0x0507,
 0x0281, 0x0040, 0x0701, 0x0205, 0x4002, 0x0100
};
 
static UINT16 _StringDescriptor0[2] = 
{
 0x0304, 0x0409
};
 
static UINT16 _StringDescriptor1[11] = 
{
 0x0316, 0x0055, 0x0053, 0x0042, 0x0020, 0x0044, 0x0065, 0x0076, 0x69, 0x0063, 0x0065
};
 
static UINT16 _StringDescriptor2[26] = 
{
 0x0334, 0x004E, 0x0075, 0x0076, 0x006F, 0x0074, 0x006F, 0x006E, 0x0020, 0x0041,
 0x0052, 0x004D, 0x0020, 0x0039, 0x0032, 0x0036, 0x002D, 0x0042, 0x0061, 0x0073,
 0x0065, 0x0064, 0x0020, 0x004D, 0x0043, 0x0055
};


void usbdClearAllFlags()
{
	GET_VEN_Flag=0;
	GET_VENO_Flag=0;
	GET_DEV_Flag=0;
	GET_CFG_Flag=0;
	GET_QUL_Flag=0;
	GET_OSCFG_Flag=0;
	GET_STR_Flag=0;
	usbdGetConfig=0;
	usbdGetInterface=0;
	usbdGetStatus=0;
}
void usbd_update_device()
{
	//update this device for set requests
	switch(_usb_cmd_pkt.bRequest)
	{
		case USBR_SET_ADDRESS:
			outpw(REG_USBD_ADDR, _usbd_address);
			break;

		case USBR_SET_CONFIGURATION:

			outpw(REG_USBD_EPA_RSP_SC, EP_TOGGLE);
			outpw(REG_USBD_EPB_RSP_SC, EP_TOGGLE);
			break;

		case USBR_SET_INTERFACE:
			break;

		case USBR_SET_FEATURE:
			if(_usbd_haltep == 0)
				outpw(REG_USBD_CEP_CTRL_STAT, CEP_SEND_STALL);
			else if(_usbd_haltep == 1)
				outpw(REG_USBD_EPA_RSP_SC, EP_HALT);
			else if(_usbd_haltep == 2)
				outpw(REG_USBD_EPB_RSP_SC, EP_HALT);
			else if(enableremotewakeup == 1)
			{
				enableremotewakeup = 0;
				remotewakeup = 1;
			}
			else if(enabletestmode == 1)
			{
				enabletestmode = 0;
				if(testselector == TEST_J)
					outpw(REG_USBD_TEST, TEST_J);
				else if(testselector==TEST_K)
					outpw(REG_USBD_TEST, TEST_K);
				else if(testselector==TEST_SE0_NAK)
					outpw(REG_USBD_TEST, TEST_SE0_NAK);
				else if(testselector==TEST_PACKET)
					outpw(REG_USBD_TEST, TEST_PACKET);
				else if(testselector==TEST_FORCE_ENABLE)
					outpw(REG_USBD_TEST, TEST_FORCE_ENABLE);
			}
			break;

		case USBR_CLEAR_FEATURE:
			if(_usbd_unhaltep == 1 && _usbd_haltep == 1)
			{
				outpw(REG_USBD_EPA_RSP_SC, 0x0);
				outpw(REG_USBD_EPA_RSP_SC, EP_TOGGLE);
				_usbd_haltep = 4; // just for changing the haltep value
			}
			if(_usbd_unhaltep == 2 && _usbd_haltep == 2)
			{
				outpw(REG_USBD_EPB_RSP_SC, 0x0);
				outpw(REG_USBD_EPB_RSP_SC, EP_TOGGLE);
				_usbd_haltep = 4; // just for changing the haltep value
			}
			else if(disableremotewakeup == 1)
			{
				disableremotewakeup=0;
				remotewakeup=0;
			}
			break;
		
		default:
			break;
	}
}

void usbd_send_descriptor()
{
	UINT32 temp_cnt;
	int volatile i;
	UINT16 *ptr;

	if ((GET_DEV_Flag == 1) || (GET_QUL_Flag == 1) || (GET_CFG_Flag == 1) || 
		(GET_OSCFG_Flag == 1) || (GET_STR_Flag == 1) || (CLASS_CMD_Flag == 1) ||
		(usbdGetConfig == 1) || (usbdGetInterface == 1) || (usbdGetStatus == 1))
	{
		if (_usbd_remlen_flag == 0)
		{
			if (GET_DEV_Flag == 1)
				ptr = _DeviceDescriptor;
			else if (GET_QUL_Flag == 1)
				ptr = _QualifierDescriptor;
			else if (GET_CFG_Flag == 1)
			{
				if (_usbd_speedset == 2)
					ptr = _ConfigurationBlock;
				else if (_usbd_speedset == 1)
					ptr = _ConfigurationBlockFull;
			}
			else if (GET_OSCFG_Flag == 1)
				ptr = _OSConfigurationBlock;
			else if (GET_STR_Flag == 1)
			{
				if ((_usb_cmd_pkt.wValue & 0xff) == 0)
					ptr = _StringDescriptor0;
				if ((_usb_cmd_pkt.wValue & 0xff) == 1)
					ptr = _StringDescriptor1;
				if ((_usb_cmd_pkt.wValue & 0xff) == 2)
					ptr = _StringDescriptor2;
			}
			else if (CLASS_CMD_Flag == 1)
			{
				outpb(REG_USBD_CEP_DATA_BUF, 0x00);
				outpw(REG_USBD_IN_TRNSFR_CNT, 1);
				return;
			}
			else if (usbdGetConfig == 1)
			{
				outpb(REG_USBD_CEP_DATA_BUF, _usbd_confsel);
				outpw(REG_USBD_IN_TRNSFR_CNT, 1);
				return;
			}
			else if (usbdGetInterface == 1)
			{
				outpb(REG_USBD_CEP_DATA_BUF, _usbd_altsel);
				outpw(REG_USBD_IN_TRNSFR_CNT, 1);
				return;
			}
			else if (usbdGetStatus == 1)
			{
				outpw(REG_USBD_CEP_DATA_BUF, usbdGetStatusData);
				outpw(REG_USBD_IN_TRNSFR_CNT, 2);
				return;
			}
		}
		else
			ptr = _usbd_ptr;

		if (_usb_cmd_pkt.wLength > 0x40)
		{
			_usbd_remlen_flag = 1;
			_usbd_remlen = _usb_cmd_pkt.wLength - 0x40;
			_usb_cmd_pkt.wLength = 0x40;
		}
		else if (_usbd_remlen != 0)
		{
			_usbd_remlen_flag = 0;
			_usb_cmd_pkt.wLength = _usbd_remlen;
			_usbd_remlen = 0;
		}
		else
		{
			_usbd_remlen_flag = 0;
			_usbd_remlen = 0;
		}
	
		temp_cnt = _usb_cmd_pkt.wLength / 2;

		for (i=0; i<temp_cnt; i++)
			outpw(REG_USBD_CEP_DATA_BUF, *ptr++);

		if ((_usb_cmd_pkt.wLength % 2) != 0)
			outpb(REG_USBD_CEP_DATA_BUF, *ptr & 0xff);

		if (_usbd_remlen_flag)
			_usbd_ptr = ptr;

		outpw(REG_USBD_IN_TRNSFR_CNT, _usb_cmd_pkt.wLength);
	}
}

void usbd_control_packet()
{
	UINT32	temp;
	BOOL	ReqErr;
	
	temp = inpw(REG_USBD_SETUP1_0);
	_usb_cmd_pkt.bmRequestType = (UINT8)temp & 0xff;
	_usb_cmd_pkt.bRequest = (UINT8)(temp >> 8) & 0xff;
	_usb_cmd_pkt.wValue = (UINT16)inpw(REG_USBD_SETUP3_2);
	_usb_cmd_pkt.wIndex = (UINT16)inpw(REG_USBD_SETUP5_4);
	_usb_cmd_pkt.wLength = (UINT16)inpw(REG_USBD_SETUP7_6);

	// vendor command
	if (_usb_cmd_pkt.bmRequestType == 0x40)
	{
//		uprintf("1");
		// clear flags
		usbdClearAllFlags();
		GET_VENO_Flag=1;

		Bulk_Out_Transfer_Size = 0;
		if (_usb_cmd_pkt.bRequest == 0xa0)
		{
			if (_usb_cmd_pkt.wValue == 0x12)
			{		
//				uprintf("--");		
				Bulk_Out_Transfer_Size = _usb_cmd_pkt.wIndex;
				outpw(REG_USBD_CEP_CTRL_STAT, CEP_NAK_CLEAR);	// clear nak so that sts stage is complete//lsshi
				Bulk_First_Flag = 1;
			}
			else if (_usb_cmd_pkt.wValue == 0x13)
			{
//				uprintf("++");
				// reset DMA
				outpw(REG_USBD_DMA_CTRL_STS, 0x80);
				outpw(REG_USBD_DMA_CTRL_STS, 0x00);
				outpw(REG_USBD_EPA_RSP_SC, inpw(REG_USBD_EPA_RSP_SC)|0x01);		// flush fifo
				outpw(REG_USBD_EPB_RSP_SC, inpw(REG_USBD_EPB_RSP_SC)|0x01);		// flush fifo

				outpw(REG_USBD_EPA_RSP_SC, inpw(REG_USBD_EPA_RSP_SC)|0x00000008);	// clear ep toggle
			    outpw(REG_USBD_CEP_CTRL_STAT, CEP_NAK_CLEAR);	// clear nak so that sts stage is complete
				Bulk_First_Flag = 0;
			}
		} else
//				uprintf("==>%x<==", _usb_cmd_pkt.bRequest);

		outpw(REG_USBD_CEP_IRQ_STAT, 0x400);
		return;
	}
	if (_usb_cmd_pkt.bmRequestType == 0xc0)
	{
//		uprintf("2");
	
		// clear flags
		usbdClearAllFlags();
		GET_VEN_Flag=1;
		outpw(REG_USBD_CEP_IRQ_STAT, 0x408);
		outpw(REG_USBD_CEP_IRQ_ENB, 0x408);		//suppkt int ,status and in token
		return;
	}

	// standard request
	switch (_usb_cmd_pkt.bRequest)
	{
//		uprintf("3");

		case USBR_GET_DESCRIPTOR:
        //uprintf("\nUSBR_GET_DESCRIPTOR\n\n");
			ReqErr = ((_usb_cmd_pkt.bmRequestType == 0x80) && ((_usb_cmd_pkt.wValue & 0xf000) == 0) 
			&& ((_usb_cmd_pkt.wValue & 0x80) == 0)) ? 0 : 1;

			if(ReqErr==1)
			{ 
				MSG_DEBUG("GET_DESCRIPTOR => 0[%x], 2[%x], 4[%x], 6[%x]\n", inpw(REG_USBD_SETUP1_0), 
				inpw(REG_USBD_SETUP3_2), inpw(REG_USBD_SETUP5_4), inpw(REG_USBD_SETUP7_6));
				break;	//break this switch loop
			}

			switch	((_usb_cmd_pkt.wValue & 0xf00) >> 8) 
			{  //high byte contains desc type so need to shift???
				case USB_DT_DEVICE:
					// clear flags
					usbdClearAllFlags();

					GET_DEV_Flag = 1;
					if (_usb_cmd_pkt.wLength > DEVICE_DSCPT_LEN)
						_usb_cmd_pkt.wLength = DEVICE_DSCPT_LEN;
					break;

				case USB_DT_CONFIG:
					// clear flags
					usbdClearAllFlags();

					GET_CFG_Flag = 1;
					if (_usb_cmd_pkt.wLength > CONFIG_DSCPT_LEN)
						_usb_cmd_pkt.wLength = CONFIG_DSCPT_LEN;

					break;

				case USB_DT_QUALIFIER:	// high-speed operation
					// clear flags
					usbdClearAllFlags();

					GET_QUL_Flag = 1;
					if (_usb_cmd_pkt.wLength > QUALIFIER_DSCPT_LEN)
						_usb_cmd_pkt.wLength = QUALIFIER_DSCPT_LEN;

					break;

				case USB_DT_OSCONFIG:	// other speed configuration

					// clear flags
					usbdClearAllFlags();

					GET_OSCFG_Flag = 1;
					if (_usb_cmd_pkt.wLength > OSCONFIG_DSCPT_LEN)
						_usb_cmd_pkt.wLength = OSCONFIG_DSCPT_LEN;

					break;

				case USB_DT_STRING:
					// clear flags
					usbdClearAllFlags();

					GET_STR_Flag = 1;
					if ((_usb_cmd_pkt.wValue & 0xff) == 0)
					{
						if (_usb_cmd_pkt.wLength > STR0_DSCPT_LEN)
							_usb_cmd_pkt.wLength = STR0_DSCPT_LEN;
					}
					else if ((_usb_cmd_pkt.wValue & 0xff) == 1)
					{
						if (_usb_cmd_pkt.wLength > STR1_DSCPT_LEN)
							_usb_cmd_pkt.wLength = STR1_DSCPT_LEN;
					}
					else if ((_usb_cmd_pkt.wValue & 0xff) == 2)
					{
						if (_usb_cmd_pkt.wLength > STR2_DSCPT_LEN)
							_usb_cmd_pkt.wLength = STR2_DSCPT_LEN;
					}

					break;

⌨️ 快捷键说明

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