博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C8051F340 USB Fn hacking
阅读量:7038 次
发布时间:2019-06-28

本文共 46451 字,大约阅读时间需要 154 分钟。

/************************************************************************************ *                           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 count if( (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); // ¶ËµãË÷ÒýÖÁ ¶Ëµã0 POLL_READ_BYTE (E0CSR, ControlReg); // Read control register if (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 state POLL_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 number WORD wValue; // varies according to request WORD wIndex; // varies according to request WORD 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 properly SETUP.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 requests if( (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 buffer ReportHandler_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 Table if(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 Handler 0, 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}; <--------+

 

转载地址:http://vtial.baihongyu.com/

你可能感兴趣的文章