📄 usbhid.c
字号:
// For CMD_GET_STATUS, don't overwrite current cmd we're working on
//LcdDisplay(16,0,"收到数据",0);
//printfLCD("%X%Y收到字节: %x", 24,0, val++);
RecvFlagPacket = 1;
//M25P80_Write(1,10,64,&rcvReport);
// M25P80_Bulk_Erase(1);
returnStatus = TRUE;
}
else
{
// Copy into 'current command' global variable
memcpy(currentCmd.u.buffer, rcvReport.u.buffer, sizeof(rcvReport));
memset((uchar*)&status, 0, sizeof(status));
// g_debug1 = currentCmd.u.cmd;
} // Some commands are processed at this point
}
}
static BOOL HandleReport()
/******************************************************************************
Function : static BOOL HandleReport()
Parameters : none
Description: Handles HID Get_Report and Set_Report SETUP packets.
Returns TRUE if the SETUP packet is a Get_Report or Set_Report
request; else returns FALSE.
******************************************************************************/
{
// If it is a HID Set_Report request...
if ((setupPacket.bmRequestType == CLASS_INTERFACE_TO_DEVICE)
&& (setupPacket.bRequest == HID_SET_REPORT))
{
rcvIndex = 0; // Prepare to receive report
return TRUE;
}
// Else if it is a HID Get_Report request ...
else if ((setupPacket.bmRequestType == CLASS_INTERFACE_TO_HOST)
&& (setupPacket.bRequest == HID_GET_REPORT))
{
// Transmit first segment of response (should be already prepared)
UCON0 &= ~uTSEQ0;
TransmitDataEP0(txReport.u.buffer, EP0_SIZE);
txIndex = EP0_SIZE; // Prepare next segment while first one is going out
PrepareTransmitSegment(txIndex);
return TRUE;
}
return FALSE;
}
bdata char USB_ISR_FLAGS = 0;
sbit GoOnResume = USB_ISR_FLAGS ^ 0;
sbit GoOnSuspend = USB_ISR_FLAGS ^ 7;
static void OnUSBSuspend()
/******************************************************************************
Function : static void OnUSBSuspend()
Parameters : none
Description: service routine for USB Suspend event
******************************************************************************/
{
data char bie,biea;
bie = IE;
biea = IEA;
IEA = 1; // disable all INTs except USB
IE = 128; // disable all INTs except USB
SUSPND = 1; //Enter suspend mode for uPSD
GoOnSuspend = 0; //clear global Suspend flag
// entering SUSPEND or setting SUSPNDF causes to top the clocks to the USB
// and causes the USB module to enter Suspend Mode.
UIEN |= uRESUMIE; // enable resume INT
PCON |= 1; //Enter Idle mode
// here the uPSD sleeps and waits for the next INT
SUSPND = 0; //clear the flag
IE = bie;
IEA = biea;
UIEN &= ~uRESUMIE; // disable resume INT
RESUMF = 0; //clear the flag
}
// void printfLCD(uchar *chr_ptr, ...);
void InitUSB(void)
{
UsbInitialize(); // Initialize USB,
IP = 0; // USB must have the highest priority !!!
IPA = 1; // USB must have the highest priority !!!
EA = 0;
IEA |= 0x80; // Enable DDC Interrupt - Priority is user TBD
EA = 1; // Enable INTs
}
static void UsbIsr() interrupt 6 using 3
/******************************************************************************
Function : static void UsbIsr()
Parameters : none
Description: USB interrupt service routine.
Note: Do not modify this routine !!!
******************************************************************************/
{
data uchar cb, packetlen;
data uchar i;
uchar byte;
uint in;
uchar buff[9];
if (RXD0F) // If data received on EP0 OUT ...
{
// do not change this SETUP packet processing part up to else !!!
if (USTA & uSETUP) // If it's a SETUP packet ...
{
if (UCON0 & uSTALL0) // try to fix bug in uPSD
{
/*#pragma asm
anl UCON0,#255-uSTALL0 ;clear STALL0 bit when it hangs
#pragma endasm*///08-02-2004
UCON0 &= 255-uSTALL0;
}
if (ReadSetupPacket()) // Read the SETUP packet
{
//tady to nepomaha
if (!HandleReport()) // Test and handle HID type packets
{
// If this is not a HID report ... pass it on to the basic SETUP packet handler
OnSetupPacket();
}
else
{
}
}
else
{
//No Setup packet with DATA length = 8, STALLed automatically in ReadSetupPacket()
}
RXD0F = 0; // Clear interrupt flag so next packet can come in now
}
else
/*======== No SETUP packet, normal data packets ========*/
{
// If in the middle of receiving a report ...
if ((USTA & 0x0F) && (rcvIndex < OUTPUT_REPORT_SIZE))
{
cb = (USTA & 0x0F); // Read the next segment
if (cb > EP0_SIZE)
{
cb = EP0_SIZE; // fix bug
}
for (i = 0; i < cb; i++)
{
//rcvReport.u.buffer[rcvIndex + i] = UDR0; //read received data
byte = UDR0;
rcvReport.u.buffer[rcvIndex + i] = 0;
buff[i] = byte;
}
if((buff[0]&0xf0)==0x50)
{
packetlen = buff[0] & 0x0f; //接收长度
for(i = 0; i < packetlen; i++)
{
in = rxin + 1;
if (in > RxbuffLength)
in = 0;
if (rxout != in)
{
USBRxdBuf[rxin] = buff[i+1];
rxin = in;
}
}
}
/*#pragma asm
xrl USTA,#uRSEQ; // Toggle data toggle bit
#pragma endasm*///08-02-2004
USTA ^= uRSEQ;
// Handle report as it comes in and/or when all done
// OnReportSegmentReceived(cb);
if ((rcvIndex += cb) >= OUTPUT_REPORT_SIZE)
{
OnReportReceived();//
/*#pragma asm //send a zero length packet
anl UCON0,#uTSEQ0+uRX0E
orl UCON0,#uTX0E ;enable trasmit
#pragma endasm*///08-02-2004
UCON0 &= uTSEQ0+uRX0E;
UCON0 |= uTX0E;
}
RXD0F = 0; // Clear interrupt flag so next packet can come in now
}
else
{
// Got 0 length ACK data packet; expecting a SETUP packet now.
USTA ^= uRSEQ; // Toggle data toggle bit
RXD0F = 0; // Clear interrupt flag so next packet can come in now
}
}
}
if (TXD0F)
{
TXD0F = 0; // Clear the interrupt flag
// Do not change this part up to call of BaseEp0Handler
// If in the middle of transmitting a report ...
if (txIndex < FEATURE_REPORT_SIZE)
{
// Transmit the next segment of outgoing report
cb = min(FEATURE_REPORT_SIZE - txIndex, EP0_SIZE);
TransmitDataEP0(txReport.u.buffer + txIndex, cb);
if ((txIndex += cb) >= FEATURE_REPORT_SIZE)
{
OnReportTransmitted();
}
else
{
// Prepare the next segment while that last one is going out
PrepareTransmitSegment(txIndex);
}
}
else
{
// This part can changed (or BaseEp0Handler directly)
BaseEp0TxHandler(); // Handle standard control requests
}
}
if (SUSPND) // Handle suspend interrupt
{
SUSPND = 0; // keep USB logic functional
GoOnSuspend = 1; // set global flag
UIEN &= ~uSUSPNDIE; // disable INT
DDCCON = 0x2; // generate DDC interrupt
DDCCONintc++; // aux. DDC cnt
}
if (TXD1F) // If data successfully transmitted on EP1 ...
{
UIEN &= ~uTXD1IE; // disable EP1,2 INT, serviced in OnIdle()
DDCCON = 0x2; // generate DDC interrupt
DDCCONintc++; // aux. DDC cnt
}
if (RSTF) // Handle USB bus reset, it must be at the end of USB ISR
{
USB_ISR_FLAGS = 0;
OnUSBReset(); //resets all the flags automatically
DDCCON = 0x2; // generate DDC interrupt
DDCCONintc++; // aux. DDC cnt
}
g_debugUSB_INT_CNT++; // increment USB ISR counter
}
static data char bufIndex = 0; // Current position in LCD buffer
static data char txBuf[8]; // Buffer to send back to PC
static void OnTransmitEP1() //
//ff()
{
data unsigned char i,nBytes; // Num bytes of LCD data
uchar buff[8];
data uchar packetlen;
/*
nBytes = 7;
for(i=1;i<8;i++) txBuf[i] = i;
if(MySendFlag)
{
MySendFlag = 0;
txBuf[0] = 0x55;
}
else txBuf[0] = 1;
*/
buff[0] = 0;
nBytes = 7;
if(MySendFlag)
{
buff[0] = 0x50;
packetlen = 0;
for(i=1;i<8;i++)
{
if(SendPos<MySendLen) //数据没有发送完
{
buff[i] = USBTxdBuf[SendPos++];
packetlen++;
}
else
{
buff[i] = 0;
MySendFlag = 0;
}
}
buff[0] += packetlen;
//buff[0] = 0x57;
}
TransmitDataEPx(1, buff, nBytes+1); // Transmit input report to host
}//
static void DDC_isr (void) interrupt 7 using 2
/******************************************************************************
Function : static void UsbIsr()
Parameters : none
Description: This is the rest of USB ISR. You can use other INT (except USB)
if needed. Only USB must have the highest priority ...
Remark: This part can be deleted if you do not use suspend mode or EP1/2.
All the time-consuming operations (>200us) must be here to avoid
possible problems with very long USB ISR.
*******************************************************************************/
{
data uchar ddcint; //
EA = 0; // disable int
DDCCON = 0; // Clear DDCCON
ddcint = S1STA; // Dummy Read DDC I2C S1STA to clear Interupt
S1CON = 0; // Clear DDC I2C S1CON
EA = 1; // enable int
while (DDCCONintc>0) // multiple DDC calls
{
DDCCONintc--; // aux. DDC cnt
//
if (TXD1F) //Service USB INT EP1
{
TXD1F = 0;
OnTransmitEP1(); //service EP1
}
// The following 3 lines can be deleted if you don't plan to use Suspend
if (GoOnSuspend) //Service USB INT Suspend
{
OnUSBSuspend(); //
}
}
}
uchar Receive(uint Len,uchar *Dat)
{
uint i=0;
ulong TimeOut = 0;
uchar x;
for(i=0;i<Len;i++)
{
x=Check_InBuff();
while(!x)
{
TimeOut++;
if(TimeOut>80000)return 0;
x=Check_InBuff();
}
Dat[i]=USB_GetByte();
TimeOut=0;
}
return 1;
}
void UsbSend(uint Len,uchar *Dat)
{
uint i;
while(MySendFlag); //数据是否发完
MySendFlag = 1;
MySendLen = Len;
SendPos = 0;
for(i=0;i<Len;i++)
{
USBTxdBuf[i] = Dat[i];
}
}
/* *************************************************************************
*** ***
** *** End of File *** **
*** ***
*************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -