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

📄 usb.c

📁 sl811hs 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
//ep0  setup and control transfer
//ep1  bulk in
//ep2  bulk out

//Write Cycle Time for Auto Inc Mode Writes is 150 ns minimum.
//address will take effect after 85ns when address was written.
//extbank0's width was defined as 32bits

#include "vd.h"
#include "usb.h"

#define USB_ADDR_BASE 0x7fc0000
#define USB_ADDR_ADDR (*(volatile unsigned *)(USB_ADDR_BASE))                  //writing pointer for instruction 
#define USB_ADDR_DATA (*(volatile unsigned *)(USB_ADDR_BASE+0x4))			 //writing pointer for data 
#define max 8192

typedef struct				
{
    B8 bmRequest;					// SETUP Token Protocol
    B8 bRequest;
    B16 wValue;
    B16 wIndex;
    B16 wLength;
} 	SetupPKG, *pSetupPKG;


extern void uartpush(char data[]);
extern B32 ltoa(B32 value,char data[],B32 radix);

void usb_init(void);
void USBReset(void);
B32  USBMemTest(void);
void USBBufRead(B8 addr, B8 *s, B8 c);
B8   USBRead(B8 addr);
void USBBufWrite(B8 addr, B8 *s, B8 c);
void USBWrite(B8 addr, B8 data);
void Delayms(B32 time);
void usb_main(void);
B16  WordSwap(B16 input);
void sl811s_init(void);

void EP0A_IN_Arm(B8	buf_adr, B8 len, B8 seq);
void EP0A_OUT_Arm(B8 len);
void EP1A_IN_Arm(B8 buf_adr, B8 len, B8 seq);
void EP2A_OUT_Arm(B8 len,B8 seq);

void ep0_isr(void);
void ep1_isr(void);
void ep2_isr(void);
void sof_isr(void);

void bufscan(void);



SetupPKG 	dReq;			// Setup token struct
B8	Slave_USBaddr;			// USB device address
B8	Slave_ConfigVal;		// Device configuration value
B8	Slave_Protocol;			// HID device protocol status
B8	Slave_IdleRate;			// HID device idle rate value
B8	Slave_RemoteWU;			// Device remote wakeup stats
B8	Slave_inEPstall;		// EP0 ~ EP7's IN stall status
B8	Slave_outEPstall;		// EP0 ~ EP7's OUT stall status
B8	Slave_IfcAlt[MAXIFCNUM];// 8 interface(Ep0~7) contain alternate setting value


B16	len_req;				// length of data for EP0
B16	sof_cnt;				// 1ms counter
B8  ep1_toggle;				// EP1 DATA toggle state
B8 ep2_toggle;				// EP2 DATA toggle state
B16	in_buffer_idx;			// EP0 IN data buffer tracking

B8 	flags;					// Flag Bitmap
B8	dev_first;				// status for 8-byte EP0 transfer
B8	timeout;				// time out for debounce
B8	enum_done;				// end of enum, (end of report descp)

B8 	Toggle_SW;				// Toggle switch

B8	IN_NULL;				// EP0's IN null packet transmission
B8	IN_EXACT;				// EP0's IN data length requested is extact of EP0_LEN
B8	BUS_POWERED;			// Bus powered device 

B8  UsbBuf_T[max][65];		//buffer for in data.the first byte was for the packet data numbers,0=null, max=64;
B8  UsbBuf_R[max][65];		//buffer for out data.
B8	UsbBuf_C;				//buffer for control transfer,just for out from host

B8  PacketShift_T0;			//0 for head,and 1 for tail 
B8  PacketShift_T1;
B8  PacketShift_R0;
B8  PacketShift_R1;


B8 	EP1_BUF_Full;			//if 0 mean empty,else mean full


//*****************************************************************************************
// USB Basic Function
//*****************************************************************************************
void Delayms(B32 time)
{
	B32 i,j;
	for(j=0;j<time;j++)
		for(i=0;i<10000;i++);
}

void USBWrite(B8 addr, B8 data)
{
	USB_ADDR_ADDR=(B32)addr;
	__asm
	{
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
	}
	USB_ADDR_DATA=(B32)data;
}

void USBBufWrite(B8 addr, B8 *s, B8 c)
{
	if(c==0) return;
	USB_ADDR_ADDR=(B32)addr;
	while (c--) 
	{
		__asm
		{
			
			
			NOP
			NOP
			NOP
		}
		USB_ADDR_DATA=(B32)*s++;
	}
}

B8 USBRead(B8 addr)
{
	USB_ADDR_ADDR=(B32)addr;
	__asm
	{
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
	}
	return ((B8)USB_ADDR_DATA);
}

void USBBufRead(B8 addr, B8 *s, B8 c)
{
	if(c==0) return;
	USB_ADDR_ADDR=(B32)addr;
	while (c--)
	{
		__asm
		{
			
			NOP
			NOP
			NOP
		}
		*s++ = (B8)USB_ADDR_DATA;
	}
}

//*****************************************************************************************
// USB Mem Test
//*****************************************************************************************
B32 USBMemTest()
{
	char data[64];
	B16 errors=0,i;
	uartpush("\tUSB Memory test started!\n\r ");
	for (i = EP0Buf; i < cMemEnd; i++) 	// addr = data
		USBWrite(i,i);
	for (i = EP0Buf; i < cMemEnd; i++) 	// verify data
	{
		if ((B8)i!=USBRead((B8)i))
			errors++;
		
		USBWrite((B8)i, (B8)~i);
		if ((B8)~i!=USBRead((B8)i))
			errors++;
		
	}
	// auto increment: addr = data
	for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
		USB_ADDR_DATA=(B32)i;
	// auto: addr = data
	for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
	{
		if ((B8)i != (B8)USB_ADDR_DATA)
			errors++;
	}
	// clear all SL811H/SL11H Memory
	for (i = EP0Buf,USB_ADDR_ADDR=(B32)EP0Buf;i<cMemEnd;i++)
		USB_ADDR_DATA=0;
	
	uartpush("\tMemory test done ,");
	ltoa(errors,data,10);
	uartpush(data);
	uartpush(" errors was found!\n\r");
	
		
	return (B32)errors; 		// Return number of error
}


//*****************************************************************************************
// USB Reset
//*****************************************************************************************
void USBReset()
{
	B8 tmp;
	uartpush("USBReset();\n\r");
	tmp = USBRead(CtrlReg); 	// Read Control Status
	USBWrite(CtrlReg,tmp|8); 	// Setup USB Reset
	Delayms(250);
	USBWrite(CtrlReg,tmp|0x18); // su suspend/resume, reset
	Delayms(150);
	USBWrite(CtrlReg,tmp|8); 	// Setup USB Reset
	Delayms(10); 				// Delay 10 ms
	USBWrite(CtrlReg,tmp); 		// enable USB
}

//*****************************************************************************************
//USB init to slave 
//*****************************************************************************************

void usb_init()
{
	B32 temp;
	char data[256];
	
	temp=EXTACON0_C;
	temp=temp&0xffff0000;
	temp=temp|0x00000841;
	EXTACON0_C=temp;            //set EXTACON0 mode--tACS1=0cycle tACC1=4cycle tCOS1=1cycle tCOH1=1cycle
	
	uartpush("usb_init();\n\r");
	temp=USBRead(0x0e);
	ltoa(temp,data,16);
	uartpush("##########hw_version=0x");
	uartpush(data);
	uartpush("\n\r");
			
			
	//Write value “0x00” to register 0FH
	USBWrite(0x0f,0x00);
	//Memory Test
	USBMemTest();
	//Reset chip
	USBWrite(IntEna,0x40);	// enable USB Reset interrupt
    USBWrite(CtrlReg,0x01);   // enable USB, FullSpeed
    USBWrite(IntStatus,0xFF);	// clear all interrupts
	/*
	
	
	//USBReset();
	//Disable Interrupt Enable
	//Write value “0x00” to register 06H
	USBWrite(0x06,0x00);
	//Setup USB Address
	//Write value “0x00” to register 07H
	USBWrite(0x0f,0x00);
	//Setup endpoint 0 address starts at 0x40
	//Write value “0x40’ to register 01H
	USBWrite(0x01,0x40);
	//Setup transfer length of endpoint 0		//改
	//Write value “0x40” to register 02H
	USBWrite(0x02,0x40);
	//Set Arm and direction bit
	//Write value “0x03” to register 00H		
	USBWrite(0x00,0x03);

//Endpoint 1 Set A:
	//Setup address Endpoint 1 starts at 0x60
	//Write value “0x60” to register 11H
	USBWrite(0x11,0x60);
	//Setup endpoint 1 transfer length
	//Write value “0x40” to register 12H
	USBWrite(0x12,0x40);
	//Set Arm and direction bit
	//Write value “0x03” to register 10H
	USBWrite(0x10,0x03);
	
//Endpoint 2 Set A and B:
	//Setup Endpoint2A address starts at 0x80
	//Write value “0x80” to register 21H
	USBWrite(0x21,0x80);
	//Setup Endpoint2B address starts at 0xC0
	//Write value “0xC0” to register 29H
	USBWrite(0x29,0xc0);
	//Setup Endpoint2A transfer length
	//Write value “0x40” to register 22H
	USBWrite(0x22,0x40);
	//Setup Endpoint2B transfer length			//改??
	//Write value “0x40” to register 2AH
	USBWrite(0x2a,0x40);
	//Set Arm and direction bit					//改
	//Write value “0x03” to register 20H
	USBWrite(0x20,0x03);
	
//Interrupt Enable for Endpoint 0, 1, 2, SOF and USB reset
	//Write value “0x67” to register 06H
	USBWrite(0x06,0x67);
	//Enable USB Transfer
	//Write value “0x01” to register 05H
	USBWrite(0x05,0x01);
	//Clear Interrupt Status
	//Write value “0xFF” to register 0DH
	USBWrite(0x0d,0xff);

*/

}

////////////////////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************
// EP0 interrupt service routine
//*****************************************************************************************
void ep0_isr(void)
{
	B8 	status, byte_rx, len_xfr;
	B8	data_seq, req_type;
	char data[256];

	uartpush("ep0_isr();\n\r");
	USBWrite(IntStatus,EP0_DONE);							// clear EP0 interrupt	
	status 	= USBRead(EP0AStatus);							// get packet status
	
	//ltoa(status,data,16);
	//uartpush("####EP0A_status=0x");
	//uartpush(data);
	//uartpush("\n\r");
	
	byte_rx = USBRead(EP0AXferLen) - USBRead(EP0ACounter);	// get no. of bytes received
															// for OUT data from host
	//----------------------------------------------------------------------------------------
	// ACK received 
	//----------------------------------------------------------------------------------------
	if(status & EP_ACK)
	{
		//uartpush("__ACK received!\n\r");
		//----------------------------------------------------------------
		// Set newly assigned USB address
		//----------------------------------------------------------------
		if(Slave_USBaddr)								
		{														// if new USB address was assigned, 
		    //uartpush("____Set newly assigned USB address!\n\r");
		    USBWrite(USBAddress,Slave_USBaddr);				// communicate all USB transaction	
			Slave_USBaddr = 0;									// using this new address.				
		}

		//================================================================
		// SETUP's ACKed
		//================================================================
		if(status & EP_SETUP)					
		{
	    	//uartpush("____SETUP's ACKed!\n\r");
	    	USBBufRead(EP0A_Slave_Buf, (B8*)&dReq, byte_rx); 			// capture SETUP data request
			
			
			//----------------------------------------
			//例程的B16和ARM的组织形式相反
			//----------------------------------------
			dReq.wValue=WordSwap(dReq.wValue);							//edit by chendong at 2004-07-15 10:30
																		//The wValue field specifies the descriptor type in the high byte and the descriptor index in the low byte
			dReq.wIndex=WordSwap(dReq.wIndex);
			
			dReq.wLength=WordSwap(dReq.wLength);
			//////////////////////////////////////////////////////////
			
			
			len_req = WordSwap(dReq.wLength);							// len_req = actual requested length
			in_buffer_idx = 0;											// reset buffer locatio indexing
			IN_NULL = FALSE;											// these are for IN-NULL packet
			IN_EXACT = FALSE;											// transfer condition
			req_type = (dReq.bmRequest&0x60)>>5;						// decode for Std,Class,Vendor type

		    //-------------------------------------------------------------------------------
			//send debug data back to the pc through uart			

⌨️ 快捷键说明

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