📄 host2131.c
字号:
#pragma NOIV // Do not generate interrupt vectors
////////////////////////////////////////////////////////////////////////////////
// File: host2131.c
// Purpose: 8051 firmware to master SL811 Embedded Host.
// Derived from periph.c frameworks file.
// Contains USB peripheral-related firmware.
// Contains PC host command interface.
// Based on SL811HST code written by cxn.
//
// $Header: /USB/ez811/firmware/Emb_Host/host2131.c 8 5/17/02 6:09p Tpm $
// Copyright (c) 2002 Cypress Semiconductor. May not be reproduced without permission.
// See the license agreement for more details.
////////////////////////////////////////////////////////////////////////////////
#include "ezusb.h"
#include "ezregs.h"
#include "host_811.h"
extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;
extern BOOL SLAVE_ENUMERATED;
extern BOOL BULK_OUT_DONE;
extern BOOL DESC_XFER;
extern BOOL DATA_XFER;
extern xdata BYTE DataBufLen;
extern xdata BYTE DBUF[];
extern xdata BYTE HOSTCMD[];
extern xdata BYTE REGBUFF[];
extern xdata BYTE remainder;
extern void sl811h_init(void);
extern int slave_detect(void);
extern BOOL CONFIG_DONE;
extern BOOL DATA_XFER_OUT;
extern xdata BYTE DBUFOut[];
extern BOOL dsPoll;
extern BOOL bDataToggle;
extern xdata pDevDesc pDev; // Device descriptor struct
extern xdata pCfgDesc pCfg; // Config descriptor struct
extern xdata pStrDesc pStr; // String descriptor struct
extern xdata pHidDesc pHid; // HID class descriptor struct
extern xdata pHubDesc pHub; // HUD class descriptor struct
extern xdata pIntfDesc pIfc; // Interface descriptor struct
extern xdata pHUBDEV uHub; // Struct for downstream device on HUB
extern xdata pUSBDEV uDev[]; // Multiple USB devices attributes, Max 5 devices
void dsOut(void);
int DataRW(BYTE usbaddr, BYTE epaddr, WORD wPayload, WORD wLen, BYTE *pData);
WORD GetDevInfo(BYTE *DevInfo);
int desc_next;
int data_next;
void TD_Poll(void);
BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------
// IN2 => 1 bytes max, Refresh data update from ezusb to host
//-----------------------------------------------------------------------------
void TD_Init(void) // Called once at startup
{
Rwuen = TRUE; // Enable remote-wakeup
ISOCTL |= 0x01; // free up iso endpoints for external data space (1024)
IN07VAL |= bmEP1; // Enable endpoint 1 IN
IN07VAL |= bmEP2; // Enable endpoint 2 IN
IN07VAL |= bmEP3; // Enable endpoint 3 IN
OUT07VAL |= bmEP1; // Enable endpoint 1 OUT
OUT07IEN |= bmEP1; // Enable endpoint 1 OUT interrupt
OUT1BC = 0; // Arm Endpoint 1 OUT to recieve data
OUT07VAL |= bmEP3; // Enable endpoint 3 OUT
OUT07IEN |= bmEP3; // Enable endpoint 3 OUT interrupt
OUT3BC = 0; // Arm Endpoint 3 OUT to recieve data
BPADDR = (WORD)TD_Poll; // Setup breakpoint to trigger on TD_Poll()
USBBAV |= bmBPEN; // Enable the breakpoint
USBBAV &= ~bmBPPULSE;
sl811h_init(); // setup SL811H chip variables
desc_next = 0;
data_next = 0;
}
//*****************************************************************************************
// ENDPOINT FUNCTION :
// EP2-IN -> Return a byte of 0x01 to ezusb host to indicate a attach/detach for refresh
//*****************************************************************************************
void TD_Poll(void)
{
int i,count;
BYTE DescBufLen; // EZUSB's IN #1 descriptor buffer length
slave_detect(); // Poll for any slave USB device attached to "SL811HS" Embedded Host
if(BULK_OUT_DONE && !DESC_XFER)
{
BULK_OUT_DONE = FALSE;
switch(HOSTCMD[0]) // type of commands from EZUSB host
{
case SL_REFRESH:
DescBufLen = GetDevInfo(DBUF);
if(!DescBufLen)
{ // there is nothing to transfer - keep the host app from pending
DBUF[0] = 0;
DescBufLen = 1; // arming the IN1 is done in the slave_detect loop
}
DESC_XFER = TRUE; // set DESC_XFER to start transfer
break;
default: break; // default break;
}
}
if(DESC_XFER && !(IN1CS & bmEPBUSY))
{ // ensure DESC_XFER & IN1 not busy
if(DescBufLen) // check for any data length
{ //
count = (int)((DescBufLen>=64) ? 64:DescBufLen); // select data length, max allowed is 64 bytes
for(i=0; i<count; i++) // copy data into IN buffer
IN1BUF[i] = DBUF[i+desc_next]; //
IN1BC = count; // arm IN data transfer
DescBufLen -= count; // update remaining data len
desc_next += count;
if(!DescBufLen)
{
desc_next = 0;
DESC_XFER = FALSE; // reset DESC_XFER to stop transfer
}
}
}
}
//---------------------------------------
BOOL TD_Suspend(void) // Called before the device goes into suspend mode
{
return(TRUE);
}
BOOL TD_Resume(void) // Called after the device resumes
{
return(TRUE);
}
//-----------------------------------------------------------------------------
// Device Request hooks
// The following hooks are called by the end point 0 device request parser.
//-----------------------------------------------------------------------------
BOOL DR_GetDescriptor(void)
{
return(TRUE);
}
BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received
{
Configuration = SETUPDAT[2];
CONFIG_DONE = TRUE;
return(TRUE); // Handled by user code
}
BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received
{
IN0BUF[0] = Configuration;
EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
return(TRUE); // Handled by user code
}
BOOL DR_SetInterface(void) // Called when a Set Interface command is received
{
AlternateSetting = SETUPDAT[2];
return(TRUE); // Handled by user code
}
BOOL DR_GetInterface(void) // Called when a Set Interface command is received
{
IN0BUF[0] = AlternateSetting;
EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
return(TRUE); // Handled by user code
}
BOOL DR_GetStatus(void)
{
return(TRUE);
}
BOOL DR_ClearFeature(void)
{
return(TRUE);
}
BOOL DR_SetFeature(void)
{
return(TRUE);
}
#define EP0BUFF_SIZE 0x40
BOOL DR_VendorCmnd(void)
{
WORD addr, len, bc;
BYTE EpAddr, EpIdx;
WORD i;
BYTE RegAddr;
xdata BYTE OUT_DATA[EP0BUFF_SIZE]; // OUT data buffer
int retDataRW = FALSE;
BYTE DescBufLen = 0;
WORD ReqLen = 0;
switch(SETUPDAT[1])
{ // NOTE" 0xA0 is reserved: 0xA0 = Anchor Download (handled by core)
case SL_RESET:
{
sl811h_init(); // initialize SL811HST
*IN0BUF = SETUPDAT[1]; // return command type
IN0BC = 0x01; // arm endp, # bytes to xfr
EP0CS |= bmBIT1; // ack handshake phase of device request
break;
}
case SL_DEVICE_DESCP: // GetDevDesc
case SL_CONFIG_DESCP: // GetConfDesc
case SL_CLASS_DESCP: // GetClassDesc
case SL_STRING_DESCP: // GetStringDesc
{
EpAddr = SETUPDAT[2]; // Get address
ReqLen = SETUPDAT[6];
ReqLen |= SETUPDAT[7] << 8; // Get requested length
if(SETUPDAT[1] == SL_DEVICE_DESCP)
{
pDev =(pDevDesc)DBUF;
if(GetDesc(EpAddr,DEVICE,0,18,DBUF)) // Device Descp - 18 bytes
DescBufLen = (WORD)pDev->bLength; // update buffer length
}
if(SETUPDAT[1] == SL_CONFIG_DESCP)
{
pCfg =(pCfgDesc)DBUF;
if (GetDesc(EpAddr,CONFIGURATION,0,255,DBUF))
DescBufLen = WordSwap(pCfg->wLength);
}
if(SETUPDAT[1] == SL_CLASS_DESCP)
{
if (GetDesc(EpAddr,CONFIGURATION,0,255,DBUF)) // Configuration Descp
{
pIfc = (pIntfDesc)(DBUF + 9); // point to Interface Descp
if(pIfc->iClass==HIDCLASS) // HID_CLASS
{
pHid = (pHidDesc)(DBUF + 9 + 9); // get HID's report descriptor
DescBufLen = (pHid->wItemLength <= 255) ? pHid->wItemLength : 255;
if(!GetHid_Desc(EpAddr,HID_REPORT,DescBufLen,DBUF))
DescBufLen = 0;
}
else if(pIfc->iClass==HUBCLASS) // HUB_CLASS
{
pHub =(pHubDesc)DBUF; // get HUB class descriptor
DescBufLen = (pHub->bLength <= 255) ? pHub->bLength : 255;
if(!GetHubDesc(EpAddr,0,9,DBUF))
DescBufLen = 0;
}
else
DescBufLen = 0; // Undefined Class
}
}
if(SETUPDAT[1] == SL_STRING_DESCP)
{
pStr = (pStrDesc)DBUF;
pStr->bLength = 0;
if(GetDesc(EpAddr,(WORD)(0x02<<8)|STRING,0x0904,4,DBUF))
{ // get iManufacturer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -