?? host_811.c
字號:
//#include "host_811.h"
#include "44b.h"
#include <stdlib.h>
#include "USB_SYS.h"
//*****************************************************************************************
// SL811H Modules (major routines only):
//*****************************************************************************************
// 1) usbXfer() : handles usd data transfer, SETUP,IN, OUT
// 2) ep0Xfer() : handles endpoint zero control pipe
// 3) DataRW() : handles data endpoint transfer pipe
// 4) EnumUsbDev() : device enum(HID/HUB), excl. multi-interface
// 6) speed_detect(): SL811H slave device attach/speed detect
// 7) slave_detect(): Main loop control between SL811H & EZUSB & GUI
//*****************************************************************************************
//variables
//*****************************************************************************************
//
BYTE DBUF[512]; // at 0x2000 for general descriptors data//~~~做什么用的?
BYTE remainder; // Remaining byte in a USB transfer
pUSBDEV uDev[MAX_DEV]; // Multiple USB devices attributes, Max 5 devices//~~Max 2 吧?
pDevDesc pDev; // Device descriptor struct
pCfgDesc pCfg; // Configuration descriptor struct
pIntfDesc pIfc; // Interface descriptor struct
pEPDesc pEnp; // Endpoint descriptor struct
pStrDesc pStr; // String descriptor struct
//*****************************************************************************************
// Boolean Logic Defines//~~arm不支持布爾類型,用byte類型代替
//*****************************************************************************************
BYTE SLAVE_FOUND; // Slave USB device found
BYTE SLAVE_ENUMERATED; // slave USB device enumeration done
BYTE FULL_SPEED; // Full-Speed = TRUE, Low-Speed = FALSE
BYTE BULK_OUT_DONE; // Set when EZUSB's OUT1 hostcmd xfer is done
BYTE DESC_XFER; // Set when there is data for EZUSB's IN1 desc xfer
BYTE DATA_XFER; // Set when there is data for EZUSB's IN3 data xfer
BYTE DATA_XFER_OUT; // Set when there is data for EZUSB's OUT3 data xfer
BYTE CONFIG_DONE; // Set when EZUSB completes its enumeration process.
BYTE TIMEOUT_ERR; // timeout error during data endpoint transfer
BYTE DATA_STOP; // device unplugged during data transfer
BYTE DATA_INPROCESS; // set when we are in a data pipe transfer
BYTE pLS_HUB; // indicate previous command is a LS device on hub
BYTE bData1; //~~標識是data0還是data1
//*****************************************************************************************
// Byte Read from SL811H
// a = register address
// return = data in register
//*****************************************************************************************
BYTE SL811Read(BYTE a)
{
SL811H_ADDR = a;
return (SL811H_DATA);
}
//*****************************************************************************************
// Byte Write to SL811H
// a = register address
// d = data to be written to this register address
//*****************************************************************************************
void SL811Write(BYTE a, BYTE d)
{
SL811H_ADDR = a;
SL811H_DATA = d;
}
//*****************************************************************************************
// Buffer Read from SL811H
// addr = buffer start address
// s = return buffer address where data are to be save/read
// c = buffer data length
//*****************************************************************************************
void SL811BufRead(BYTE addr, BYTE *s, BYTE c)
{
SL811H_ADDR = addr;
while (c--)
{
USB_Delay(1);
*s++ = SL811H_DATA;}
}
//*****************************************************************************************
// Buffer Write to SL811H
// addr = buffer start address
// s = buffer address where data are to be written
// c = buffer data length
//*****************************************************************************************
void SL811BufWrite(BYTE addr, BYTE *s, BYTE c)
{
SL811H_ADDR = addr;
while (c--)
{
USB_Delay(1);
SL811H_DATA = *s++;}
}
//*****************************************************************************************
// UsbReset during enumeration of device attached directly to SL811HS
//*****************************************************************************************
void USBReset()
{
BYTE tmp;
tmp = SL811Read(CtrlReg);
SL811Write(CtrlReg,tmp|0x08);
USB_Delay(5);
SL811Write(CtrlReg,tmp);
}
//*****************************************************************************************
// usbXfer:
// successful transfer = return TRUE
// fail transfer = return FALSE
// 此函數完成setup/in/out事務的傳輸; 相當重要的usb 傳輸函數
//*****************************************************************************************
int usbXfer(BYTE usbaddr, BYTE endpoint, BYTE pid, BYTE iso, WORD wPayload, WORD wLen, BYTE *buffer)
{
//~~usbaddr設備號(udev的數組元素標號),endpoint是端點號,pid是包標識符
//~~wlen是發送接收數據長度,buffer是數據緩沖區,wpayload是最大載荷,是811中緩沖區長度
BYTE cmd, result, timeout, intr;
//~~cmd寫給EP0Control的值,result是ep0中斷后EP0Status的值,intr是讀取IntStatus的值
BYTE xferLen, bufLen, data0, data1, dataX, addr; //~~去掉xdata
//~~xferlen是每次實際傳送的數據長度,data0/1是811中data0/1的緩沖區地址,
//~~buflen記錄buffer中數據傳送到哪個位子了
//~~addr記錄第二次以后的傳送是data0的buffer還是data1的buffur
//~~datax是幫助addr確定本次傳送是data0的buffer中的數據還是data1的buffer中的數據
//------------------------------------------------
// Default setting for usb trasnfer
//------------------------------------------------
bufLen = dataX = timeout = 0; //reset all
data0 = EP0_Buf; // DATA0 buffer address
data1 = data0 + (BYTE)wPayload; // DATA1 buffer address
DATA_STOP = TIMEOUT_ERR = FALSE; // set default conditions//~~本來為bool類型
//------------------------------------------------
// Define data transfer payload
//~~如果要傳輸的數據長度大于相應端點的最大包尺寸就先發送最大包長度的數據
//------------------------------------------------
if (wLen >= wPayload) // select proper data payload
xferLen = wPayload; // limit to wPayload size
else // else take < payload len
xferLen = wLen; //
//------------------------------------------------
// For IN token
//------------------------------------------------
if (pid==PID_IN) // for current IN tokens
{
if(FULL_SPEED)
cmd = sDATA0_RD; // FS/FS on Hub, sync to sof//~~原來為sDATA0_RD
else // LS, no sync to sof for IN
cmd = DATA0_RD;
//Uart_Printf("%x\n",cmd);
}
//------------------------------------------------
// For OUT token
//------------------------------------------------
else if(pid==PID_OUT) // for OUT tokens
{
if(xferLen) // only when there are
SL811BufWrite(data0,buffer,xferLen); // data to transfer on USB
if(FULL_SPEED)
cmd = sDATA0_WR; // FS/FS on Hub, sync to sof//~~原來為sDATA0_WR
else // LS, no sync to sof for OUT
cmd = DATA0_WR;
// implement data toggle
bData1 = uDev[usbaddr].bData1[endpoint];//~~bdata1是bool型,標示data0還是data1
uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint] ? 0 : 1); // DataToggle
if(bData1)
cmd |= 0x40; // Set Data1 bit in command
}
//------------------------------------------------
// For SETUP/OUT token
//------------------------------------------------
else // for current SETUP/OUT tokens
{
if(xferLen)
SL811BufWrite(data0,buffer,xferLen); // data to transfer on USB
if(FULL_SPEED)
cmd = sDATA0_WR; // FS/FS on Hub, sync to sof//~~原來為sDATA0_WR
else // LS, no sync to sof for OUT
cmd = DATA0_WR;
}
//------------------------------------------------
// Isochronous data transfer setting
//------------------------------------------------
if (iso)
cmd |= ISO_BIT; // if iso setup ISO mode
//------------------------------------------------
// For EP0's IN/OUT token data, start with DATA1
// Control Endpoint0's status stage.
// For data endpoint, IN/OUT data, start ????
//------------------------------------------------
if (endpoint == 0 && pid != PID_SETUP) // for Ep0's IN/OUT token
//~~端點0時說明是控制傳輸,并且不是setup包,那么肯定先傳輸data1
cmd |= 0x40; // always set DATA1
//Uart_Printf("%x\n",cmd);
//------------------------------------------------
// Arming of USB data transfer for the first pkt
//------------------------------------------------
SL811Write(EP0Status,((endpoint&0x0F)|pid)); // PID + EP address
SL811Write(EP0Counter,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
//Uart_Printf("%x\n",SL811Read(EP0Control));
//------------------------------------------------
// 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
//Uart_Printf("%x",intr);
if((intr & USB_RESET) || (intr & INSERT_REMOVE)) // proceed to parse result from slave
{ // device.
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)
break; // interrupt done !!!
}
SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
result = SL811Read(EP0Status);
//Uart_Printf("%x\n",result); // read EP0status register
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -