⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.c

📁 PS2和USB兼容的鼠标源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    0x03,       		//* 人机接口设备(HID)类
    0x01,       		//* 使用的子类:支持BIOS根启动Boot的子类
    0x02,       		//* 使用的协议:鼠标
    0x00,       		//* 接口描述符字符串索引
    0x09,       		//* HID描述符的字节数大小
    DESCRIPTOR_HID,       	//* HID描述符类型编号
    0x10,       		//* HID类协议版本号,LO为10
    0x01,       		//* HID类协议版本号,LO为1,所以为1.10
    0x00,       		//* 固件的国家地区代号,0x21为美国
    0x01,       		//* 下级描述符的数量,为1个
    0x22,       		//* 下级描述符为报告描述符
    0x3b,       		//* 下级描述符的长度的低字节
    0x00,       		//* 下级描述符的长度的高字节
    0x07,       		//* 端点描述符的字节数大小
    DESCRIPTOR_ENDPOINT,     	//* 端点描述符类型编号
    0x81,       		//* 端点号0x1,输入端点
    0x03,       		//* 使用的传输类型:中断传输
    0x05,       		//* 该端点支持的最大包尺寸,0x5字节
    0x00,
    0x0a        		//* 中断扫描时间:设置为10ms
};

volatile const    char * g_cdata;
volatile   signed char * g_mdata;
volatile unsigned char   g_lenth;
/********************************************************************************/
/* function : load_rom_ctrl_buffer()                                            */
/* created  : hw-chen                                                           */
/* descript : copy data from a ROM source                                       */
/********************************************************************************/
void load_rom_ctrl_buffer(void)
{   asm("PUSH   A");
    asm("PUSH   X");
    asm("MOV    X,0");
    asm("ROM_COPY:");
    asm("PUSH   X");
    asm("MOV    A,[_g_cdata]");
    asm("MOV    X,[_g_cdata+1]");
    asm("INC    [_g_cdata+1]");
    asm("ADC    [_g_cdata],0");
    asm("ROMX    ");
    asm("POP    X");
    asm("MOV    REG[X+0x50],A");
    asm("INC    X");
    asm("MOV    A,X");
    asm("CMP    A,[_g_lenth]");
    asm("JC     ROM_COPY");
    asm("POP    X");
    asm("POP    A");
}

/********************************************************************************/
/* function : load_ram_ctrl_buffer()                                            */
/* created  : hw-chen                                                           */
/* descript : copy data from a RAM source                                       */
/********************************************************************************/
void load_ram_ctrl_buffer(void)
{   asm("PUSH   A");
    asm("PUSH   X");
    asm("MOV    X,0");
    asm("RAM_COPY:");
    asm("MVI    A,[_g_cdata+1]");
    asm("MOV    REG[X+0x50],A");
    asm("INC    X");
    asm("MOV    A,X");
    asm("CMP    A,[_g_lenth]");
    asm("JC     RAM_COPY");
    asm("POP    X");
    asm("POP    A");
}

/********************************************************************************/
/* function : usb_error_clear()                                                 */
/* created  : hw-chen                                                           */
/* descript : 如果端点出现错误,需要清除                                         */
/********************************************************************************/
void usb_error_clear(void)
{   EP0CNT = 0x0;
    EP0MODE= MODE_ACK_IN_STATUS_OUT;
}
/********************************************************************************/
/* function : usb_set_mode()                                                    */
/* created  : hw-chen                                                           */
/* descript : 设置控制端点模式                                                  */
/********************************************************************************/
void usb_set_mode(unsigned char mode)
{   EP0CNT = 0x0;
    EP0MODE= mode;
}

/********************************************************************************/
/* function : usb_load_ctrl_buffer()                                            */
/* created  : hw-chen                                                           */
/* descript : 向端点0的控制缓冲区写入数据                                       */
/********************************************************************************/
char usb_load_ctrl_buffer(void)
{   if((usb_transmit.length>=0x8))
    {   usb_transmit.length-=0x8;
        g_lenth=0x8;
    }
    else
    {   g_lenth=usb_transmit.length;
        usb_transmit.length=0x0;
    }
    if((usb_transmit.cflag))
    {   g_cdata=usb_transmit.cdata;
        usb_transmit.cdata+=g_lenth;
        load_rom_ctrl_buffer();
        return g_lenth;
    }
    else
    {   g_mdata=usb_transmit.mdata;
        load_rom_ctrl_buffer();
        usb_transmit.mdata+=g_lenth;
        return g_lenth;
    }
}


/********************************************************************************/
/* function : usb_control_read()                                                */
/* created  : hw-chen                                                           */
/* descript : 控制读取                                                          */
/*            this routine is called after a setup has been received that is    */
/*            requesting a data response from the mouse. upon entry,            */
/*            usb_transmit has been initialized to point to the data buffer     */
/*            that needs to be tranmsitted.  usb_control_read adjusts the       */
/*            length of the data to be returned if the host requested less data */
/*            than the actual length of the buffer.  it then loads the fifo     */
/*            with the first chunck of data and prepares the SIE to ack with    */
/*            the data.                                                         */
/********************************************************************************/
void usb_control_read(void)
{   if((!EP0DATA_7)&&(EP0DATA_6<usb_transmit.length))
    {   usb_transmit.length = EP0DATA_6;
    }
    byte_count=0x0;
    if((usb_transmit.length))
    {   byte_count=usb_load_ctrl_buffer();    //data to send. Load FIFO with first chunck
    }
    if((ctrl_toggle_bit==0x1))
    {   byte_count|=DATATOGGLE;             //* 设置TOGGLE
        ctrl_toggle_bit=0x0;
    }
    else
    {   ctrl_toggle_bit=0x1;
    }
    EP0CNT = byte_count;                    //* 设置长度
    EP0MODE= MODE_ACK_IN_STATUS_OUT;    //* and set the ep mode to ack the next IN with the data.
}


/********************************************************************************/
/* function : usb_get_status()                                                  */
/* created  : hw-chen                                                           */
/* descript : 获取状态                                                          */
/*            This routine checks for either a request to get the device        */
/*            status, the interface status, or the endpoint status,             */
/*            sets up usb_transmit to point to the appropriate status, and      */
/*            calls usb_control_read to initiate the transfer.                  */
/********************************************************************************/
void usb_get_status(void)
{   switch(EP0DATA_0)
    {
    case (DEV_2_HST|STANDARD|DEVICE):
         usb_transmit.length= 0x2;                      //* send 2 bytes
         usb_transmit.mdata = &dev_status.rem_wakeup;   //* point at remote wakeup status
         usb_transmit.cflag = 0x0;
         break;
    case (DEV_2_HST|STANDARD|INTERFACE):
         usb_transmit.length= 0x2;
         usb_transmit.cdata = get_interface_status_table;
         usb_transmit.cflag = 0x1;
         break;
    case (DEV_2_HST|STANDARD|ENDPOINT):
         usb_transmit.length= 0x2;                      //* send two bytes
         usb_transmit.mdata = &dev_status.ept1_stall;   //* point at endpoint stall status
         usb_transmit.cflag = 0x0;
         break;
    default:
         usb_set_mode(stall_inout);                     //* bogus request, complain
         return;
    }
    usb_control_read();                                 //* initiate transfer
}

/********************************************************************************/
/* function : usb_get_string()                                                  */
/* created  : hw-chen                                                           */
/* descript : 处理字符串描述符                                                  */
/********************************************************************************/
int usb_get_string(void)
{   switch(EP0DATA_2)
    {
    case 0x0:
         usb_transmit.length= sizeof(string_language_table);
         usb_transmit.cdata = string_language_table;
         usb_transmit.cflag = 0x1;
         break;
    case 0x1:
         usb_transmit.length= sizeof(string_description_one);
         usb_transmit.cdata = string_description_one;
         usb_transmit.cflag = 0x1;
         break;
    case 0x2:
         usb_transmit.length= sizeof(string_description_two);
         usb_transmit.cdata = string_description_two;
         break;
    case 0x3:
         usb_transmit.length= sizeof(string_description_thr);
         usb_transmit.cdata = string_description_thr;
         usb_transmit.cflag = 0x1;
         break;
    case 0x4:
         usb_transmit.length= sizeof(string_description_for);
         usb_transmit.cdata = string_description_for;
         usb_transmit.cflag = 0x1;
         break;
    case 0x5:
         usb_transmit.length= sizeof(string_description_fiv);
         usb_transmit.cdata = string_description_fiv;
         usb_transmit.cflag = 0x1;
         break;
    default:
         usb_set_mode(stall_inout);
         return 0x0;
    }
    return 0x1;
}
/********************************************************************************/
/* function : usb_get_descriptor()                                              */
/* created  : hw-chen                                                           */
/* descript : 获取描述符                                                        */
/********************************************************************************/
void usb_get_descriptor(void)
{   unsigned char rdata=EP0DATA_0;
    if((rdata!=usb_i_type_device)&&(rdata!=usb_i_type_endpoint)&&(rdata!=usb_i_type_interface))
    {   usb_set_mode(stall_inout);
        return;
    }
    switch(EP0DATA_3)
    {
    case DESCRIPTOR_DEVICE :
         usb_transmit.length= sizeof(st_descript_device);
         usb_transmit.cdata = descriptor_device;
         usb_transmit.cflag = 0x1;
         break;
    case DESCRIPTOR_CONFIGURATION :
         usb_transmit.length= sizeof(st_all_confiure);
         usb_transmit.cdata = &all_confiure[0x0];
         usb_transmit.cflag = 0x1;
         break;
    case DESCRIPTOR_STRING :
         if(usb_get_string()==0x0)
         {  return;
         }
         break;
    case DESCRIPTOR_HID :
         usb_transmit.length= sizeof(st_descript_hid);
         usb_transmit.cdata = &all_confiure[sizeof(st_descript_configure)+sizeof(st_descript_interface)];
         usb_transmit.cflag = 0x1;
         break;
    case DESCRIPTOR_REPORT :
         usb_transmit.length= sizeof(HID_report_table);
         usb_transmit.cdata = HID_report_table;
         usb_transmit.cflag = 0x1;
         break;
    default :
         usb_set_mode(stall_inout);
         return;
    }
    ctrl_toggle_bit=0x1;
    usb_control_read();
}

/********************************************************************************/
/* function : usb_get_configuration()                                           */
/* created  : hw-chen                                                           */
/* descript : 获取配置                                                          */
/********************************************************************************/
void usb_get_configuration(void)
{   if((EP0DATA_0!=usb_i_type_device))
    {   usb_set_mode(stall_inout);
        return;
    }
    usb_transmit.length= 0x1;                       //configuration is 1-byte long

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -