📄 usbstd.c
字号:
}
else {
// deconfiguring, device must transition to addressed state
byUsbConfig = 0; // clear configuration
}
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
void StdDev_GetStatus(void) {
BYTE TmpBuf[2] = {0x00, 0x00};
// get device status (device), 1000 0000 = 0x80, { 0x80, 0x00 }
D11_WrEp(D11_EP0IN_IDX, TmpBuf, 2); // Tx Endpoint Status Packet
}
void StdDev_GetDescr(PUSB_REQUEST pSetupPkt) {
// Get Standard Device Descriptor
// 0x80, 0x06
switch(HIBYTE(pSetupPkt->wValue)) {
case 0x01:
// get device descriptor (device)
printf("(device) %d ", pSetupPkt->wLength);
pbyTxCtl = (BYTE *)&DeviceDescr;
USB_CtlTx(pSetupPkt->wLength, (WORD)DeviceDescr.bLength);
break;
case 0x02:
// get configuration descriptor
printf("(configuration) %d ",pSetupPkt->wLength);
pbyTxCtl = (BYTE *)&UsbCfgData.ConfigDescr;
USB_CtlTx(pSetupPkt->wLength, SWAPWORD(UsbCfgData.ConfigDescr.wTotalLength));
break;
case 0x03:
// get standard device string descriptor
// wIndex contains language identifier (ignore for now)
// wValue contains both the Descriptor Type (Upper 8 bits)
// and the Descriptor Index (lower 8 bits)
printf("(string) - %x", LOBYTE(pSetupPkt->wValue));
switch(LOBYTE(pSetupPkt->wValue)) {
case 0x00:
// requesting array of supported language id's
// point to Language Descriptor structure
pbyTxCtl = (BYTE *)&StrDescLanguage;
USB_CtlTx(pSetupPkt->wLength, (WORD)StrDescLanguage.bLength);
break;
case 0x01:
// requesting manufacturers identification string
// point to Manufacturers identification string
pbyTxCtl = (BYTE *)&StrDescManufacturer;
USB_CtlTx(pSetupPkt->wLength, (WORD)StrDescManufacturer.bLength);
break;
case 0x02:
// requesting product identification string
// point to Product identification string
pbyTxCtl = (BYTE *)&StrDescProduct;
USB_CtlTx(pSetupPkt->wLength, (WORD)StrDescProduct.bLength);
break;
case 0x03:
// requesting configuration identification string
// point to Product identification string
pbyTxCtl = (BYTE *)&StrDescConfiguration;
USB_CtlTx(pSetupPkt->wLength, (WORD)StrDescConfiguration.bLength);
break;
case 0x04:
// requesting interface identification string
// point to Product identification string
pbyTxCtl = (BYTE *)&StrDescInterface;
USB_CtlTx(pSetupPkt->wLength, (WORD)StrDescInterface.bLength);
break;
default:
// requesting unsupported string
printf(" Error - unsupported string index ");
break;
}
break;
case 0x04:
// LOBYTE(wValue) = 0x04
// get standard device interface descriptor
printf("(interface) ");
pbyTxCtl = (BYTE *)&UsbCfgData.InterfaceDescr;
USB_CtlTx(pSetupPkt->wLength,
(WORD)UsbCfgData.InterfaceDescr.bLength);
break;
default:
printf("(unsupported request) ");
break;
}
}
void StdInt_GetStatus(void) {
BYTE TmpBuf[2] = {0x00, 0x01};
// get device status (interface), 1001 0000 = 0x90, { 0x81, 0x00 }
D11_WrEp(D11_EP0IN_IDX, TmpBuf, 2); // Tx Endpoint Status Packet
}
void StdInt_GetDescr(PUSB_REQUEST pSetupPkt) {
// get standard interface - descriptor, 1001 0110 = 0x96, { 0x81, 0x06 }
switch(HIBYTE(pSetupPkt->wValue)) {
case 0x22:
// get standard interface descriptor (report)
printf("(report) ");
pbyTxCtl = (BYTE *)&ReportDescr;
USB_CtlTx(pSetupPkt->wLength, HID_REPORT_DESC_SIZE);
break;
case 0x21:
// get standard interface descriptor (HID)
printf("(HID) ");
pbyTxCtl = (BYTE *)&UsbCfgData.HidDescr;
USB_CtlTx(pSetupPkt->wLength, sizeof(USB_HID_DESCRIPTOR));
break;
default:
printf("(unsupported request) ");
break;
}
}
void StdInt_GetInt(PUSB_REQUEST pSetupPkt) {
// get standard interface - interface, 1001 1010 = 0x9A, { 0x81, 0x0A }
// DbgWrStr("Setup - Get Interface (interface)",1);
if( LOBYTE(pSetupPkt->wIndex) == byUsbInterface ) {
// request is for the currently selected interface (valid request)
// return the currently selected alternate interface
printf("(interface) ");
D11_WrEp(D11_EP0IN_IDX, &byUsbAltInterface, 1);
}
else {
printf("(unsupported request) ");
}
}
void StdInt_SetInterface(PUSB_REQUEST pSetupPkt) {
// set standard interface - interface, 0001 1011 = 0x1B, { 0x01, 0x0B }
// DbgWrStr("Setup - Set Standard Interface (interface)",1);
if(byUsbConfig) {
byUsbAltInterface = pSetupPkt->wValue;
byUsbInterface = pSetupPkt->wIndex;
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
else {
// when not configured, should respond with a request error
// that is... no response ??
}
}
void StdEnd_GetStatus(PUSB_REQUEST pSetupPkt) {
// get device status (endpoint), 1010 0000 = 0xA0, { 0x82, 0x00 }
// DbgWrStr("Setup - Get Standard Device Status (endpoint)",1);
BYTE TmpBuf[2] = {0x00, 0x00};
switch( LOBYTE(pSetupPkt->wIndex) ) {
case 0x00:
TmpBuf[0] = D11_GetEpStat(D11_EP0OUT_IDX);
break;
case 0x80:
TmpBuf[0] = D11_GetEpStat(D11_EP0IN_IDX);
break;
case 0x81:
TmpBuf[0] = D11_GetEpStat(D11_EP1IN_IDX);
break;
/*
case 0x01:
CtlWrBuf[2] = D11_GetEpStat(D11_EP1OUT_IDX);
break;
case 0x02:
CtlWrBuf[2] = D11_GetEpStat(D11_EP2OUT_IDX);
break;
case 0x82:
CtlWrBuf[2] = D11_GetEpStat(D11_EP2IN_IDX);
break;
*/
default:
break;
}
if(TmpBuf[0] & 0x08) {
// endpoint is stalled, return 0x0001
TmpBuf[0] = 0x01;
}
else {
// endpoint is not stalled return 0x0000
TmpBuf[0] = 0x00;
}
D11_WrEp(D11_EP0IN_IDX, TmpBuf, 2); // Tx Endpoint Status Packet
}
/*
void StdEnd_SyncFrame(void) {
}
*/
void StdEnd_ClrFeature(PUSB_REQUEST pSetupPkt) {
// clear feature (endpoint), 0010 0001 = 0x21, { 0x02, 0x01 }
// DbgWrStr("Setup - Clear Standard Feature (endpoint)",1);
switch( LOBYTE(pSetupPkt->wIndex) ) {
case 0x00:
D11_ClrEpStall(D11_EP0OUT_IDX);
break;
case 0x80:
D11_ClrEpStall(D11_EP0IN_IDX);
break;
case 0x81:
D11_ClrEpStall(D11_EP1IN_IDX);
break;
/*
case 0x01:
D11_ClrEpStall(D11_EP1OUT_IDX);
break;
case 0x02:
D11_ClrEpStall(D11_EP2OUT_IDX);
break;
case 0x82:
D11_ClrEpStall(D11_EP2IN_IDX);
break;
*/
default:
break;
}
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
void StdEnd_SetFeature(PUSB_REQUEST pSetupPkt) {
// set device feature (endpoint), 0010 0011 = 0x23, { 0x02, 0x03 }
// DbgWrStr("Setup - Set Standard Device Feature (endpoint)",1);
switch( LOBYTE(pSetupPkt->wIndex) ) {
case 0x00:
D11_SetEpStall(D11_EP0OUT_IDX);
break;
case 0x80:
D11_SetEpStall(D11_EP0IN_IDX);
break;
case 0x81:
D11_SetEpStall(D11_EP1IN_IDX);
break;
/*
case 0x01:
D11_SetEpStall(D11_EP1OUT_IDX);
break;
case 0x02:
D11_SetEpStall(D11_EP2OUT_IDX);
break;
case 0x82:
D11_SetEpStall(D11_EP2IN_IDX);
break;
*/
default:
break;
}
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
void ClsInt_GetReport(PUSB_REQUEST pSetupPkt) {
// ignore report type (hibyte of wvalue)
switch(LOBYTE(pSetupPkt->wValue)) {
// report ID
case 0x01:
// Mouse Report
D11_WrEp(D11_EP0IN_IDX, (BYTE*)&RptMouse,
sizeof(RptMouse)); // write report
break;
default:
break;
}
}
void ClsInt_GetIdle(PUSB_REQUEST pSetupPkt) {
BYTE byRptId;
byRptId = LOBYTE(pSetupPkt->wValue);
if( byRptId <= (MAX_REPORTS) ) {
// valid report number
if(Rpt[byRptId].byType == RT_INPUT) {
// report is input, return reports idle value
D11_WrEp(D11_EP0IN_IDX, (BYTE*)&Rpt[byRptId].byIdle, 1);
}
else {
// host shouldn't be asking us for idle values of non input reports
// but give it up anyway
D11_WrEp(D11_EP0IN_IDX, (BYTE*)&Rpt[byRptId].byIdle, 1);
}
}
else {
// not a valid report id, return null
D11_TxNull(D11_EP0IN_IDX);
}
}
void ClsInt_GetProtocol(void) {
BYTE byTemp = (BYTE)bProtocol;
D11_WrEp(D11_EP0IN_IDX, &byTemp, 1);
}
void ClsInt_SetReport(PUSB_REQUEST pSetupPkt) {
byRxCtlCnt = LOBYTE(pSetupPkt->wLength);
// pbyRxCtl = NULLPTR;
if(byRxCtlCnt) {
// data is coming
bRxCtl = 1;
switch(LOBYTE(pSetupPkt->wValue)) {
// report ID
case 0x01:
// Mouse Report
pbyRxCtl = (BYTE*)&RptMouse;
break;
default:
break;
}
}
}
void ClsInt_SetIdle(PUSB_REQUEST pSetupPkt) {
BYTE byRptId;
BYTE i;
byRptId = LOBYTE(pSetupPkt->wValue);
if( byRptId == 0 ) {
// 0 is flag for global idle setting of all input reports
for(i=0; i<= MAX_REPORTS; i++) {
if(Rpt[i].byType == RT_INPUT) {
// report is input, set idle value
Rpt[i].byIdle = HIBYTE(pSetupPkt->wValue);
}
}
}
else if( byRptId <= (MAX_REPORTS) ) {
// valid report number
if(Rpt[byRptId].byType == RT_INPUT) {
// report is input, return reports idle value
Rpt[byRptId].byIdle = HIBYTE(pSetupPkt->wValue);
}
else {
// host shouldn't be asking us to set idle values of non input reports
// but do it anyway
Rpt[byRptId].byIdle = HIBYTE(pSetupPkt->wValue);
}
}
else {
// not a valid report id, error?
}
D11_TxNull(D11_EP0IN_IDX);
}
/*
void Ven_Get(PUSB_REQUEST pSetupPkt) {
}
*/
/*
void Ven_Set(PUSB_REQUEST pSetupPkt) {
}
*/
void USB_CtlTx(WORD wReqCnt, WORD wActCnt) {
// transmits bytes to the host via the control endpoint
printf("USB_CtlTx Loading first 8 bytes");
if(wReqCnt > wActCnt) {
// size of data is smaller than number of bytes requested
byTxCtlCnt = wActCnt;
}
else {
// size of data is equal to or greater than number of bytes requested
byTxCtlCnt = wReqCnt;
}
// D11_GetLtStat(D11_EP0IN_IDX);
if(byTxCtlCnt < 8) {
D11_WrEp(D11_EP0IN_IDX, pbyTxCtl, byTxCtlCnt);
}
else {
D11_WrEp(D11_EP0IN_IDX, pbyTxCtl, 8);
pbyTxCtl+=8;
byTxCtlCnt-=8;
byTxCtl = 1;
}
}
void USB_CtlRxData(void) {
BYTE byRead;
if(bRxCtl) {
printf(" P R O C E S S D A T A C A L L");
// receiving control data
if(pbyRxCtl != NULLPTR) {
byRead = D11_RdEp(pbyRxCtl, D11_EP0OUT_IDX);
}
else {
// just clear the buffer
byRead = D11_ClrEp(D11_EP0OUT_IDX);
}
if(byRead > byRxCtlCnt) {
// ouch, got more than we were expecting
bRxCtl = 0;
byRxCtlCnt = 0;
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
else if(byRead == byRxCtlCnt) {
// got the last of it
bRxCtl = 0;
byRxCtlCnt = 0;
printf(" Got the report data!");
D11_TxNull(D11_EP0IN_IDX); // TxNull Packet
}
else {
// more to come
byRxCtlCnt -= byRead;
if(pbyRxCtl != NULLPTR) {
pbyRxCtl += byRead;
}
}
}
else {
printf(" RdEpIdx02 Null { 0x00, 0x00 } ");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -