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

📄 usb.c

📁 PS2和USB兼容的鼠标源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* descript : 处理端点0的CLASS类型的SETUP包                                     */
/********************************************************************************/
void usb_pro_class_setup(void)
{   switch(EP0DATA_1)
    {
    case GET_REPORT:
         usb_get_report();
         break;
    case GET_IDLE:
         usb_get_idle();
         break;
    case GET_PROTOCOL:
         usb_get_protocol();
         break;
    case SET_REPORT:
         usb_stall_inout();
         break;
    case SET_IDLE:
         usb_set_idle();
         break;
    case SET_PROTOCOL:
         usb_set_protocol();
         break;
    default:
         usb_stall_inout();
         break;
    }
}

/********************************************************************************/
/* function : usb_pro_vendor_setup()                                            */
/* created  : hw-chen                                                           */
/* descript : 处理端点的VENDOR类型的SETUP包                                     */
/********************************************************************************/
void usb_pro_vendor_setup(void)
{   if((EP0DATA_1==0x2)&&(EP0DATA_2==0x17)&&(EP0DATA_4==0x1))
    {   ctrl_logic_bit=0x1;
        return;
    }
    if((EP0DATA_1==0x2)&&(EP0DATA_2==0x17)&&(EP0DATA_4==0x0))
    {   ctrl_logic_bit=0x1;
        return;
    }
    else
    {   return;
    }
}
/********************************************************************************/
/* function : usb_pro_setup_request()                                           */
/* created  : hw-chen                                                           */
/* descript : 处理端点0的SETUP包                                                */
/*            SETUP数据包的TOGGLE=0x0,DATAVALID=0x1,共10字节长度                */
/********************************************************************************/
void usb_pro_setup_request(void)
{   unsigned char request;
	dev_status.cur_addr &= 0x7F;    //* clear the address flag
    if((EP0CNT&(DATAVALID|DATATOGGLE|COUNT_MASK))!=(DATAVALID|0xA))
    {   usb_set_mode(MODE_ACK_IN_STATUS_OUT);  //* invalid request, stall
        return;
    }
    request=EP0DATA_0;
    if((request&REQ_MASK)==CLASS)
    {   usb_pro_class_setup();
        return;
    }
    if((request&REQ_MASK)==STANDARD)
    {   usb_pro_stander_setup();
        return;
    }
    if((request&REQ_MASK)==VENDOR)
    {   usb_pro_vendor_setup();
        return;
    }
    else
    {   return;
    }
}

/********************************************************************************/
/* function : usb_endpoint_0_isr()                                              */
/* created  : hw-chen                                                           */
/* descript : USB的端点0中断                                                    */
/********************************************************************************/
void usb_endpoint_0_isr(void)
{   unsigned char mdata;
    PUSHA();
    PUSHX();

    mdata=EP0MODE;

    if((mdata&0x10)!=0x10)      //* 如果没有ACK'D
    {   EP0CNT =0x0;            //* 设置长度
        EP0MODE=MODE_ACK_IN_STATUS_OUT;
        goto isr_out;
    }
    if((mdata&0x80)==0x80)      //* 如果收到SETUP
    {   usb_pro_setup_request();//* handle setup request
        goto isr_out;
    }
    if((mdata&0x40)==0x40)      //* 如果收到IN
    {   usb_pro_in_request();   //* handle in request
        goto isr_out;
    }
    if((mdata&0x20)==0x20)      //* 如果收到OUT
    {   EP0CNT =0x0;            //* 设置长度
        EP0MODE=MODE_ACK_IN_STATUS_OUT;
        goto isr_out;
    }
    else
    {   EP0CNT =0x0;           //* 设置长度
        EP0MODE=MODE_ACK_IN_STATUS_OUT;
        goto isr_out;
    }
isr_out:
    POPX();
    POPA();
    return;
}

/********************************************************************************/
/* function : usb_endpoint_1_isr()                                              */
/* created  : hw-chen                                                           */
/* descript : USB的数据输入端点中断                                             */
/********************************************************************************/
void usb_endpoint_1_isr(void)
{   unsigned char mdata;
    PUSHA();
    PUSHX();
    mdata=EP1CNT;
    if((EP1MODE&0x10))
    {   EP1CNT =0x0;
        EP1MODE=MODE_NAK_IN;
    }
    else
    {   EP1CNT =0x0;
        EP1MODE=MODE_NAK_IN;
    }
    POPX();
    POPA();
    return;
}

/********************************************************************************/
/* function : usb_idle_counter()                                            */
/* created  : hw-chen                                                           */
/* descript : 如果我们设置了IDLE周期,并且IDLE周期计数器已经为0,那么无论如何,我  */
/*            们需要发送一个数据包给主机,所以设置变化标记                       */
/********************************************************************************/
unsigned char usb_idle_counter(void)
{   if((mouse_xmit_state.idle_period==0x0))
    {   return 0x0;
    }
    mouse_xmit_state.idle_counter-=0x1;
    if((mouse_xmit_state.idle_counter!=0x0))
    {   return 0x0;
    }
    mouse_xmit_state.idle_counter=mouse_xmit_state.idle_period;
    return 0x1;
}

/********************************************************************************/
/* function : usb_main_tasking()                                                */
/* created  : hw-chen                                                           */
/* descript : 这个函数4MS调用一次,维护IDLE计数器,如果设置了IDLE周期,即使没有    */
/*            鼠标运动或者按键操作,它都会按照一定的频率发送数据包给主机,如果    */
/*            有鼠标运动或者按键,它也会发送数据包给主机                         */
/********************************************************************************/
void usb_main_tasking(void)
{   unsigned char mdata;
    mdata=EP1CNT;
    mdata=EP1MODE;
    if((mdata&USB_MODE_MASK)!=MODE_NAK_IN)          //* 如果USB不处于NAK-IN状态,是不能发送数据包给主机的
    {   return;
    }
    mouse_status.change_flag|=mouse_poll_buttons(); //* 查看是否有按键动作
    mouse_status.change_flag|=mouse_poll_adns();    //* 读取光学器件,查看鼠标是否有移动
    mouse_status.change_flag|=usb_idle_counter();   //* 处理IDLE计数器
    if(mouse_status.change_flag==0x0)               //* 没有任何数据发送
    {   return;
    }
    EP1DATA_0=mouse_status.button_byte&0x7; //* 通用的M.R.L三个按键
    EP1DATA_1=-mouse_status.x_count;
    EP1DATA_2=mouse_status.y_count;
    EP1DATA_3=mouse_status.z_count;
    if((ctrl_logic_bit==0x0))
    {   if(mouse_status.button_byte&0x08)   //* 扩展的L键
        {   EP1DATA_4=0x1;
        }
        if(mouse_status.button_byte&0x10)   //* 扩展的R键
        {   EP1DATA_4=0xFF;
        }
        else
        {   EP1DATA_4=0x0;
        }
    }
    else
    {   if(mouse_status.button_byte&0x08)   //* 扩展的L键
        {   EP1DATA_0|=0x40;
        }
        if(mouse_status.button_byte&0x10)   //* 扩展的R键
        {   EP1DATA_0|=0x80;
        }
        EP1DATA_4=0x0;
    }
    mouse_status.x_count=0x0;
    mouse_status.y_count=0x0;
    mouse_status.z_count=0x0;
    EP1CNT=DATA_toggle_bit|0x5;
    EP1MODE=MODE_ACK_IN;
    if((DATA_toggle_bit==0x80))
    {   DATA_toggle_bit=0x0;
    }
    else
    {   DATA_toggle_bit=0x80;
    }
    mouse_xmit_state.idle_counter=mouse_xmit_state.idle_period;
    mouse_status.change_flag=0x0;
}
/********************************************************************************/
/* function : usb_print_infor()                                                 */
/* created  : hw-chen                                                           */
/* descript : 通过USB的EP1发送调试信息                                          */
/********************************************************************************/
void usb_print_infor(unsigned char data)
{   unsigned char mdata;
    mdata=EP1MODE;
    mdata=EP1CNT;
    EP1DATA_0=data;          //* 装入发送的数据
    EP1CNT =DATA_toggle_bit|0x1;
    EP1MODE=MODE_ACK_IN;
    if((DATA_toggle_bit==0x80))
    {   DATA_toggle_bit=0x0;
    }
    else
    {   DATA_toggle_bit=0x80;
    }
}

/********************************************************************************/
/* function : usb_start()                                                       */
/* created  : hw-chen                                                           */
/* descript : 启动USB用户模式,设置DEVICE的SELECTION,设置成为未配置状态,允许SIU  */
/*            地址为0x0,允许USB上拉                                             */
/********************************************************************************/
void usb_start(void)
{   volatile unsigned char mdata;
    P10CR    = 0x00;
    P11CR    = 0x00;
    USBCR    = 0x80;            //* 允许USB,地址设置成为0x0
    USBXCR   = 0x80;            //* 允许USB上拉电阻,上拉D-引脚
    EP0MODE  = stall_inout;     //* ACK SETUP/STALL IN/OUT
    asm("NOP");
    mdata    = EP0MODE;         //* 读取操作
    INT_MSK1|= (INT_MSK1_USB_ACTIVITY|INT_MSK1_USB_BUS_RESET|INT_MSK1_USB_EP0);
    dev_status.cur_addr     = 0x0;
    dev_status.configure    = 0x0;
    dev_status.rem_wakeup   = 0x0;
    dev_status.dev_status   = 0x0;
    dev_status.ept1_stall   = 0x0;
    dev_status.ept_status   = 0x0;
    dev_status.protocol     = 0x0;
}


/********************************************************************************/
/* function : usb_main_process()                                                */
/* created  : hw-chen                                                           */
/* descript : 在调用它之前所有的USB变量需要初始化                               */
/********************************************************************************/
void usb_main_process(void)
{   usb_start();
    while(1)
    {   if((msecond_status.ms_flag&ONE_MSEC_FLAG)==0x0)    //* 如果没有到1MS
        {   continue;
        }
        if((msecond_status.ms_counter&0x3)==0x0)    //* 4MS定时器
        {   if((dev_status.configure))
            {   usb_main_tasking();

            }
        }
        msecond_status.ms_flag &= ~ONE_MSEC_FLAG;
    }
}

⌨️ 快捷键说明

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