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

📄 usb.c

📁 PS2和USB兼容的鼠标源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    usb_transmit.mdata = &dev_status.configure;     //point at it
    usb_transmit.cflag = 0x0;
    usb_control_read();                             //initiate transfer
}

/********************************************************************************/
/* function : usb_get_report()                                                  */
/* created  : hw-chen                                                           */
/* descript : 获取报告                                                          */
/********************************************************************************/
void usb_get_report(void)
{   if((EP0DATA_0!=usb_i_class_interface))
    {   usb_set_mode(stall_inout);
        return;
    }
    usb_transmit.length= (dev_status.protocol == REPT_PROTOCOL ? 4 : 3);
    usb_transmit.mdata = &mouse_status.button_byte;
    usb_transmit.cflag = 0x0;
    usb_control_read();
}

/********************************************************************************/
/* function : usb_get_protocol()                                                */
/* created  : hw-chen                                                           */
/* descript : 获取协议                                                          */
/********************************************************************************/
void usb_get_protocol(void)
{   if((EP0DATA_0!=usb_i_class_interface))
    {   usb_set_mode(stall_inout);
        return;
    }
    usb_transmit.length= 0x1;                       //* set length of protocol
    usb_transmit.mdata = &dev_status.protocol;      //* aim usb_transmit at it
    usb_transmit.cflag = 0x0;
    usb_control_read();                             //* initiate transfer
}


/********************************************************************************/
/* function : usb_get_idle()                                                    */
/* created  : hw-chen                                                           */
/* descript : 获取状态                                                          */
/********************************************************************************/
void usb_get_idle(void)
{   if((EP0DATA_0!=usb_i_class_interface))
    {   usb_set_mode(stall_inout);
        return;
    }
    usb_transmit.length= 0x1;                               //idle is 1-byte long
    usb_transmit.mdata = &mouse_xmit_state.idle_period;     //point at it
    usb_transmit.cflag = 0x0;
    usb_control_read();                                     //initiate transfer
}

/********************************************************************************/
/* function : usb_set_configuration()                                           */
/* created  : hw-chen                                                           */
/* descript : 设置配置                                                          */
/********************************************************************************/
void usb_set_configuration(void)
{   if((EP0DATA_0!=usb_o_type_device))
    {   usb_set_mode(stall_inout);
        return;
    }
    if((EP0DATA_2!=UNCONFIG)&&(EP0DATA_2!=CONFIGURED))
    {   usb_set_mode(stall_inout);
        return;
    }
    dev_status.configure = EP0DATA_2;       //* set the configuration
    dev_status.ept1_stall= 0x0;             //* and clear EP1 stall
    EP1CNT &= ~DATATOGGLE;                  //* clear EP1's data toggle
    if((dev_status.configure==UNCONFIG))    //* not configured -- disable EP1 from responding
    {   EP1MODE=MODE_DISABLE;
    }
    else                                    //* configured -- NAK traffic on EP1
    {   DATA_toggle_bit=0x0;                 //*
        EP1MODE=MODE_NAK_IN;
    }
    usb_set_mode(MODE_STATUS_ONLY);
}

/********************************************************************************/
/* function : usb_set_address()                                                 */
/* created  : hw-chen                                                           */
/* descript : 设置地址                                                          */
/*            the address change cannot actually take place until the ensuing   */
/*            status-in is received from the host                               */
/*            so we just save the address and set a flag to indicate that a new */
/*            address was just received.  the code that handles ins will        */
/*            recognize this and set the address properly                       */
/********************************************************************************/
void usb_set_address(void)
{   if((EP0DATA_0!=usb_o_type_device))
    {   usb_set_mode(stall_inout);
        return;
    }
    dev_status.cur_addr=0x80|EP0DATA_2;
    usb_set_mode(MODE_STATUS_ONLY);
}


/********************************************************************************/
/* function : usb_clr_feature()                                                 */
/* created  : hw-chen                                                           */
/* descript : 清除标记                                                          */
/*            resume是由PC主机叫醒USB设备,而wake-up是由USB设备叫醒PC主机        */
/*            这个线程主要检查两个功能:                                         */
/*            1.清除USB设备叫醒PC主机请求                                       */
/*            2.清除端点1的STALL请求                                            */
/********************************************************************************/
void usb_clr_feature(void)
{   if((EP0DATA_0==usb_o_type_device)&&(EP0DATA_2==DEV_REM_WAKEUP)&&(EP0DATA_3==0x0))
    {   dev_status.rem_wakeup=DIS_REM_WAKEUP; /* disable remote wakeup */
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    if((EP0DATA_0==usb_o_type_endpoint)&&(dev_status.configure==CONFIGURED)&&(EP0DATA_2==EPT_STALL)&&(EP0DATA_3==0x0)&&(EP0DATA_4==0x81))
    {   dev_status.ept1_stall=0x0;      //* ep1 stall request not stalled
        EP1CNT &= ~DATATOGGLE;          //* clear data 0/1 bit
        EP1MODE = MODE_NAK_IN_OUT;  //* nak anything on endpoint 1 until ready
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    else
    {   usb_set_mode(stall_inout);
        return;
    }
}

/********************************************************************************/
/* function : usb_set_feature()                                                 */
/* created  : hw-chen                                                           */
/* descript : 设置标记                                                          */
/********************************************************************************/
void usb_set_feature(void)
{   if((EP0DATA_0==usb_o_type_device)&&(EP0DATA_2==DEV_REM_WAKEUP)&&(EP0DATA_3==0x0))
    {   dev_status.rem_wakeup=ENB_REM_WAKEUP;     //* set remote wakeup
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    if((EP0DATA_0==usb_o_type_endpoint)&&(dev_status.configure==CONFIGURED)&&(EP0DATA_2==EPT_STALL)&&(EP0DATA_3==0x0)&&(EP0DATA_4==0x81))
    {   dev_status.ept1_stall=0x1;      //* mark endpoint as stalled
        EP1MODE=stall_inout;            //* stall traffic on endpoint 1
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    else
    {   usb_set_mode(stall_inout);
        return;
    }
}


/********************************************************************************/
/* function : usb_set_idle()                                                    */
/* created  : hw-chen                                                           */
/* descript : 设置空闲                                                          */
/*            this routine is entered whenever a set idle request is received.  */
/*            see the hid spec for the rules on setting idle periods.           */
/********************************************************************************/
void usb_set_idle(void)
{   if((EP0DATA_0!=usb_o_class_interface)&&(EP0DATA_0!=usb_o_class_endpoint))
    {   usb_set_mode(stall_inout);
        return;
    }
    if((EP0DATA_4)||(EP0DATA_5))
    {   usb_set_mode(stall_inout);
        return;
    }
    if((mouse_xmit_state.idle_period==0x0))//current idle setting is off. set both the new period and the counter
    {   mouse_xmit_state.idle_period = EP0DATA_3;
        mouse_xmit_state.idle_counter= mouse_xmit_state.idle_period;
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    if((mouse_xmit_state.idle_counter<=0x2)) // counter for current idle period is nearly expiring. leave it alone, but set new idle period
    {   mouse_xmit_state.idle_period = EP0DATA_3;
        usb_set_mode(MODE_STATUS_ONLY);
        return;
    }
    if(EP0DATA_3>mouse_xmit_state.idle_counter) //* new period is shorter than the old one.  Force current idle period to expire soon,and set new idle period
    {   mouse_xmit_state.idle_period = EP0DATA_3;
        mouse_xmit_state.idle_counter = 1;
    }
    else //new period is longer than old one. set new idle period, and adjust current period to be equal to the new period, minus the counts that have already expired for the old one
    {   mouse_xmit_state.idle_period  = EP0DATA_3;
        mouse_xmit_state.idle_counter = EP0DATA_3 - mouse_xmit_state.idle_period;
    }
    usb_set_mode(MODE_STATUS_ONLY);
    return;
}

/********************************************************************************/
/* function : usb_set_protocol()                                                */
/* created  : hw-chen                                                           */
/* descript : 设置协议                                                          */
/********************************************************************************/
void usb_set_protocol(void)
{   if(((EP0DATA_0!=usb_o_class_interface)&&(EP0DATA_0!=usb_o_class_endpoint))||(EP0DATA_4)||(EP0DATA_5)||(EP0DATA_2>REPT_PROTOCOL))
    {   usb_set_mode(stall_inout);
    }
    else
    {   dev_status.protocol = EP0DATA_2;    //set the new protocol
        usb_set_mode(MODE_STATUS_ONLY);         //acknowledge
    }
}

/********************************************************************************/
/* function : usb_stall_inout()                                                 */
/* created  : hw-chen                                                           */
/* descript : 停止端点0                                                         */
/********************************************************************************/
void usb_stall_inout(void)
{   usb_set_mode(stall_inout);
}

/********************************************************************************/
/* function : usb_pro_in_request()                                              */
/* created  : hw-chen                                                           */
/* descript : HOST通过ACK确认端点零的IN数据包                                   */
/*            对于端点零,只要SETUP或者OUT事务更新了,EP0CNT寄存器就不能写,需要   */
/*            读取它就解锁                                                      */
/********************************************************************************/
void usb_pro_in_request(void)
{   byte_count=EP0CNT;
    byte_count=0x0;
    if((usb_transmit.length))               //* if we've stuff to send, load it into fifo
    {   byte_count=usb_load_ctrl_buffer();
    }
    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.
    if((dev_status.cur_addr&0x80))          //* 如果地址在SETUP阶段更新了,需要在IN包更新地址
    {   USBCR=dev_status.cur_addr;          //* enable the new address
        dev_status.cur_addr&=0x7F;          //* and clear the new address flag
    }
}

/********************************************************************************/
/* function : usb_pro_stander_setup()                                           */
/* created  : hw-chen                                                           */
/* descript : 处理端点0的标准类型的SETUP包                                      */
/********************************************************************************/
void usb_pro_stander_setup(void)
{   switch(EP0DATA_1)
    {
    case GET_STATUS:
         usb_get_status();
         break;
    case CLR_FEATURE:
         usb_clr_feature();
         break;
    case SET_FEATURE:
         usb_set_feature();
         break;
    case SET_ADDRESS:
         usb_set_address();
         break;
    case GET_DESCRIPTOR:
         usb_get_descriptor();
         break;
    case GET_CONFIGURATION:
         usb_get_configuration();
         break;
    case SET_CONFIGURATION:
         usb_set_configuration();
         break;
    case GET_INTERFACE:
         usb_get_status();
         break;
    default:
         usb_stall_inout();
         break;
    }
}


/********************************************************************************/
/* function : usb_pro_class_setup()                                             */
/* created  : hw-chen                                                           */

⌨️ 快捷键说明

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