?? 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 + -