📄 sl811.c
字号:
#include <string.h>
#include "..\INC\44blib.h"
#include "..\INC\utils.h"
#include "..\INC\MassOp.h"
#include "..\INC\led.h"
#include "..\INC\SL811.h"
#include "..\inc\hpi.h"
extern TJHFLAGS bTJHFlags;
TJHPKG usbstack;
pUSBDEV uDev;
U8 SL811Read(U8 a)
{
SL811H_ADDR=a;
return SL811H_DATA;
}
void SL811Write(U8 a, U8 d)
{
SL811H_ADDR=a;
SL811H_DATA=d;
}
void SL811BufRead(U8 addr, U8 *s, U8 c)
{
U8 i;
SL811H_ADDR=addr;
for(i=0;i<c;i++)
*s++ =SL811H_DATA;
}
void SL811BufWrite(U8 addr, U8 *s, U8 c)
{
SL811H_ADDR=addr;
while (c--)
SL811H_DATA = *s++;
}
U16 WordSwap(U16 input)
{
return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}
U32 SwapINT32(U32 dData)
{
dData = (dData&0xff)<<24|(dData&0xff00)<<8|(dData&0xff000000)>>24|(dData&0xff0000)>>8;
return dData;
}
U16 SwapINT16(U16 dData)
{
dData = (dData&0xff00)>>8|(dData&0x00ff)<<8;
return dData;
}
U16 MakeU16(U8 d1,U8 d0)
{
U16 result;
result=d1;
result=result<<8|d0;
return result;
}
U32 MakeU32(U8 d3,U8 d2,U8 d1,U8 d0)
{
unsigned long temp,result;
temp=d3;
result=temp<<24;
temp=d2;
result=result|temp<<16;
temp=d1;
result=result|temp<<8|d0;
return result;
}
//*****************************************************************************************/
// SL811H variables initialization
//*****************************************************************************************/
void SL811_Init(void)
{
SL811Write(cDATASet,0xe0);
//SL811Write(cDATASet,0xb0);
SL811Write(cSOFcnt,0xae);
//SL811Write(cSOFcnt,0x84);
SL811Write(CtrlReg,0x5);
SL811Write(EP0Status,0x50);
SL811Write(EP0Counter,0);
SL811Write(EP0Control,0x01);
SL811Write(IntEna,0x20); // USB-A, Insert/Remove, USB_Resume.
SL811Write(IntStatus,INT_CLEAR); // Clear Interrupt enable status
}
//***********************************************
U8 SL811_GetRev(void)
{
return SL811Read(0x0e);
}
/* check if the Mass Storage Device is online?-------edited by tianjh 05.03.11----*/
U8 check_usbdevice(void)
{
U8 intr; //intr -> the status of Interrupt Register
prompt();
Uart_Printf("CHECK DEVICE BEGINNING.\n");//FOR DEBUGGING EDITED BY TAINJH 05.03.21
prompt();
intr=SL811Read(IntStatus);
SL811Write(IntStatus,INT_CLEAR);
SL811Write(IntStatus,INSERT_REMOVE); //the bit of Insert/Remove
if(intr & 0x40) // This bit is "1" -> Device not present
{
Uart_Printf("The Udisk is not present!\n"); //added by chenzhi 2006.5.15
if(bTJHFlags.SLAVE_ONLINE ==1)
{
Led_Display(4,0);
Led_Display(3,0);
Uart_Printf("\nMass storage device is removed.\n");
prompt();
bTJHFlags.UDiskOK = FALSE;
bTJHFlags.SLAVE_ONLINE =0;
}
}
else // This bit is "0" -> Device is present
{
if(bTJHFlags.SLAVE_ONLINE == 0)
{
Delay1(6000000);
if(!EnumUsbDev(1)) //step 1: enumerate USB device, assign USB address = #1
return FALSE;
Uart_Printf("\n Found USB DEVICE. Now begin to enuerate......\n");
Delay1(500000);
if(EnumMassDev()) //step 2: emumerate U-Disk
{
bTJHFlags.UDiskOK = TRUE;
Uart_Printf("Mass storage device mounted successfully. It's ready to use\n");
if(bTJHFlags.bIsFat32)
Uart_Printf("File system on the disk is FAT32\n");
else
Uart_Printf("File system on the disk is FAT16\n");
prompt();
// init all the variables
// init complete
Led_Display(3,1);
Led_Display(4,1);
}
else
{
Led_Display(3,0);
bTJHFlags.UDiskOK = FALSE;
Uart_Printf("Enumerate device FAILD!\n");
prompt();
}
bTJHFlags.SLAVE_ONLINE =1;
return TRUE;
}
}
return TRUE;
}
/****************************************************************************************/
//
/****************************************************************************************/
void USBReset(void)
{
U8 temp;
temp=SL811Read(CtrlReg);
SL811Write(CtrlReg,temp|0x08);
Delay1(250);
SL811Write(CtrlReg,temp);
}
//*****************************************************************************************/
// usbXfer:
// successful transfer = return TRUE
// fail transfer = return FALSE
//*****************************************************************************************/
//************************************
U8 usbXfer(void)
{
U8 xferLen, data0, data1,cmd,offset;
U8 intr,result,remainder,dataX,bufLen,addr,timeout;
U8 bEnd,temp;
//------------------------------------------------
// Default setting for usb trasnfer
//------------------------------------------------
dataX=timeout=bEnd=0;
offset=0;
data0 = EP0_Buf; // DATA0 buffer address
data1=EP1_Buf;
bTJHFlags.DATA_STOP=FALSE;
bTJHFlags.TIMEOUT_ERR=FALSE;
//------------------------------------------------
// Define data transfer payload
//------------------------------------------------
if (usbstack.wLen >= usbstack.wPayload) // select proper data payload
xferLen = usbstack.wPayload; // limit to wPayload size
else // else take < payload len
xferLen = usbstack.wLen; //
// For IN token
if (usbstack.pid==PID_IN) // for current IN tokens
{ //
cmd = sDATA0_RD; // FS/FS on Hub, sync to sof
}
// For OUT token
else if(usbstack.pid==PID_OUT) // for OUT tokens
{
SL811BufWrite(data0,(U8 *)usbstack.buffer,xferLen); // data to transfer on USB
cmd = sDATA0_WR;
bTJHFlags.bData1 = uDev.bData1[usbstack.endpoint];
uDev.bData1[usbstack.endpoint] = (uDev.bData1[usbstack.endpoint] ? 0 : 1); // DataToggle
if(bTJHFlags.bData1==1)
{
cmd |= 0x40; // Set Data1 bit in command
}
}
// For SETUP/OUT token
else // for current SETUP/OUT tokens
{
if(xferLen) // only when there are
{
usbstack.setup.wValue=WordSwap(usbstack.setup.wValue);
usbstack.setup.wIndex=WordSwap(usbstack.setup.wIndex);
SL811BufWrite(data0,(U8 *)&usbstack.setup,xferLen); // data to transfer on USB
}
cmd = sDATA0_WR; // FS/FS on Hub, sync to sof
}
//------------------------------------------------
// For EP0's IN/OUT token data, start with DATA1
// Control Endpoint0's status stage.
// For data endpoint, IN/OUT data, start ????
//------------------------------------------------
if (usbstack.endpoint == 0 && usbstack.pid != PID_SETUP) // for Ep0's IN/OUT token
cmd |= 0x40; // always set DATA1
//------------------------------------------------
// Arming of USB data transfer for the first pkt
//------------------------------------------------
temp=(usbstack.endpoint&0x0F)|usbstack.pid;
SL811Write(EP0Status,temp); // PID + EP address
SL811Write(EP0Counter,usbstack.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
SL811Write(EP1Status,temp); // PID + EP address
SL811Write(EP1Counter,usbstack.usbaddr); // USB address
SL811Write(EP1Address,data1); // buffer address, start with "data0"
SL811Write(EP1XferLen,64); // data transfer length
//------------------------------------------------
// 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
intr = SL811Read(IntStatus);
// wait for interrupt to be done, and
if((intr & USB_RESET) || (intr & INSERT_REMOVE)) // proceed to parse result from slave
{ // device.
bTJHFlags.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)&&((offset==0)))
break;
if((intr & USB_B_DONE)&&((offset>0)))
break; // interrupt done !!!
}
Delay1(10000);
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
result = SL811Read(EP0Status); // read EP0status register
remainder = SL811Read(EP0Counter); // remainder value in last pkt xfer
//-------------------------ACK----------------------------
if (result & EP0_ACK) // Transmission ACK
{
// SETUP TOKEN
if(usbstack.pid == PID_SETUP) // do nothing for SETUP/OUT token
break; // exit while(1) immediately
// OUT TOKEN
else if(usbstack.pid == PID_OUT)
{
usbstack.wLen -= (WORD)xferLen;
usbstack.buffer += xferLen;
if(!usbstack.wLen)
break;
//////////////////////////////
if (usbstack.wLen >= usbstack.wPayload) // select proper data payload
xferLen = usbstack.wPayload; // limit to wPayload size
else // else take < payload len
xferLen = usbstack.wLen; //
addr=data0;
SL811BufWrite(addr,usbstack.buffer,xferLen);
cmd=sDATA0_WR;
bTJHFlags.bData1 = uDev.bData1[usbstack.endpoint];
uDev.bData1[usbstack.endpoint] = (uDev.bData1[usbstack.endpoint] ? 0 : 1); // DataToggle
if(bTJHFlags.bData1==1)
cmd |= 0x40; // Set Data1 bit in command
SL811Write(EP0Address,addr); // buffer address, start with "data0"
SL811Write(EP0XferLen,xferLen); // data transfer length
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
SL811Write(EP0Control,cmd);
} //PID OUT
//////////////////////////////////////////////
// IN TOKEN
else if(usbstack.pid == PID_IN)
{ // for IN token only
usbstack.wLen -= (WORD)xferLen; // update remainding wLen value
cmd ^= 0x40; // toggle DATA0/DATA1
dataX++; // point to next 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 + -