📄 sl811hs_appnote.txt
字号:
4.1.15 Resume Wakeup
Devices that are in suspend state because of lack of USB activity, will be forced to resume operation when the SL811HS resumes SOF transmission. The SL811HS will do the following:
-Enable SOF generation
-Disable Suspend states
-Starts normal operation
Program Sample 14: Resume Wakeup
...
USBReset(10); // Do USB_RESET
Cypress Semiconductor Corporation
SL811HS and SL811HST: Application Notes
// Generate SOF, setup 48Mhz, suspend disable
SL11Write(CtrlReg, 0x01);
...
4.1.16 Specific Command Transfer
This subroutine is similar to the DeviceIoControl in the Window Driver Model. See the USB specification v1.1, chapter 9 for more details.
Program Sample 15: Vendor Command
The VendorCmd () setup specific request parameters to the USB devices.
Program Sample 16: Vendor Command
//--------------------------------------------------------------------
// Control endpoint
// return:
// -1 on failure, 0 on success > 0 if remainder
//---------------------------------------------------------------------
int VendorCmd(BYTE bReq, BYTE bCmd, WORD wValue, WORD wIndex,
WORD wLen,BYTE* pData)
{
SetupPKG setup;
setup.bmRequest = bReq;
setup.bRequest = bCmd;
setup.wValue = wValue;
setup.wIndex = wIndex;
setup.wLength = wLen;
return ep0Xfer(uDev.wEPxCRC[0], uDev.wPayLoad[0], &setup, pData);
}
4.1.17 USB Transfer (Bulk/ISO/Control/Interrupt)
The following subroutines simulate the Micro USBD stack function on the top level.
Program Sample 17: USB Control Transfer
//---------------------------------------------------------------------
// ep0Xfer
// Dev contains the CRC of EP | Address
// Return:
// - Fail -1
// - Sucess 0
// - non-zero remainder (0 < wLen < setup->wLength)
//
//---------------------------------------------------------------------
int ep0Xfer(WORD Dev, WORD payload, PSetupPKG setup, BYTE *pData)
{
BYTE pid=PID_IN;
WORD wLen = setup->wLength;
Cypress Semiconductor Corporation
SL811HS and SL811HST: Application Notes
if (usbXfer(Dev, PID_SETUP, 0, payload, 8, (BYTE*)setup)==-1)
return FALSE;
if (wLen)
{
if (setup->bmRequest & 0x80)
{
pid = PID_OUT;
wLen = (WORD)usbXfer(Dev, PID_IN, 0, payload, wLen, pData);
payload =0;
}
else
wLen = (WORD)usbXfer(Dev, PID_OUT, 0, payload, wLen, pData);
}
usbXfer(Dev, pid, 0, payload, 0, NULL);
return wLen >= 0; // return remainder
}
4.1.18 Device Enumeration
The function FindUsbDev () is used to enumerate full speed devices or Hub. The process of Enumeration includes Get_Descriptor, Set_Address, Get_Configuration, and Set_Configuration. This is standard USB Device enumeration for all full/low devices or Hubs.
Program Sample 18: Device Enumeration
The complete code is in the SL811HR.C Does this software exist and does it come standard with the SL811HS DVK? Otherwise, it should either not be here at all or this software should be made available for the SL811HS DVK.
Program Sample 19: Device Enumeration
//--------------------------------------------------------------------
// Find Full Speed USB Device
//--------------------------------------------------------------------
int FindUsbDev(short DevNum)
{
pDevDesc pDev;
pConfDesc pConf;
pIntfDesc pIntf;
int i,j;
BYTE *p, *ep;
sEPDesc sEP;
if (DevNum==1) USBReset(); // root hub
uDev.wEPxCRC[0] = crc5(0); // address = 0, endpoint = 0
uDev.wPayLoad[0] = 8;
printf("Get Device Descriptor: .. \n");
pDev = (pDevDesc)SCMD;
if (!GetDesc(DEVICE<<8,0x40,(BYTE*)SCMD)) return FALSE;
printf("Set Address: %x ", DevNum);
if (!SetAddress(DevNum)) return FALSE;
printf("len=%02x ep0Len=%d\n", pDev->bLength, pDev->bMaxPacketSize0);
uDev.wPayLoad[0] = (pDev->bMaxPacketSize0&0xff)?pDev->bMaxPacketSize0:8;
printf("Get Device Descriptor: ..");
uDev.wEPxCRC[0] = crc5((WORD)(DevNum+(0<<7)));// Endpoint 0 |assign new addr
if (!GetDesc(DEVICE<<8,0x09, (BYTE*)SCMD)) return FALSE;
printf("Vendor: %04x Product: %04x\n",pDev->idVendor,pDev->idProduct);
uDev.wVID = pDev->idVendor;
uDev.wPID = pDev->idProduct;
printf("Get Configuration\n");
if (!GetDesc(CONFIGURATION<<8,0xff, (BYTE*)SCMD)) return FALSE;
if (!GetDesc(CONFIGURATION<<8,0x12, (BYTE*)SCMD)) return FALSE;
if (!GetDesc(CONFIGURATION<<8,0x09, (BYTE*)SCMD)) return FALSE;
if (!GetDesc(CONFIGURATION<<8,0x20, (BYTE*)SCMD)) return FALSE;
pConf = (pConfDesc)SCMD;
//printf("Len=%d, type: %02x\n", pConf->wLength, pConf->bType);
//printf("Set Configuration\n");
if (!Set_Configuration(DEVICE)) return FALSE;
p = (BYTE*)SCMD;
i = *p;
pIntf = (pIntfDesc)&p[i]; // point to Interface Desc
p = (BYTE*)&p[i+pIntf->bLength]; // point to EP Desc
printf("Number of Endpoint = %d\n",pIntf->bEndPoints);
uDev.bNumOfEPs = pIntf->bEndPoints;
if (uDev.bNumOfEPs > cMaxEP) return FALSE;
ep = (BYTE*)&sEP;
for (i=1; i <= pIntf->bEndPoints; i++)
{
uDev.wEPxCRC[i] = crc5((WORD)(DevNum+(i<<7))); // Endpoint CRC
for (j=0; j<7; j++) ep[j] = *p++;
if (sEP.bEPAdd&0x80) Rd_EP = sEP.bEPAdd&0xf; // index of Read EP
else Wr_EP = sEP.bEPAdd;
uDev.bEPAddr[i] = sEP.bAttr;
uDev.wPayLoad[i] = sEP.wPayLoad;
printf("Length %x Type %x EndPoint Addr %02x Attr %02x wLength=%04x\n",
sEP.bLength, sEP.bType, sEP.bEPAdd, sEP.bAttr, sEP.wPayLoad);
DToggle[i] = 0;
}
printf("Write Endpoint %d, Read Endpoint %d\n", Wr_EP, Rd_EP);
return TRUE;
}
5. SL811HS USB TRANSFER
The UsbXfer() subroutine handles USB packet transactions. It supports ping-pong operation for SETUP, PID_IN and PID_OUT Tokens. This code is currently designed to support Control pipe, Bulk Data Pipe. This code can be expanded to support ISO and Interrupt endpoints.
The usbXfer() handles USB Transactions. It will report USBStatus register contents:
//--------------------------------------------------------------------------
// usbXfer:
// NOTE: The CRC contains Device 4-bit of EndPoint Number | 7-bit of Device Addr
// iso = 1 transfer with ISO mode, else Bulk/Interrupt/Control
// return 0 on Success
//
// USB Status
// 0x01 ACK
//
0x02
Device Error Bit
//
0x04
Device Time out
//
0x08
Toggle bit
//
0x10
SET_UP packet bit
(Not used in SL11H)
//
0x20
Overflow bit
//
0x40
Device return NAKs, forever
//
0x80
Device return STALL
// need to keep track DATA0 and DATA1 for write endpoint
//--------------------------------------------------------------------------
int usbXfer(WORD crc, BYTE pid, BYTE iso, WORD payload, int len, BYTE *buf)
{
short result, bLen, rLen, time_out, data0, data1, D0, ep;
WORD retry;
BYTE Cmd=DATA0_RD, addr, rem, pl;
extern short dbug;
if (dbug) pl = payload + 24; // low speed debug
else pl = (payload>>3) + 3;
ep = (crc>>7) & 0xf;
data0 = cMemStart;
#ifdef SL811H
SL11Write(EP0Status, (BYTE)( (pid << 4) + ep ) );
SL11Write(EP0Counter, (BYTE)(crc & 0x7f));
#ifdef REV13
if (dbug && pid==PID_IN) // handle low speed via Hub
{
SL11Write(EP1Status, 0xc0);
SL11Write(EP1XferLen, 0);
}
#endif
#else
SL11Write(data0,pid); // PID
SL11BufWrite((short)(data0+1),(BYTE*)&crc, 2); // 2 bytes CRC
#endif
if (len>=(int)payload)
{ // setup ping pong buffer
data1 = data0 + payload + cOFFSET; // next buffer
#ifndef SL811H
SL11Write(data1,pid); // PID
SL11BufWrite((short)(data1+1),(BYTE*)&crc,2);
#endif
rLen = payload;
}
else
rLen = (short)len;
SL11Write(EP0XferLen,(BYTE)(cOFFSET+rLen)); // setup 3-byte header + payload
SL11Write(EP0Address, (BYTE)data0); // DATA0
#ifndef SL811H
if (pid == PID_SOF) // Send Software SOF
{
SL11Write(EP0Control, 1); // arm and return
return len;
}
#endif
if (iso) Cmd |= ISO_BIT; // if iso setup ISO mode
if (pid != PID_IN)
{ SL11BufWrite((short)(data0+cOFFSET),buf, rLen); // DATA to SL11 Memory
Cmd = DATA0_WR;
}
if (ep==0 && pid != PID_SETUP) Cmd |= 0x40; else Cmd |= DToggle[ep];
retry = 1; rem = time_out = result = D0 = 0;
Cmd |= dbug; // set PRE for low speed
while (1)
{
if (retry>0)
{
SL11Write(IntStatus,0xff);
if (full_speed)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -