首页 > 编程学习 > C8051F340 USB Fn hacking

C8051F340 USB Fn hacking

发布时间:2022/12/10 17:51:48
/*************************************************************************************                           C8051F340 USB Fn hacking* 说明:*     简单跟踪一下这个C8051F340 USB的使用。**                                               2017-4-1 深圳 南山平山村 曾剑锋***********************************************************************************/void main(void)
{System_Init (); --------------------+USB0_Init ();                       |EA = 1;                             ||while (1) {                         |Key_Scan();                     |      ------------------------------------+Key_Handle();                   |      ------------------------------------*-+}                                   |                                          | |
}                                       |                                          | ||                                          | |
void System_Init (void)    <------------+                                          | |
{                                                                                  | |PCA0MD &= ~0x40;                    // Disable Watchdog timer                  | |Sysclk_Init ();      -------+       // initialize system clock                 | |Port_Init ();               |       // configure cross bar      -----------+   | |Timer_Init ();              |       // configure timer          -----------*-+ | |
}                               |                                              | | | ||                                              | | | |
void Sysclk_Init (void)   <-----+                                              | | | |
{                                                                              | | | |
#ifdef _USB_LOW_SPEED_                                                         | | | || | | |OSCICN |= 0x03;                     // Configure internal oscillator for   | | | |// its maximum frequency and enable                                        | | | |// missing clock detector                                                  | | | || | | |CLKSEL  = SYS_EXT_OSC;              // Select System clock                 | | | |CLKSEL |= USB_INT_OSC_DIV_2;        // Select USB clock                    | | | |
#else                                                                          | | | |OSCICN |= 0x03;                     // Configure internal oscillator for   | | | |// its maximum frequency and enable                                        | | | |// missing clock detector                                                  | | | || | | |CLKMUL  = 0x00;                     // Select internal oscillator as       | | | |// input to clock multiplier                                               | | | || | | |CLKMUL |= 0x80;                     // Enable clock multiplier             | | | |CLKMUL |= 0xC0;                     // Initialize the clock multiplier     | | | |Delay();                            // Delay for clock multiplier to begin | | | || | | |while(!(CLKMUL & 0x20));            // Wait for multiplier to lock         | | | |CLKSEL  = SYS_INT_OSC;              // Select system clock                 | | | |CLKSEL |= USB_4X_CLOCK;             // Select USB clock                    | | | |
#endif  /* _USB_LOW_SPEED_ */                                                  | | | |
}                                                                              | | | || | | |
void Port_Init(void)                <------------------------------------------+ | | |
{                                                                                | | |P0MDOUT        = 0xFF;                                                       | | |P0SKIP        = 0xFF;                                                        | | |P2MDIN   = 0xFF;                 // Port 2 pin 5 set as analog input         | | |P2SKIP   = 0xFF;                    // Port 2 pin 5 skipped by crossbar      | | || | |XBR1        = 0x40;                    // Enable Crossbar                    | | || | |DebugLEDOFF;                        // ¹Ø±Õµ÷Êﵮ                            | | |
}                                                                                | | || | |
void Timer_Init (void)                                                           | | |
{                                                                                | | |TMR2CN  = 0x00;                     // Stop Timer2; Clear TF2;               | | || | |CKCON  &= ~0xF0;                    // Timer2 clocked based on T2XCLK;       | | |TMR2L   = 0x7F;                      // Timer/Counter 2 Low                  | | |TMR2H   = 0xFF;                      // Timer/Counter 2 High                 | | |TMR2RLL = 0xEF;                         // Timer/Counter 2 Reload Low        | | |TMR2RLH    = 0xD8;                         // Timer/Counter 2 Reload High    | | || | |ET2     = 1;                        // Enable Timer2 interrupts              | | |TR2     = 1;                        // Start Timer2                          | | |
}                                                                                | | || | |
void USB0_Init (void)          <-------------------------------------------------+ | |
{                                                                                  | || |//    #define POLL_WRITE_BYTE(addr, data) while(USB0ADR & 0x80);  \            | |//                                    WRITE_BYTE(addr, data);                  | |POLL_WRITE_BYTE (POWER, 0x08);      // Force Asynchronous USB Reset       ---+ | |POLL_WRITE_BYTE (IN1IE, 0x07);      // Enable Endpoint 0-1 in interrupts     | | |POLL_WRITE_BYTE (OUT1IE,0x07);      // Enable Endpoint 0-1 out interrupts    | | |POLL_WRITE_BYTE (CMIE, 0x07);       // Enable Reset, Resume, and Suspend     | | |// interrupts                                                                | | |USB0XCN = 0xE0;                     // Enable transceiver; select full speed | | |POLL_WRITE_BYTE (CLKREC,0x89);      // Enable clock recovery, single-step    | | |// mode disabled                                                             | | || | |EIE1 |= 0x02;                       // Enable USB0 Interrupts                | | || | |// Enable USB0 by clearing the USB                                           | | |POLL_WRITE_BYTE (POWER, 0x01);      // Inhibit Bit and enable suspend        | | |// detection                                                                 | | || | |
}                                                                                | | || | |
#define POLL_WRITE_BYTE(addr, data) while(USB0ADR & 0x80);  \       <------------+ | |WRITE_BYTE(addr, data);                                         -----+         | ||         | |
#define WRITE_BYTE(addr, data) USB0ADR = (addr); USB0DAT = data     <----+         | ||         | |
sfr  USB0DAT      =  0x97;             // USB0 Data Register        <----+         | || |
void Key_Scan(void) {             <------------------------------------------------+ |static unsigned char AllKeyBk;                                                   |unsigned char AllKey = 0;                                                        |unsigned char i = 0;                                                             ||if(b_ScanKey) {    // 定时器中每过10ms会对这个变量置1一次                        |b_ScanKey = 0;                                                               |AllKey = P2;                                                                 |AllKey >>= 2;                                                                |if(AllKey != 0x3F) {    // 有键按下                                          |if(AllKeyBk != AllKey) {                                                 |LongKeyCnt = 0;    // 有新的按键按下,重新去抖                       |}                                                                        |AllKeyBk = AllKey;                                                       |LongKeyCnt++;                                                            |if(LongKeyCnt > 1) {    // 20ms 去抖                                     |key_status[KEYALL] = KEY_DOWN;                                       |for( i = 0; i < 6; i++) {                                            |// 判断每一个按键的状态                                          |if( (AllKey & 0x01) == 0 ) {                                     |key_status[i] = KEY_DOWN;                                    |} else {                                                         |key_status[i] = KEY_UP;                                      |}                                                                |AllKey >>= 1;                                                    |}                                                                    |}                                                                        |} else {                                                                     |key_status[KEYALL] = KEY_UP;                                             |LongKeyCnt = 0;                 // 当按键抬起来之后这里会置零            |for( i = 0; i < 6; i++) {                                                |key_status[i] = KEY_UP;                                              |}                                                                        |}                                                                            |}                                                                                |
}                                                                                    ||
void Key_Handle(void)          <-----------------------------------------------------+
{static unsigned char key_status_bk[6] = {KEY_UP};unsigned char i;unsigned char cnt_i;cnt_i = 2;if(key_status[KEYF1] == KEY_DOWN) {if(key_status[KEYF1] != key_status_bk[KEYF1]) {IN_PACKET[cnt_i] = KB_F1;DebugLEDON;cnt_i++;}} else if(key_status[KEYF1] == KEY_UP) {if(key_status[KEYF1] != key_status_bk[KEYF1]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYF2] == KEY_DOWN) {if(key_status[KEYF2] != key_status_bk[KEYF2]) {IN_PACKET[cnt_i] = KB_F2;DebugLEDON;cnt_i++;}} else if(key_status[KEYF2] == KEY_UP) {if(key_status[KEYF2] != key_status_bk[KEYF2]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYF3] == KEY_DOWN) {if(key_status[KEYF3] != key_status_bk[KEYF3]) {IN_PACKET[cnt_i] = KB_F3;DebugLEDON;cnt_i++;}} else if(key_status[KEYF3] == KEY_UP) {if(key_status[KEYF3] != key_status_bk[KEYF3]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYF4] == KEY_DOWN) {if(key_status[KEYF4] != key_status_bk[KEYF4]) {IN_PACKET[cnt_i] = KB_F4;DebugLEDON;cnt_i++;}} else if(key_status[KEYF4] == KEY_UP) {if(key_status[KEYF4] != key_status_bk[KEYF4]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYF5] == KEY_DOWN) {if(key_status[KEYF5] != key_status_bk[KEYF5]) {IN_PACKET[cnt_i] = KB_F5;DebugLEDON;cnt_i++;}} else if(key_status[KEYF5] == KEY_UP) {if(key_status[KEYF5] != key_status_bk[KEYF5]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYF6] == KEY_DOWN) {if(key_status[KEYF6] != key_status_bk[KEYF6]) {IN_PACKET[cnt_i] = KB_F6;DebugLEDON;cnt_i++;}} else if(key_status[KEYF6] == KEY_UP) {if(key_status[KEYF6] != key_status_bk[KEYF6]) {    // 按键状态发生改变,只发送一次数据
            DebugLEDOFF;}}if(key_status[KEYALL] == KEY_DOWN){if(key_status[KEYALL] != key_status_bk[KEYALL]) {SendPacket (0);}} else if(key_status[KEYALL] == KEY_UP){for(i = 2; i < 6; i++) {IN_PACKET[i] = 0;                              -------+}                                                         |if(key_status[KEYALL] != key_status_bk[KEYALL]) {  -------*-+SendPacket (0);                                       | |}                                                         | |}                                                             | || |for(i = 0; i < 7; i++) {                                      | |key_status_bk[i] = key_status[i];                         | |}                                                             | |
}                                                                 | || |
unsigned char IN_PACKET[8] ={0,0,0,0,0,0,0,0};            <-------+ ||
unsigned char key_status[7] = {KEY_UP};                   <---------+void Timer2_ISR (void) interrupt 5        // 10ms
{static unsigned Timer2_Cnt = 0;Timer2_Cnt++;b_ScanKey = 1;    // for key countif( (Timer2_Cnt%50) == 0 )    {}if( Timer2_Cnt == 50000)Timer2_Cnt = 0;TF2H = 0;                           // Clear Timer2 interrupt flag
}//-----------------------------------------------------------------------------
// Usb_ISR
//-----------------------------------------------------------------------------
//
// Called after any USB type interrupt, this handler determines which type
// of interrupt occurred, and calls the specific routine to handle it.
//
//-----------------------------------------------------------------------------
void Usb_ISR (void) interrupt 8        // USB中断入口
{unsigned char bCommon, bIn, bOut;POLL_READ_BYTE (CMINT, bCommon);    // USB0公共中断寄存器    ------+POLL_READ_BYTE (IN1INT, bIn);        // USB0输入端点中断寄存器     |POLL_READ_BYTE (OUT1INT, bOut);        // USB0输出端点中断寄存器   |{                                                                  |if (bCommon & rbRSUINT) {        // 恢复-> 没有实质的动作      |Usb_Resume ();                                 ------------*-+}                                                              | |if (bCommon & rbRSTINT) {        // 复位                       | |Usb_Reset ();                                  ------------*-*-+}                                                              | | |if (bCommon & rbSUSINT)  {        // 挂起                      | | |Usb_Suspend ();                                ------------*-*-*---+}                                                              | | |   |if (bIn & rbEP0) {                // 端点0中断处理             | | |   |Handle_Control ();                             ------------*-*-*---*-----+}                                                              | | |   |     |if (bIn & rbIN1) {              // 端点1输入中断处理           | | |   |     |Handle_In1 ();                                 ------------*-*-*---*-+   |}                                                              | | |   | |   |if (bOut & rbOUT1) {            // 端点1输出中断处理           | | |   | |   |Handle_Out1 ();                                ------------*-*-*---*-*-+ |}                                                              | | |   | | | |}                                                                  | | |   | | | |
}                                                                      | | |   | | | || | |   | | | |
#define POLL_READ_BYTE(addr, target) while(USB0ADR & 0x80); \    <-----+ | |   | | | |READ_BYTE(addr, target);                               -------+      | |   | | | ||      | |   | | | |
#define READ_BYTE(addr, target) USB0ADR = (0x80 | addr); \ <------+      | |   | | | |while (USB0ADR & 0x80); target = USB0DAT        | |   | | | || |   | | | |
void Usb_Resume(void)                     <------------------------------+ |   | | | |
{                                                                          |   | | | |volatile int k;                                                        |   | | | ||   | | | |k++;                                                                   |   | | | ||   | | | |// Add code for resume                                                 |   | | | |
}                                                                          |   | | | ||   | | | |
void Usb_Reset (void)                     <--------------------------------+   | | | |
{                                                                              | | | |USB0_STATE = DEV_DEFAULT;           // Set device state to default         | | | || | | |POLL_WRITE_BYTE (POWER, 0x01);      // Clear usb inhibit bit to enable USB | | | |// suspend detection                                                       | | | || | | |EP_STATUS[0] = EP_IDLE;             // Set default Endpoint Status         | | | |EP_STATUS[1] = EP_HALT;                                                    | | | |EP_STATUS[2] = EP_HALT;                                                    | | | |
}                                                                              | | | || | | |
void Usb_Suspend (void)         <----------------------------------------------+ | | |
{                                                                                | | |volatile int k;                                                              | | |k++;                                                                         | | |
}                                                                                | | || | |
void Handle_In1 ()              <------------------------------------------------+ | |
{                                                                                  | |EP_STATUS[1] = EP_IDLE;                                                        | |
}                                                                                  | || |
void Handle_Out1 ()             <--------------------------------------------------+ |
{                                                                                    ||unsigned char Count = 0;                                                         |unsigned char ControlReg;                                                        ||POLL_WRITE_BYTE (INDEX, 1);         // Set index to endpoint 2 registers         |POLL_READ_BYTE (EOUTCSR1, ControlReg);                                           ||if (EP_STATUS[1] == EP_HALT)        // If endpoint is halted, send a stall       |{                                                                                |POLL_WRITE_BYTE (EOUTCSR1, rbOutSDSTL);                                      |}                                                                                ||else                                // Otherwise read received packet            |// from host                                                                 |{                                                                                |if (ControlReg & rbOutSTSTL)     // Clear sent stall bit if last             |// packet was a stall                                                    |{                                                                            |POLL_WRITE_BYTE (EOUTCSR1, rbOutCLRDT);                                  |}                                                                            ||Setup_OUT_BUFFER ();             // configure buffer to save                 |// received data                                                             |Fifo_Read(FIFO_EP1, OUT_BUFFER.Length, OUT_BUFFER.Ptr);                      ||// process data according to received Report ID.                             |// In systems with Report Descriptors that do not define report IDs,         |// the host will still format OUT packets with a prefix byte                 |// of '0x00'.                                                                ||ReportHandler_OUT (OUT_BUFFER.Ptr[0]);                                       ||POLL_WRITE_BYTE (EOUTCSR1, 0);   // Clear Out Packet ready bit               |}                                                                                |
}                                                                                    ||
//-----------------------------------------------------------------------------      |
// Handle_Control                                                                    |
//-----------------------------------------------------------------------------      |
//                                                                                   |
// Return Value : None                                                               |
// Parameters   : None                                                               |
//                                                                                   |
// - Decode Incoming SETUP requests                                                  |
// - Load data packets on fifo while in transmit mode                                |
//                                                                                   |
//-----------------------------------------------------------------------------      ||
void Handle_Control (void)                    <--------------------------------------+
{unsigned char ControlReg;           // Temporary storage for EP control register
POLL_WRITE_BYTE (INDEX, 0);         // ¶ËµãË÷ÒýÖÁ ¶Ëµã0POLL_READ_BYTE (E0CSR, ControlReg); // Read control registerif (EP_STATUS[0] == EP_ADDRESS)     // Handle Status Phase of Set Address// command
    {POLL_WRITE_BYTE (FADDR, SETUP.wValue.c[LSB]);EP_STATUS[0] = EP_IDLE;}if (ControlReg & rbSTSTL)           // If last packet was a sent stall,{                                   // reset STSTL bit and return EP0// to idle statePOLL_WRITE_BYTE (E0CSR, 0);EP_STATUS[0] = EP_IDLE;return;}if (ControlReg & rbSUEND)           // If last SETUP transaction was{                                   // ended prematurely then set
        POLL_WRITE_BYTE (E0CSR, rbDATAEND);// Serviced SETUP End bit and return EP0
        POLL_WRITE_BYTE (E0CSR, rbSSUEND);EP_STATUS[0] = EP_IDLE;          // to idle state
    }if (EP_STATUS[0] == EP_IDLE)        // If Endpoint 0 is in idle mode
    {if (ControlReg & rbOPRDY)        // Make sure that EP 0 has an Out Packet{                                // ready from host although if EP0// is idle, this should always be the case/*typedef struct{// typedef union {unsigned int i; unsigned char c[2];} WORD;unsigned char bmRequestType;        // Request recipient, type, and dir.unsigned char bRequest;             // Specific standard request numberWORD wValue;                        // varies according to requestWORD wIndex;                        // varies according to requestWORD wLength;                       // Number of bytes to transfer} setup_buffer;                        // End of SETUP Packet Type*/Fifo_Read (FIFO_EP0, 8, (unsigned char *)&SETUP);// Get SETUP Packet off of Fifo, it is currently Big-Endian// Compiler Specific - these next three statements swap the bytes of the// SETUP packet words to Big Endian so they can be compared to other 16-bit// values elsewhere properlySETUP.wValue.i = SETUP.wValue.c[MSB] + 256*SETUP.wValue.c[LSB];SETUP.wIndex.i = SETUP.wIndex.c[MSB] + 256*SETUP.wIndex.c[LSB];SETUP.wLength.i = SETUP.wLength.c[MSB] + 256*SETUP.wLength.c[LSB];// Intercept HID class-specific requestsif( (SETUP.bmRequestType & ~0x80) == DSC_HID) {switch (SETUP.bRequest) {case GET_REPORT:Get_Report ();                ----------------------------------+break;                                                          |case SET_REPORT:                                                    |Set_Report ();                                                  |break;                                                          |case GET_IDLE:                                                      |Get_Idle ();                                                    |break;                                                          |case SET_IDLE:                                                      |Set_Idle ();                                                    |break;                                                          |case GET_PROTOCOL:                                                  |Get_Protocol ();                                                |break;                                                          |case SET_PROTOCOL:                                                  |Set_Protocol ();                                                |break;                                                          |default:                                                            |Force_Stall ();      // Send stall to host if invalid           |break;                 // request                               |}                                                                       |} else                                                                      ||switch (SETUP.bRequest)       // Call correct subroutine to handle      |{                             // each kind of standard request          |case GET_STATUS:                                                    |Get_Status ();                                                  |break;                                                          |case CLEAR_FEATURE:                                                 |Clear_Feature ();                                               |break;                                                          |case SET_FEATURE:                                                   |Set_Feature ();                                                 |break;                                                          |case SET_ADDRESS:                                                   |Set_Address ();                                                 |break;                                                          |case GET_DESCRIPTOR:                                                |Get_Descriptor ();                                              |break;                                                          |case GET_CONFIGURATION:                                             |Get_Configuration ();                                           |break;                                                          |case SET_CONFIGURATION:                                             |Set_Configuration ();                                           |break;                                                          |case GET_INTERFACE:                                                 |Get_Interface ();                                               |break;                                                          |case SET_INTERFACE:                                                 |Set_Interface ();                                               |break;                                                          |default:                                                            |Force_Stall ();         // Send stall to host if invalid request|break;                                                          |}                                                                       |}                                                                               |}                                                                                   ||if (EP_STATUS[0] == EP_TX)          // See if endpoint should transmit              |{                                                                                   |if (!(ControlReg & rbINPRDY) )   // Don't overwrite last packet                 |{                                                                               |// Read control register                                                    |POLL_READ_BYTE (E0CSR, ControlReg);                                         ||// Check to see if SETUP End or Out Packet received, if so do not put       |// any new data on FIFO                                                     |if ((!(ControlReg & rbSUEND)) || (!(ControlReg & rbOPRDY)))                 |{                                                                           |// Add In Packet ready flag to E0CSR bitmask                            |ControlReg = rbINPRDY;                                                  |if (DATASIZE >= EP0_PACKET_SIZE)                                        |{                                                                       |// Break Data into multiple packets if larger than Max Packet       |Fifo_Write_InterruptServiceRoutine (FIFO_EP0, EP0_PACKET_SIZE,      |(unsigned char*)DATAPTR);                                   |// Advance data pointer                                             |DATAPTR  += EP0_PACKET_SIZE;                                        |// Decrement data size                                              |DATASIZE -= EP0_PACKET_SIZE;                                        |// Increment data sent counter                                      |DATASENT += EP0_PACKET_SIZE;                                        |}                                                                       |else                                                                    |{                                                                       |// If data is less than Max Packet size or zero                     |Fifo_Write_InterruptServiceRoutine (FIFO_EP0, DATASIZE,             |(unsigned char*)DATAPTR);                                   |ControlReg |= rbDATAEND;// Add Data End bit to bitmask              |EP_STATUS[0] = EP_IDLE; // Return EP 0 to idle state                |}                                                                       |if (DATASENT == SETUP.wLength.i)                                        |{                                                                       |// This case exists when the host requests an even multiple of      |// your endpoint zero max packet size, and you need to exit         |// transmit mode without sending a zero length packet               |ControlReg |= rbDATAEND;// Add Data End bit to mask                 |EP_STATUS[0] = EP_IDLE; // Return EP 0 to idle state                |}                                                                       |// Write mask to E0CSR                                                  |POLL_WRITE_BYTE(E0CSR, ControlReg);                                     |}                                                                           |}                                                                               |}                                                                                   ||if (EP_STATUS[0] == EP_RX)          // See if endpoint should transmit              |{                                                                                   |// Read control register                                                        |POLL_READ_BYTE (E0CSR, ControlReg);                                             |if (ControlReg & rbOPRDY)        // Verify packet was received                  |{                                                                               |ControlReg = rbSOPRDY;                                                      |if (DATASIZE >= EP0_PACKET_SIZE)                                            |{                                                                           |Fifo_Read(FIFO_EP0, EP0_PACKET_SIZE, (unsigned char*)DATAPTR);          |// Advance data pointer                                                 |DATAPTR  += EP0_PACKET_SIZE;                                            |// Decrement data size                                                  |DATASIZE -= EP0_PACKET_SIZE;                                            |// Increment data sent counter                                          |DATASENT += EP0_PACKET_SIZE;                                            |}                                                                           |else                                                                        |{                                                                           |// read bytes from FIFO                                                 |Fifo_Read (FIFO_EP0, DATASIZE, (unsigned char*) DATAPTR);               ||ControlReg |= rbDATAEND;   // signal end of data                        |EP_STATUS[0] = EP_IDLE;    // set Endpoint to IDLE                      |}                                                                           |if (DATASENT == SETUP.wLength.i)                                            |{                                                                           |ControlReg |= rbDATAEND;                                                |EP_STATUS[0] = EP_IDLE;                                                 |}                                                                           |// if EP_RX mode was entered through a SET_REPORT request,                  |// call the ReportHandler_OUT function and pass the Report                  |// ID, which is the first by the of DATAPTR's buffer                        |if ( (EP_STATUS[0] == EP_IDLE) && (SETUP.bRequest == SET_REPORT) )          |{                                                                           |ReportHandler_OUT (*DATAPTR);                                           |}                                                                           ||if (EP_STATUS[0] != EP_STALL) POLL_WRITE_BYTE (E0CSR, ControlReg);          |}                                                                               |}                                                                                   ||
}                                                                                       ||
//-----------------------------------------------------------------------------         |
//                                                                                      |
// Return Value - None                                                                  |
// Parameters - None                                                                    |
//                                                                                      |
// Description: Sends a given report type to the host.                                  |
//                                                                                      |
//-----------------------------------------------------------------------------         |
void Get_Report (void)                                   <------------------------------+
{// call appropriate handler to prepare bufferReportHandler_IN_ISR(SETUP.wValue.c[LSB]);            --------------------+// set DATAPTR to buffer used inside Control Endpoint                     |DATAPTR = IN_BUFFER.Ptr;                                                  |DATASIZE = IN_BUFFER.Length;                                              ||if (EP_STATUS[0] != EP_STALL)                                             |{                                                                         |// Set serviced SETUP Packet                                          |POLL_WRITE_BYTE (E0CSR, rbSOPRDY);                                    |EP_STATUS[0] = EP_TX;            // Endpoint 0 in transmit mode       |DATASENT = 0;                    // Reset DATASENT counter            |}                                                                         |
}                                                                             ||
void ReportHandler_IN_ISR(unsigned char R_ID)            <--------------------+
{unsigned char index;index = 0;while(index <= IN_VECTORTABLESize){// check to see if Report ID passed into function// matches the Report ID for this entry in the Vector Tableif(IN_VECTORTABLE[index].ReportID == R_ID)       ---------------------------+{                                                                           |IN_VECTORTABLE[index].hdlr();                                           |break;                                                                  |}                                                                           ||// if Report IDs didn't match, increment the index pointer                  |index++;                                                                    |}                                                                               ||
}                                                                                   ||
// ****************************************************************************     |
// Link all Report Handler functions to corresponding Report IDs                    |
// ****************************************************************************     ||
const VectorTableEntry code IN_VECTORTABLE[IN_VECTORTABLESize] =        <-----------+
{// FORMAT: Report ID, Report Handler0, IN_Report                                                       ------+
};                                                                           ||
void IN_Report(void){                            <---------------------------+// save left mouse button stat to bit 0 of first data byte// IN_PACKET[2] = MOUSE_BUTTON1;// IN_PACKET[3] = MOUSE_BUTTON2;IN_BUFFER.Ptr = IN_PACKET;                   ---------+IN_BUFFER.Length = 8;                                 ||
}                                                         ||
unsigned char IN_PACKET[8] ={0,0,0,0,0,0,0,0};   <--------+

 


本文链接:https://www.ngui.cc/zz/1569045.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000