📄 usb.c
字号:
/* 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 + -