在BOOL DR_VendorCmnd(void)函数里的switch(SETUPDAT[1])中的SETUPDAT[1]与WINDOWS API的
SetupPacket.bRequest = ReqCode;//SETUPDAT[1]对应。
SETUPDAT数组总共8个字节,SETUPDAT[0:7]分别与PC API 的SetupPacket结构相对应。
SetupPacket的结构定义如下:
typedef struct _SETUP_PACKET {
union {//对应SETUPDAT[0]
BM_REQ_TYPE bmReqType;
UCHAR bmRequest;
};
UCHAR bRequest;//对应SETUPDAT[1]
union { //对应SETUPDAT[2:3]
WORD_SPLIT wVal;
USHORT wValue;
};
union {//对应SETUPDAT[4:5]
WORD_SPLIT wIndx;
USHORT wIndex;
};
union {//对应SETUPDAT[6:7]
WORD_SPLIT wLen;
USHORT wLength;
};
ULONG ulTimeOut;//这个参数用于API超时检测,不传输到下位机。
} SETUP_PACKET, *PSETUP_PACKET;
赋值例子:
SetupPacket.bmRequest = bmReq; //SETUPDAT[0]
SetupPacket.bRequest = ReqCode;//SETUPDAT[1]
SetupPacket.wValue = Value;//SETUPDAT[2:3]
SetupPacket.wIndex = Index;//SETUPDAT[4:5]
SetupPacket.wLength = bufLen;//SETUPDAT[6:7]
SetupPacket.ulTimeOut = TimeOut / 1000;
通过EP0的VENDER指令读写数据:
1、PC->EP0写数据。
使用数据前要进行:
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
//清零计数以允许新的数据进来,同时停止 NAKing
否则读取不了正确的数据。
/////////////////自定义指令//////////////////////////////
case 0XB0://B0写LED数码管
// Arm endpoint - do it here to clear (after sud avail)
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
//清零计数以允许新的数据进来,同时停止 NAKing
while(EP0CS & bmEPBUSY);
I2C_WriteByte(LED_ADDR,EP0BUF[0]);
break;
2、PC->EP0读数据。
直接给EP0BUF赋值,传输字节数量赋值,然后EP0CS |= bmHSNAK; 即可。
case 0XB1://B1读按键
*EP0BUF = I2C_ReadByte(BTN_ADDR);
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
BOOL DR_VendorCmnd(void)
{
WORD addr, len, bc;
WORD ChipRev;
WORD i;
// Determine I2C boot eeprom device address; addr = 0x0 for 8 bit addr eeproms (24LC00)
I2C_Addr = SERIAL_ADDR | ((I2CS & 0x10) >> 4); // addr=0x01 for 16 bit addr eeprom (LC65)
// Indicate if it is a dual byte address part
DB_Addr = (BOOL)(I2C_Addr & 0x01); //TPM: ID1 is 16 bit addr bit - set by rocker sw or jumper
switch(SETUPDAT[1])
{ /////////////////自定义指令/////////////////////////////////
case 0XB0://B0写LED数码管
// Arm endpoint - do it here to clear (after sud avail)
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
//清零计数以允许新的数据进来,同时停止 NAKing
while(EP0CS & bmEPBUSY);
I2C_WriteByte(LED_ADDR,EP0BUF[0]);
break;
case 0XB1://B1读按键
*EP0BUF = I2C_ReadByte(BTN_ADDR);
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
////////////////////////////////////////////
//TPM handle new commands
case VR_GET_CHIP_REV:
ChipRev = GET_CHIP_REV();
*EP0BUF = ChipRev;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
break;
case VR_I2C_100:
I2CTL &= ~bm400KHZ;
EP0BCH = 0;
EP0BCL = 0;
break;
case VR_I2C_400:
I2CTL |= bm400KHZ;
EP0BCH = 0;
EP0BCL = 0;
break;
case VR_RENUM:
*EP0BUF = 7;
EP0BCH = 0;
EP0BCL = 1; // Arm endpoint with # bytes to transfer
EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
EZUSB_Delay(1000);
EZUSB_Discon(TRUE); // renumerate until setup received
break;
case VR_DB_FX:
DB_Addr = 0x01; //TPM: need to assert double byte
I2C_Addr |= 0x01; //TPM: need to assert double byte
addr = SETUPDAT[2]; // Get address and length
addr |= SETUPDAT[3] << 8;
len = SETUPDAT[6];
len |= SETUPDAT[7] << 8;
// Is this an upload command ?
if(SETUPDAT[0] == VR_UPLOAD)
{
while(len) // Move requested data through EP0IN
{ // one packet at a time.
while(EP0CS & bmEPBUSY);
if(len < EP0BUFF_SIZE)
bc = len;
else
bc = EP0BUFF_SIZE;
for(i=0; i<bc; i++)
*(EP0BUF+i) = 0xcd;
EEPROMRead(addr,(WORD)bc,(WORD)EP0BUF);
EP0BCH = 0;
EP0BCL = (BYTE)bc; // Arm endpoint with # bytes to transfer
addr += bc;
len -= bc;
}
}
// Is this a download command ?
else if(SETUPDAT[0] == VR_DOWNLOAD)
{
while(len) // Move new data through EP0OUT
{ // one packet at a time.
// Arm endpoint - do it here to clear (after sud avail)
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
while(EP0CS & bmEPBUSY);
bc = EP0BCL; // Get the new bytecount
EEPROMWrite(addr,bc,(WORD)EP0BUF);
addr += bc;
len -= bc;
}
}
break;
case VR_RAM:
// NOTE: This case falls through !
case VR_EEPROM:
DB_Addr = 0x00; //TPM: need to assert double byte
I2C_Addr |= 0x00; //TPM: need to assert double byte
addr = SETUPDAT[2]; // Get address and length
addr |= SETUPDAT[3] << 8;
len = SETUPDAT[6];
len |= SETUPDAT[7] << 8;
// Is this an upload command ?
if(SETUPDAT[0] == VR_UPLOAD)
{
while(len) // Move requested data through EP0IN
{ // one packet at a time.
while(EP0CS & bmEPBUSY);
if(len < EP0BUFF_SIZE)
bc = len;
else
bc = EP0BUFF_SIZE;
// Is this a RAM upload ?
if(SETUPDAT[1] == VR_RAM)
{
for(i=0; i<bc; i++)
*(EP0BUF+i) = *((BYTE xdata *)addr+i);
}
else
{
for(i=0; i<bc; i++)
*(EP0BUF+i) = 0xcd;
EEPROMRead(addr,(WORD)bc,(WORD)EP0BUF);
}
EP0BCH = 0;
EP0BCL = (BYTE)bc; // Arm endpoint with # bytes to transfer
addr += bc;
len -= bc;
}
}
// Is this a download command ?
else if(SETUPDAT[0] == VR_DOWNLOAD)
{
while(len) // Move new data through EP0OUT
{ // one packet at a time.
// Arm endpoint - do it here to clear (after sud avail)
EP0BCH = 0;
EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
while(EP0CS & bmEPBUSY);
bc = EP0BCL; // Get the new bytecount
// Is this a RAM download ?
if(SETUPDAT[1] == VR_RAM)
{
for(i=0; i<bc; i++)
*((BYTE xdata *)addr+i) = *(EP0BUF+i);
}
else
EEPROMWrite(addr,bc,(WORD)EP0BUF);
addr += bc;
len -= bc;
}
}
break;
}
return(FALSE); // no error; command handled OK
}