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

📄 usb.c

📁 这个是录音琴的程序,用光电感应器来检测琴键的动作.并且将他记录下来,可以回放.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************Copyright (c)***************************************

        U盘操作.

************************************************************************************/

#include	"common.h"
#include	"usb.H"

/*---------------------------------------------------------------------------------*/

UBYTE 			xdata 	FatBuf[512];
UBYTE 			xdata 	CurFatSector[512];

UBYTE 			xdata	opLun;
UWORD 			xdata 	FreeClusterNum;
UWORD 			xdata	FreeSecNum;

UWORD 			xdata 	StartSec2Write;
UBYTE 			xdata 	*BufStartAddress;
UWORD  			xdata 	OldClusterPointer;

USBFLAGS 		bdata	DiskFlags;
USBPKG 			xdata	usbstack;
pUSBDEV  		xdata	uDev;

DIR_INFO 		xdata 	ThisDir;
FILE_INFO 		xdata 	ThisFile;
SYS_INFO_BLOCK 	xdata 	DeviceInfo;
TPBLK_STRUC 	xdata 	TPBulk_Block;

/*---------------------------------------------------------------------------------*/

UBYTE SL811Read(UBYTE a)
{
	UBYTE nVal;

	SL811H_ADDR=a;
	nVal=SL811H_DATA;
	return nVal;
}

void SL811Write(UBYTE a, UBYTE d)
{
	SL811H_ADDR=a;
	SL811H_DATA=d;
}

void SL811BufRead(UBYTE addr, UBYTE *s, UBYTE c)
{
	UBYTE i;
	SL811H_ADDR=addr;

	for(i=0;i<c;i++)
		*s++ =SL811H_DATA;
}

void SL811BufWrite(UBYTE addr, UBYTE *s, UBYTE c)
{
	SL811H_ADDR=addr;

	while (c--)
		SL811H_DATA = *s++;
}

UHWORD WordSwap(UHWORD input)
{
	return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}

void DelayMs(UBYTE nFactor)
{
	UBYTE	i;
	UHWORD  j;

	for(i=0; i<nFactor; i++)
	{
		for(j=0;j<1000;j++)
			j=j;
	}
}

UWORD SwapINT32(UWORD dData)
{
    dData = (dData&0xff)<<24|(dData&0xff00)<<8|(dData&0xff000000)>>24|(dData&0xff0000)>>8;
	return dData;
}

UHWORD SwapINT16(UHWORD dData)
{
    dData = (dData&0xff00)>>8|(dData&0x00ff)<<8;
	return dData;
}


UWORD MakeWord(UBYTE d3,UBYTE d2,UBYTE d1,UBYTE d0)
{
	UWORD temp,result;
	temp=d3;
	result=temp<<24;
	temp=d2;
	result=result|temp<<16;
	temp=d1;
	result=result|temp<<8|d0;
	return result;
}

void USBReset(void)
{
	UBYTE temp;
    temp=SL811Read(CtrlReg);
    temp=temp&0xE7;
 	SL811Write(CtrlReg,temp|0x08);
	DelayMs(125);
    SL811Write(CtrlReg,temp);
}

UBYTE usbXfer(void)
{
	UBYTE	xferLen, data0, data1,cmd,offset;
	UBYTE 	intr,result,remainder,dataX,bufLen,addr,timeout;
	UBYTE 	bEnd;

	dataX=timeout=bEnd=0;
	offset=0;
	data0 = EP0_Buf;
	data1=EP1_Buf;

	if (usbstack.wLen >= usbstack.wPayload)
		xferLen = usbstack.wPayload;
	else
		xferLen = usbstack.wLen;

	if (usbstack.pid==PID_IN)
	{
		cmd = sDATA0_RD;
	}
	else if(usbstack.pid==PID_OUT)
	{
		SL811BufWrite(data0,usbstack.buffer,xferLen);
		cmd = sDATA0_WR;

		DiskFlags.bData1 = uDev.bData1[usbstack.endpoint];
        uDev.bData1[usbstack.endpoint] = (uDev.bData1[usbstack.endpoint] ? 0 : 1);

		if(DiskFlags.bData1==1)
          	cmd |= 0x40;
	}
	else
	{
		if(xferLen)
		{
			intr=usbstack.setup.wLength;
			usbstack.setup.wValue=WordSwap(usbstack.setup.wValue);
			usbstack.setup.wIndex=WordSwap(usbstack.setup.wIndex);
			usbstack.setup.wLength=WordSwap(usbstack.setup.wLength);
			SL811BufWrite(data0,(UBYTE *)&usbstack.setup,xferLen);
			usbstack.setup.wLength=intr;
		}

		cmd = sDATA0_WR;
	}

	if (usbstack.endpoint == 0 && usbstack.pid != PID_SETUP)
		cmd |= 0x40;

	SL811Write(EP0Status,((usbstack.endpoint&0x0F)|usbstack.pid));
	SL811Write(EP0Counter,usbstack.usbaddr);
	SL811Write(EP0Address,data0);
	SL811Write(EP0XferLen,xferLen);
	SL811Write(IntStatus,INT_CLEAR);
	SL811Write(EP0Control,cmd);

	SL811Write(EP1Status,((usbstack.endpoint&0x0F)|usbstack.pid));
	SL811Write(EP1Counter,usbstack.usbaddr);
	SL811Write(EP1Address,data1);
	SL811Write(EP1XferLen,64);

	while(1)
	{
		while(1)
		{
			intr = SL811Read(IntStatus);

			if((intr & USB_RESET) || (intr & INSERT_REMOVE))
				return	false;

			if((intr & USB_A_DONE)&&((offset==0)))
				break;

			if((intr & USB_B_DONE)&&((offset>0)))
				break;
		}

		SL811Write(IntStatus,INT_CLEAR);
		result 	  = SL811Read(EP0Status);
		remainder = SL811Read(EP0Counter);

		if (result & EP0_ACK)
		{
			if(usbstack.pid == PID_SETUP)
				break;

			else if(usbstack.pid == PID_OUT)
			{
				usbstack.wLen  -= (UHWORD)xferLen;
				usbstack.buffer += xferLen;

				if(!usbstack.wLen)
					break;

				if (usbstack.wLen >= usbstack.wPayload)
					xferLen = usbstack.wPayload;
				else
					xferLen = usbstack.wLen;

				addr=data0;
				SL811BufWrite(addr,usbstack.buffer,xferLen);

				cmd = sDATA0_WR;
				DiskFlags.bData1 = uDev.bData1[usbstack.endpoint];
        		uDev.bData1[usbstack.endpoint] = (uDev.bData1[usbstack.endpoint] ? 0 : 1);

          		if(DiskFlags.bData1==1)
          			cmd |= 0x40;

				SL811Write(EP0XferLen, xferLen);
				SL811Write(EP0Address, addr);
				SL811Write(IntStatus,INT_CLEAR);
				SL811Write(EP0Control,cmd);
			}

			else if(usbstack.pid == PID_IN)
			{
				usbstack.wLen  -= (UHWORD)xferLen;
				cmd   ^= 0x40;
				dataX++;

				if(remainder==xferLen)
					bufLen = 0;
				else
					bufLen = xferLen;

				if(!remainder && usbstack.wLen)
				{
					addr    = (dataX & 1) ? data1:data0;
					xferLen = (UBYTE)(usbstack.wLen>=usbstack.wPayload) ? usbstack.wPayload:usbstack.wLen;
					cmd |= 0x20;
					SL811Write(EP0XferLen, xferLen);
					SL811Write(EP0Address, addr);
					SL811Write(IntStatus,INT_CLEAR);
					SL811Write(EP0Control,cmd);
				}

				if(bufLen)
				{
					SL811BufRead(((dataX&1)?data0:data1), usbstack.buffer, bufLen);
					usbstack.buffer += bufLen;
				}

				if(remainder || !usbstack.wLen)
					break;
			}
			else if((usbstack.pid == PID_OUT)&&(bEnd))
            	break;
			else if(usbstack.pid == PID_SETUP)
				break;
		}

		if (result & EP0_NAK)
		{
			offset=0;
			SL811Write(IntStatus,INT_CLEAR);
			SL811Write(EP0Control+offset,cmd);
		}

		if (result & EP0_TIMEOUT)
		{
			if(usbstack.endpoint==0)
			{
				if(++timeout >= TIMEOUT_RETRY)
				{
				    timeout--;
					break;
				}
				SL811Write(IntStatus,INT_CLEAR);
				SL811Write(EP0Control,cmd);
			}
			else
			{
				break;
			}
		}

		if (result & EP0_STALL)
			return	true;

		if (result & EP0_OVERFLOW)
			break;
	}

	if (result & EP0_ACK)
		return	true;

	return	false;
}

UBYTE ep0Xfer(void)
{
	usbstack.endpoint=0;
	usbstack.pid=PID_SETUP;
	usbstack.wLen=8;

	if (!usbXfer())
   		return	false;

	usbstack.pid  = PID_IN;
	usbstack.wLen = usbstack.setup.wLength;

   	if (usbstack.wLen)
	{
		if (usbstack.setup.bmRequest & 0x80)
		{
			usbstack.pid  = PID_IN;

			if(!usbXfer())
				return	false;

			usbstack.pid  = PID_OUT;
		}
		else
   		{
			usbstack.pid  = PID_OUT;

			if(!usbXfer())
				return	false;
			usbstack.pid  = PID_IN;
		}
	}

	usbstack.wLen=0;

	if(!usbXfer())
		return	false;

	return	true;
}

UBYTE epBulkSend(UBYTE *pBuffer,UHWORD len)
{
	usbstack.usbaddr=0x1;
	usbstack.endpoint=usbstack.epbulkout;
	usbstack.pid=PID_OUT;
	usbstack.wPayload=64;
	usbstack.wLen=len;
	usbstack.buffer=pBuffer;

	if(usbstack.wLen)
		return	usbXfer();

	return	true;
}

UBYTE epBulkRcv(UBYTE *pBuffer,UHWORD len)
{
	usbstack.usbaddr=0x1;
	usbstack.endpoint=usbstack.epbulkin;
	usbstack.pid=PID_IN;
	usbstack.wPayload=64;
	usbstack.wLen=len;
	usbstack.buffer=pBuffer;

	if(usbstack.wLen)
		return	usbXfer();

	return	true;
}

UBYTE SetAddress(UBYTE addr)
{
	usbstack.usbaddr=0;
	usbstack.setup.bmRequest=0;
	usbstack.setup.bRequest=SET_ADDRESS;
	usbstack.setup.wValue=addr;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=0;

	return ep0Xfer();
}

UBYTE Set_Configuration(void)
{
	usbstack.setup.bmRequest=0;
	usbstack.setup.bRequest=SET_CONFIG;
	usbstack.setup.wValue=DEVICE;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=0;
	usbstack.buffer=NULL;

	return ep0Xfer();
}

UBYTE Set_Interface(void)
{
	usbstack.setup.bmRequest=1;
	usbstack.setup.bRequest=SET_INTERFACE;
	usbstack.setup.wValue=0;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=0;
	usbstack.buffer=NULL;

	return ep0Xfer();
}

UBYTE GetDesc(void)
{
	usbstack.setup.bmRequest=0x80;
	usbstack.setup.bRequest=GET_DESCRIPTOR;
	usbstack.setup.wValue=WordSwap(usbstack.setup.wValue);
	usbstack.wPayload=uDev.wPayLoad[0];

	return ep0Xfer();
}

UHWORD GetMaxLUN(void)
{
	usbstack.setup.bmRequest=0xa1;
	usbstack.setup.bRequest=0xfe;
	usbstack.setup.wValue=0;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=1;
	return ep0Xfer();
}

UBYTE EnumUsbDev(UBYTE usbaddr)
{
	UBYTE	i;
	UBYTE	uAddr = 0;
	UBYTE	epLen;

	pDevDesc  	pDev;
	pCfgDesc 	pCfg;
	pIntfDesc 	pIfc;
	pEPDesc 	pEnp;

	uDev.wPayLoad[0] = 8;

	if(usbaddr == 1)
		USBReset();

    DelayMs(25);

	pDev =(pDevDesc)DBUF;

	usbstack.usbaddr=uAddr;
	usbstack.setup.wValue=DEVICE;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=18;
	usbstack.buffer=DBUF;

	if (!GetDesc())
		return	false;

	uDev.wPayLoad[0]=pDev->bMaxPacketSize0;

	if (!SetAddress(usbaddr))
		return	false;

	uAddr = usbaddr;
	pDev =(pDevDesc)DBUF;
	usbstack.usbaddr=uAddr;

	usbstack.setup.wLength=pDev->bLength;
	usbstack.setup.wValue=DEVICE;
	usbstack.setup.wIndex=0;
	usbstack.buffer=DBUF;

	if (!GetDesc())
		return	false;

	uDev.wVID  = pDev->idVendor;
	uDev.wPID  = pDev->idProduct;
	uDev.iMfg  = pDev->iManufacturer;
	uDev.iPdt  = pDev->iProduct;

	pCfg = (pCfgDesc)DBUF;

	usbstack.usbaddr=uAddr;
	usbstack.setup.wValue=CONFIGURATION;
	usbstack.setup.wIndex=0;
	usbstack.setup.wLength=64;
	usbstack.buffer=DBUF;

	if (!GetDesc())
		return	false;

	pIfc = (pIntfDesc)(DBUF + 9);
	uDev.bClass 	= pIfc->iClass;
	uDev.bNumOfEPs = (pIfc->bEndPoints <= MAX_EP) ? pIfc->bEndPoints : MAX_EP;

	if(uDev.bClass!=8)
		return	false;

	usbstack.usbaddr=uAddr;

	if (!Set_Configuration())
		return	false;

	if (!Set_Interface())
		return	false;

	epLen = 0;
	for (i=1; i<=uDev.bNumOfEPs; i++)
	{
		pEnp = (pEPDesc)(DBUF + 9 + 9 + epLen);
		uDev.bEPAddr[i]  	= pEnp->bEPAdd;
		uDev.bAttr[i]		= pEnp->bAttr;
		uDev.wPayLoad[i] 	= WordSwap(pEnp->wPayLoad);
		uDev.bInterval[i] 	= pEnp->bInterval;
	    	uDev.bData1[i] = 0;
		epLen += 7;
		uDev.bData1[i]=0;
		DiskFlags.bData1=0;

		if(uDev.bAttr[i]==0x2)
		{
		    if(uDev.bEPAddr[i]&0x80)
		    	usbstack.epbulkin=uDev.bEPAddr[i];
		    else
		    	usbstack.epbulkout=uDev.bEPAddr[i];
		}
	}

	usbstack.buffer=DBUF;

	if(!GetMaxLUN())
		return	false;

	opLun=DBUF[0]&0x03;

	return	true;
}

void SL811Init(void)
{
	opLun = 0;

	DiskFlags.bData1 = false;
	DiskFlags.UDiskOK = false;
	DiskFlags.bIsFat32 = false;
	DiskFlags.bFatChanged = false;
	DiskFlags.SLAVE_ONLINE = false;

	SL811Write(cDATASet,0xe0);
	SL811Write(cSOFcnt,0xae);
	SL811Write(CtrlReg,0x5);

	SL811Write(EP0Status,0x50);
	SL811Write(EP0Counter,0);
	SL811Write(EP0Control,0x01);

	SL811Write(IntEna,0x20);
	SL811Write(IntStatus,INT_CLEAR);
}

void CheckUsbDevice(void)
{
	UBYTE intr;

	intr = SL811Read(IntStatus);
	SL811Write(IntStatus,INT_CLEAR);
	SL811Write(IntStatus,INSERT_REMOVE);

	if(intr & 0x40)	// This bit is "1" -> Device not present
	{
		if(DiskFlags.SLAVE_ONLINE == true)
		{
		   	USB_LED = 1;
			DiskFlags.UDiskOK = false;
		   	DiskFlags.SLAVE_ONLINE = false;
		   	USBReset();
		}
	}
	else	// This bit is "0" -> Device is present
	{
		if(DiskFlags.SLAVE_ONLINE == false)
		{
			DelayMs(250);

			if(!EnumUsbDev(1))
			{
				USBReset();
				return;
			}

			USB_LED = 0;

			if(EnumMassDev())
			{
				DiskFlags.UDiskOK = true;
			}
			else
			{
				DiskFlags.UDiskOK = false;
				USBReset();
			}

		   	DiskFlags.SLAVE_ONLINE = true;
		}
	}
}

UBYTE EnumMassDev(void)
{
	PMBR_BLOCK 		pMBR;
	PBPB_BLOCK 		pBPB;
	PFSINFO_BLOCK 	pFSInfo;

⌨️ 快捷键说明

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