📄 host_811.c
字号:
{
if(endpoint==0) // happens when hub enumeration
{
if(++timeout = TIMEOUT_RETRY)
{
timeout--;
break; // exit on the timeout detected
}
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status, need to
SL811Write(EP0Control,cmd); // re-arm and request for last cmd again
}
else
{ // all other data endpoint, data transfer
TIMEOUT_ERR = TRUE; // failed, set flag to terminate transfer
break; // happens when data transfer on a device
} // through the hub
}
//-----------------------STALL----------------------------
if (result & EP0_STALL) // STALL detected
break; // for unsupported request.
//----------------------OVEFLOW---------------------------
if (result & EP0_OVERFLOW) // OVERFLOW detected
break;
//-----------------------ERROR----------------------------
if (result & EP0_ERROR) //ERROR detected
break;
} //end of While(1)
if (result & EP0_ACK) // on ACK transmission
return TRUE; // return OK
return FALSE; // fail transmission
}
/*Control Endpoint 0's USB Data Xfer
ep0Xfer, endpoint 0 data transfer
*/
int ep0Xfer(BYTE usbaddr, WORD payload, pSetupPKG setup, BYTE pData)
{
BYTE xdata pid = PID_IN;
WORD xdata wLen = WordSwap(setup-wLength); //swap back for correct length
BYTE xdata ep0 = 0; // always endpoint zero
/*----------------------------------------------------
SETUP token with 8-byte request on endpoint 0
----------------------------------------------------*/
if (!usbXfer(usbaddr, ep0, PID_SETUP, 0, payload, 8, (BYTE)setup))
return FALSE;
/*----------------------------------------------------
IN or OUT data stage on endpoint 0
----------------------------------------------------*/
if (wLen) // if there are data for transfer
{
if (setup-bmRequest & 0x80) // host-to-device IN token
{
pid = PID_OUT;
if(!usbXfer(usbaddr, ep0, PID_IN, 0, payload, wLen, pData))
return FALSE;
payload = 0;
}
else // device-to-host OUT token
{
if(!usbXfer(usbaddr, ep0, PID_OUT, 0, payload, wLen, pData))
return FALSE;
}
}
/*----------------------------------------------------
Status stage IN or OUT zero-length data packet
----------------------------------------------------*/
if(!usbXfer(usbaddr, ep0, pid, 0, payload, 0, NULL))
return FALSE;
return TRUE;
}
// Control endpoint
int VendorCmd(BYTE usbaddr,BYTE bReq,BYTE bCmd,WORD wValue,WORD wIndex,WORD wLen,BYTE pData)
{
//SetupPKG xdata setup;
setup.bmRequest = bReq;
setup.bRequest = bCmd;
setup.wValue = wValue;
setup.wIndex = wIndex;
setup.wLength = WordSwap(wLen);
return ep0Xfer(usbaddr, uDev[usbaddr].wPayLoad[0], &setup, pData);
}
//Set Device Address
int SetAddress(WORD addr)
{
return VendorCmd(0,0,SET_ADDRESS, WordSwap(addr), 0, 0, NULL);
}
//Set Device Configuration
int Set_Configuration(BYTE usbaddr, WORD wVal)
{
return VendorCmd(usbaddr, 0, SET_CONFIG, WordSwap(wVal), 0, 0, NULL);
}
//Get Device Descriptor Device, Configuration, String
int GetDesc(BYTE usbaddr, WORD wValue, WORD wIndex, WORD wLen, BYTE desc)
{
return VendorCmd(usbaddr, 0x80, GET_DESCRIPTOR, wValue, wIndex, wLen, desc);
}
/*
USB Device Enumeration Process
Support 1 confguration and interface #0 and alternate setting #0 only
Support up to 1 control endpoint + 4 data endpoint only
*/
int EnumUsbDev(BYTE usbaddr)
{
int i; // always reset USB transfer address
BYTE xdata uAddr = 0; // for enumeration to Address #0
BYTE xdata epLen;
WORD xdata strLang;
/*------------------------------------------------
Reset only Slave device attached directly
------------------------------------------------*/
uDev[0].wPayLoad[0] = 64; // default 64-byte payload of Endpoint 0, address #0
if(usbaddr == 1) // bus reset for the device attached to SL811HS only
USBReset(); // that will always have the USB address = 0x01 (for a hub)
USB_Delay(25);
/*------------------------------------------------
Get USB Device Descriptors on EP0 & Addr 0
with default 64-byte payload
------------------------------------------------*/
pDev =(pDevDesc)DBUF; // ask for 64 bytes on Addr #0
if (!GetDesc(uAddr,DEVICE,0,18,DBUF)) // and determine the wPayload size
return FALSE; //get correct wPayload of Endpoint 0
uDev[usbaddr].wPayLoad[0]=pDev-bMaxPacketSize0; //on current non-zero USB address
/*------------------------------------------------
Set Slave USB Device Address
------------------------------------------------*/
if (!SetAddress(usbaddr)) //set to specific USB address
return FALSE;
uAddr = usbaddr; // transfer using this new address
/*------------------------------------------------
Get USB Device Descriptors on EP0 & Addr X
------------------------------------------------*/
if (!GetDesc(uAddr,DEVICE,0,(pDev-bLength),DBUF))
return FALSE; // For this current device
uDev[usbaddr].wVID = pDev-idVendor; //save VID
uDev[usbaddr].wPID = pDev-idProduct; // save PID
uDev[usbaddr].iMfg = pDev-iManufacturer; // save Mfg Index
uDev[usbaddr].iPdt = pDev-iProduct; //save Product Index
/*------------------------------------------------
Get String Descriptors
------------------------------------------------*/
pStr = (pStrDesc)DBUF;
if (!GetDesc(uAddr,STRING,0,4,DBUF)) // Get string language
return FALSE;
strLang = pStr-wLang; //get iManufacturer String length
if (!GetDesc(uAddr,(WORD)(uDev[usbaddr].iMfg8)STRING,strLang,4,DBUF))
return FALSE; //get iManufacturer String descriptors
if (!GetDesc(uAddr,(WORD)(uDev[usbaddr].iMfg8)STRING,strLang,pStr-bLength,DBUF))
return FALSE;
/*------------------------------------------------
Get Slave USB Configuration Descriptors
------------------------------------------------*/
pCfg = (pCfgDesc)DBUF;
if (!GetDesc(uAddr,CONFIGURATION,0,8,DBUF))
return FALSE;
if (!GetDesc(uAddr,CONFIGURATION,0,WordSwap(pCfg-wLength),DBUF))
return FALSE;
pIfc = (pIntfDesc)(DBUF + 9); // point to Interface Descp
uDev[usbaddr].bClass = pIfc-iClass; //update to class type
uDev[usbaddr].bNumOfEPs = (pIfc-bEndPoints = MAX_EP) pIfc-bEndPoints MAX_EP;
/*------------------------------------------------
Set configuration (except for HUB device)
------------------------------------------------*/
if (uDev[usbaddr].bClass!=HUBCLASS) //enumerating a FSLS non-hub device
if (!Set_Configuration(uAddr,DEVICE)) //connected directly to SL811HS
return FALSE;
/* ------------------------------------------------
For each slave endpoints, get its attributes
Excluding endpoint0, only data endpoints
------------------------------------------------*/
epLen = 0;
for (i=1; i=uDev[usbaddr].bNumOfEPs; i++) //For each data endpoint
{
pEnp = (pEPDesc)(DBUF + 9 + 9 + epLen); // point to Endpoint Descp(non-HID)
uDev[usbaddr].bEPAddr[i] = pEnp-bEPAdd; // Ep address and direction
uDev[usbaddr].bAttr[i] = pEnp-bAttr; // Attribute of Endpoint
uDev[usbaddr].wPayLoad[i] = pEnp-wPayLoad; // Payload of Endpoint
uDev[usbaddr].bInterval[i] = pEnp-bInterval; // Polling interval
uDev[usbaddr].bData1[i] = 0; //init data toggle
epLen += 7;
}
return TRUE;
}
// Full-speed and low-speed detect - Device atttached directly to SL811HS
int speed_detect()
{
SLAVE_FOUND = FALSE; //Clear USB device found flag
FULL_SPEED = TRUE; //Assume full speed device
DATA_STOP = FALSE;
SL811Write(cSOFcnt,0xAE); //Set SOF high counter, no change D+D-, host mode
SL811Write(CtrlReg,0x08); //Reset USB engine, full-speed setup, suspend disable
USB_Delay(10); //Delay for HW stablize
SL811Write(CtrlReg,0x00); // Set to normal operation
SL811Write(IntEna,0x61); // USB-A, InsertRemove, USB_Resume.
SL811Write(IntStatus,INT_CLEAR); // Clear Interrupt enable status
USB_Delay(10); // Delay for HW stablize
if(SL811Read(IntStatus)&USB_RESET)
{ //test for USB reset
SL811Write(IntStatus,INT_CLEAR); //Clear Interrupt enable status
USB_Delay(30); // Blink LED - waiting for slave USB plug-in
return 0; // exit speed_detect()
}
if((SL811Read(IntStatus)&USB_DPLUS)==0) //Checking full or low speed
{ // Low Speed is detected
SL811Write(cSOFcnt,0xEE); //Set up host and low speed direct and SOF cnt
SL811Write(cDATASet,0xE0); //SOF Counter Low = 0xE0; 1ms interval
SL811Write(CtrlReg,0x21); // Setup 6MHz and EOP enable
FULL_SPEED = FALSE; // low speed device flag
}
else
{ // Full Speed is detected
SL811Write(cSOFcnt,0xAE); // Set up host & full speed direct and SOF cnt
SL811Write(cDATASet,0xE0); // SOF Counter Low = 0xE0; 1ms interval
SL811Write(CtrlReg,0x05); // Setup 48MHz and SOF enable
}
SLAVE_FOUND = TRUE; //Set USB device found flag
SLAVE_ENUMERATED = FALSE; // no slave device enumeration
SL811Write(EP0Status,0x50); // Setup SOF Token, EP0
SL811Write(EP0Counter,0x00); //reset to zero count
SL811Write(EP0Control,0x01); // start generate SOF or EOP
USB_Delay(25); // Hub required approx. 24.1mS
SL811Write(IntStatus,INT_CLEAR); //Clear Interrupt status
return 0; // exit speed_detect();
}
//Detect USB Device
int slave_detect(void)
{
/*-------------------------------------------------------------------------
Wait for SL811HS enumeration
-------------------------------------------------------------------------*/
if(!SLAVE_ENUMERATED) //only if slave is not configured
{
speed_detect(); //wait for an USB device to be inserted to
if(SLAVE_FOUND) //the SL811HST host
{
if(EnumUsbDev(1)) //enumerate USB device, assign USB address = #1
{
SLAVE_ENUMERATED = TRUE; //Set slave USB device enumerated flag
}
}
}
/*-------------------------------------------------------------------------
SL811HS enumerated, proceed accordingly
-------------------------------------------------------------------------*/
else
{
if(Slave_Detach()) // test for slave device detach
return 0; // exit now.
} end of else
return 0;
}
//Slave_Detach
int Slave_Detach(void)
{
if( (SL811Read(IntStatus)&INSERT_REMOVE) (SL811Read(IntStatus)&USB_RESET) )
{ //Test USB detached
SLAVE_ENUMERATED = FALSE; //return to un-enumeration
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
return TRUE; // exit now !!!
}
return FALSE;
}
//SL811H variables initialization
void sl811h_init(void)
{
SL811H_DATA = 0x00;
SL811H_ADDR = 0x00;
FULL_SPEED = TRUE;
SLAVE_FOUND = FALSE;
SLAVE_ENUMERATED = FALSE;
}
void USB_Delay(int time) //time 单位为 ms
{
unsigned char j;
j=0xa3;
while(time--)
while(--j);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -