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

📄 host_811.c

📁 usb2.0驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:

///////////////////////////////////////////////////////////////////////////////
// Cypress Semiconductor - Customer Design Center 
////////////////////////////////////////////////////////////////////////////////
// File:		host_811.c

//#include "..\inc\def.h"
#include "Host_811.h"
//#include "..\inc\Fat.h"
//#include "..\inc\44b.h"

BOOLEAN	MP3Present;//extern  BOOLEAN	MP3Present;
STRU_LongDIR_INFO DIR_MP3[20];//extern STRU_LongDIR_INFO DIR_MP3[20];
STRU_LongDIR_INFO DIR_MP3_music;
DWORD UnusedDosage_Mp3;

//*****************************************************************************************
// xdata variables
//*****************************************************************************************
xdata BYTE      info[100];

xdata BYTE 			DBUF[256];		// at 0x2000 for general descriptors data
xdata DWORD           StartLogicalSectorNo;
xdata DWORD           RootStartSectorNo;
xdata DWORD           DataStartSectorNo;
xdata DWORD           Capacity;
xdata WORD            CountOfClusters_mp3;
xdata DWORD           total_dosage_mp3;
xdata DWORD           random=0;
xdata sBpbFat12      sBpbFat12_global;
xdata sMbsInfo        sMbsInfo_global;

xdata BYTE 			DataBufLen;		// EZUSB's IN #3 data transfer buffer length
xdata BYTE 			pNumPort;		// Number of downstream ports on hub
xdata BYTE			remainder;		// Remaining byte in a USB transfer
xdata pUSBDEV  		uDev[MAX_DEV];	// Multiple USB devices attributes, Max 5 devices
xdata pHUBDEV		uHub;			// Struct for downstream device on HUB

xdata pDevDesc  	pDev;			// Device descriptor struct
xdata pCfgDesc 		pCfg;			// Configuration descriptor struct
xdata pIntfDesc 	pIfc;			// Interface descriptor struct
xdata pEPDesc 		pEnp;			// Endpoint descriptor struct


//*****************************************************************************************
// Boolean Logic Defines
//*****************************************************************************************

BOOL  	SLAVE_FOUND;				// Slave USB device found
BOOL  	SLAVE_ENUMERATED;			// slave USB device enumeration done
BOOL  	FULL_SPEED;					// Full-Speed = TRUE, Low-Speed = FALSE
BOOL		HUB_DEVICE;					// HUB device = TRUE
BOOL 	BULK_OUT_DONE;				// Set when EZUSB's OUT1 hostcmd xfer is done
BOOL 	DESC_XFER;					// Set when there is data for EZUSB's IN1 desc xfer
BOOL 	DATA_XFER;					// Set when there is data for EZUSB's IN3 data xfer
BOOL 	DATA_XFER_OUT;				// Set when there is data for EZUSB's OUT3 data xfer
BOOL 	CONFIG_DONE;				// Set when EZUSB completes its enumeration process.
BOOL 	TIMEOUT_ERR;				// timeout error during data endpoint transfer
BOOL		DATA_STOP;					// device unplugged during data transfer
BOOL		DATA_INPROCESS;				// set when we are in a data pipe transfer
BOOL		pLS_HUB;					// indicate previous command is a LS device on hub

BOOL		dsPoll;				        // poll downstream port conections

BOOL		bData1;

//*****************************************************************************************
// Byte Read from SL811H
// a = register address
// return = data in register
//*****************************************************************************************
void SL811Read(BYTE a,BYTE *s)
{  
      usb_com=a;
      *s=usb_data;
	/*rPDATD=0xff;
	rPCOND =0x5555;		//output port
	rPUPD =0x00;
	rPDATC &=0xfffe;		//low 	A0
	rPDATC &=0xfff9;		//low CS and WR
	rPDATD =a;			//output address
	rPDATC |=0x0004;		//high WR
	rPDATC |=0x01;			//high A0
	rPDATD=0xff;
	rPCOND=0x0000;			//PORT D input PORT
	rPUPD=0x00;
	rPDATC &=0xfff7;		//LOW OE
	*s=rPDATD;
	rPDATC |=0x08;			//high OE
	rPDATC |=0x02;			//high CS
	
	*/
}

//*****************************************************************************************
// Byte Write to SL811H
// a = register address
// d = data to be written to this register address
//*****************************************************************************************
void SL811Write(BYTE a, BYTE d)
{  
       usb_com=a;
       usb_data=d;
	/*rPDATD=0xff;
	rPCOND =0x5555;		//output port
	rPUPD =0x00;	
	rPDATC &=0xfffe;		//low 	A0
	rPDATC &=0xfff9;		//low CS and WR
	rPDATD =a;			//output address
	rPDATC |=0x0004;		//high WR
	rPDATC |=0x01;			//high A0
	rPDATC &=0xfffb;		//LOW WR
	rPDATD=d;
	rPDATC |=0x04;			//high WR
	rPDATC |=0x02;			//high CS
	*/
}

//*****************************************************************************************
// Buffer Read from SL811H
// addr = buffer start address
// s    = return buffer address where data are to be save/read
// c	= buffer data length
//*****************************************************************************************
void SL811BufRead(BYTE addr, BYTE *s, BYTE c)
{	
	/*rPDATD=0xff;
	rPCOND =0x5555;		//output port
	rPUPD =0x00;
	
	rPDATC &=0xfffe;		//low 	A0
	rPDATC &=0xfff9;		//low CS and WR
	rPDATD =addr;			//output address
	rPDATC |=0x0004;		//high WR
	rPDATC |=0x01;			//high A0
	rPDATD=0xff;
	rPCOND=0x0000;			//PORT D input PORT
	rPUPD=0x00;*/
	usb_com=addr;
	while (c--)
	{
		/*rPDATC &=0xfff5;		//LOW OE and LOW CS
		*s++=rPDATD;
		rPDATC |=0x08;			//high OE
		rPDATC |=0x02;			//high CS*/
		*s++=usb_data;
	}
}

//*****************************************************************************************
// Buffer Write  to SL811H
// addr = buffer start address
// s    = buffer address where data are to be written
// c	= buffer data length
//*****************************************************************************************
void SL811BufWrite(BYTE addr, BYTE *s, BYTE c)
{	
	/*rPDATD=0xff;
	rPCOND =0x5555;		//output port
	rPUPD =0x00;	
	rPDATC &=0xfffe;		//low 	A0
	rPDATC &=0xfff9;		//low CS and WR
	rPDATD =addr;			//output address
	rPDATC |=0x0004;		//high WR
	rPDATC |=0x01;			//high A0*/
	usb_com=addr;
	while (c--)
	{
		/*rPDATC &=0xfff9;		//LOW WR and CS
		rPDATD=*s++;
		rPDATC |=0x04;			//high WR
		rPDATC |=0x02;			//high CS*/
		usb_com=*s++;
	}
}
//*****************************************************************************************
// Swap high and low byte 
//*****************************************************************************************
WORD WordSwap(WORD input)
{
	return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}
//*****************************************************************************************
// UsbReset during enumeration of device attached directly to SL811HS
//*****************************************************************************************
void USBReset()
{
    BYTE tmp;
    SL811Read(3,&tmp); 
      
 	SL811Write(CtrlReg,tmp|0x08);		//setup usb reset
 	usb_Delay(250);				
 	SL811Write(CtrlReg,tmp|0x18);		//suspend/resume,reset
 	usb_Delay(150);
 	SL811Write(CtrlReg,tmp|0x8);
 	usb_Delay(250);
 	
    SL811Write(CtrlReg,tmp);    
}
//*****************************************************************************************
//USB Delay edit by ricky
//here should concern about watchdog late.
//*****************************************************************************************
void usb_Delay(int sec)
{
int	timer=1000;
int	i,j;
for (i=0;i<sec;i++)
	{
	for(j=0;j<timer;j++)
	 {
	  }
	}
}
//*****************************************************************************************
// usbXfer:
// successful transfer = return TRUE
// fail transfer = return FALSE
//*****************************************************************************************
int usbXfer(BYTE usbaddr, BYTE endpoint, BYTE pid, BYTE iso, WORD wPayload, WORD wLen, BYTE *buffer)
{  
	xdata BYTE 	cmd, result, timeout, intr;
	xdata BYTE	xferLen, bufLen, data0, data1, dataX, addr;
	
	//------------------------------------------------
	// Default setting for usb trasnfer
	//------------------------------------------------
	bufLen = dataX = timeout = 0;					//reset all
	data0 = EP0_Buf;								// DATA0 buffer address
	data1 = data0 + (BYTE)wPayload;					// DATA1 buffer address
	DATA_STOP =TIMEOUT_ERR = FALSE;				// set default conditions

	//------------------------------------------------
	// Define data transfer payload
	//------------------------------------------------
	if (wLen >= wPayload)  							// select proper data payload
		xferLen = wPayload;							// limit to wPayload size 
	else											// else take < payload len
		xferLen = wLen;								//	

	//------------------------------------------------
	// For IN token
	//------------------------------------------------
	if (pid==PID_IN)								// for current IN tokens
	{												//
		cmd = sDATA0_RD;						// FS/FS on Hub, sync to sof
		// implement data toggle.added by ricky.
		bData1 = uDev[usbaddr].bData1[endpoint];

		if(bData1)
         		cmd |= 0x40;       
	}
	//------------------------------------------------
	// For OUT token
	//------------------------------------------------
	else if(pid==PID_OUT)							// for OUT tokens
	{  	
		if(xferLen)
		{									// only when there are	
			SL811BufWrite(data0,buffer,xferLen); 	// data to transfer on USB
			buffer += xferLen;								
		}

		cmd = DATA0_WR;						// FS/FS on Hub, sync to sof
		// implement data toggle
		bData1 = uDev[usbaddr].bData1[endpoint];

		if(bData1)
          		cmd |= 0x40;                              // Set Data1 bit in command
	}
	//------------------------------------------------
	// For SETUP/OUT token
	//------------------------------------------------
	else											// for current SETUP/OUT tokens
	{  	
		if(xferLen)									// only when there are	
			SL811BufWrite(data0,buffer,xferLen); 	// data to transfer on USB

		cmd = sDATA0_WR;						// FS/FS on Hub, sync to sof
	}

	//------------------------------------------------
	// Isochronous data transfer setting
	//------------------------------------------------
	if (iso) 
		cmd |= ISO_BIT;                     		// if iso setup ISO mode

	//------------------------------------------------
	// For EP0's IN/OUT token data, start with DATA1
	// Control Endpoint0's status stage.
	// For data endpoint, IN/OUT data, start ????
	//------------------------------------------------
	if (endpoint == 0 && pid != PID_SETUP) 			// for Ep0's IN/OUT token
	{
		bData1=1;
		uDev[usbaddr].bData1[endpoint] = 1; 		// DataToggle
		cmd |= 0x40; 								// always set DATA1
	}

	//------------------------------------------------
	// Arming of USB data transfer for the first pkt
	//------------------------------------------------
	SL811Write(EP0Status,((endpoint&0x0F)|pid));	// PID + EP address
	SL811Write(EP0Counter,usbaddr);					// USB address
	SL811Write(EP0Address,data0);					// buffer address, start with "data0"
	SL811Write(EP0XferLen,xferLen);					// data transfer length
	SL811Write(IntStatus,INT_CLEAR); 				// clear interrupt status
	SL811Write(EP0Control,cmd);						// Enable ARM and USB transfer start here

	//------------------------------------------------
	// Main loop for completing a wLen data trasnfer
	//------------------------------------------------
	while(TRUE)
	{   
		//---------------Wait for done interrupt------------------
		while(TRUE)												// always ensure requested device is
		{	
			// inserted at all time, then you will
                     //short_delay(5);
			SL811Read(IntStatus,&intr);						// wait for interrupt to be done, and 
			if((intr & USB_RESET) || (intr & INSERT_REMOVE))	// proceed to parse result from slave 
			{													// device.
				DATA_STOP = TRUE;								// if device is removed, set DATA_STOP
				return FALSE;									// flag true, so that main loop will 
			}													// know this condition and exit gracefully
			if(intr & USB_A_DONE)								
				break;											// interrupt done !!!
		}

		SL811Write(IntStatus,INT_CLEAR); 						// clear interrupt status
		SL811Read(EP0Status,&result);						// read EP0status register
		SL811Read(EP0Counter,&remainder);						// remainder value in last pkt xfer

		//-------------------------ACK----------------------------
		if (result & EP0_ACK)									// Transmission ACK
		{	

			// SETUP TOKEN
			if(pid == PID_SETUP)								// do nothing for SETUP/OUT token 
				break;											// exit while(1) immediately

			// OUT TOKEN				
			else if(pid == PID_OUT)
			{
				uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint] ? 0 : 1); // DataToggle
				wLen  -= (WORD)xferLen;							// update remainding wLen value
				cmd   ^= 0x40;   				// toggle DATA0/DATA1
				dataX++;	
								
				//------------------------------------------------	
				// If host requested for more data than the slave 
				// have, and if the slave's data len is a multiple
				// of its endpoint payload size/last xferLen. Do 
				// not overwrite data in previous buffer.
				//------------------------------------------------	
				if(remainder==xferLen)							// empty data detected
					bufLen = 0;									// do not overwriten previous data
				else											// reset bufLen to zero
					bufLen = xferLen;							// update previous buffer length
				
				//------------------------------------------------	
				// Arm for next data transfer when requested data 
				// length have not reach zero, i.e. wLen!=0, and
				// last xferlen of data was completed, i.e.
				// remainder is equal to zero, not a short pkt

⌨️ 快捷键说明

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