?? device.c
字號:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) P2 = dat;
else dat = P2;
break;
case 0xA8:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) IE = dat;
else dat = IE;
break;
case 0xB0:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) P3 = dat;
else dat = P3;
break;
case 0xB8:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) IP = dat;
else dat = IP;
break;
case 0xC8:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) T2CON = dat;
else dat = T2CON;
break;
default:
dat = 0;
break;
}
break;
case USB_CMD_MEM_S_IRAM:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) *(PUINT8)pudp->down.u.mByte[0] = dat;
else dat = *(PUINT8)pudp->down.u.mByte[0];
break;
case USB_CMD_MEM_S_XRAM:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) *(PUINT8X)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 )= dat;
else dat = *(PUINT8X)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 );
break;
case USB_CMD_MEM_S_ROM:
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) pudp->up.mStatus = ERR_UNSUPPORT; /* 命令不支持 */
else dat = *(PUINT8C)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 );
break;
}
if ( ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) == 0 ) pudp->up.mBuffer[ l ] = dat; /* 返回讀出的數據 */
pudp->down.u.mByte[0] ++;
if ( pudp->down.u.mByte[0] == 0 ) pudp->down.u.mByte[1] ++;
}
if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) pudp->up.mLength = 0; /* 寫操作不返回數據 */
pudp->up.mStatus = ERR_SUCCESS;
}
}
else switch ( pudp->down.mCommand ) { /* 命令類型:實現特定功能,分析命令碼 */
case USB_CMD_GET_FW_INFO: /* 獲取調試固件程序的版本,并取消未完成的上傳數據塊 */
pudp->up.mBuffer[0] = THIS_FIRMWARE_VER;
pudp->up.mLength = 1;
pudp->up.mStatus = ERR_SUCCESS;
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ); /* 同步觸發位不變,設置USB端點2的IN正忙,返回NAK */
break;
case USB_CMD_GET_APP_INFO: /* 獲取當前應用系統的版本和說明字符串 */
pudp->up.mBuffer[0] = THIS_APP_SYS_VER;
l = 0;
str = THIS_APP_SYS_STR;
while ( pudp->up.mBuffer[ l ] = *str ) { l ++; str ++; } /* 說明字符串 */
pudp->up.mLength = 1 + sizeof( THIS_APP_SYS_STR );
pudp->up.mStatus = ERR_SUCCESS;
break;
/* case MY_CMD_CH451: */
default: /* 命令不支持 */
pudp->up.mLength = 0;
pudp->up.mStatus = ERR_UNSUPPORT;
break;
}
l = pudp->up.mLength + (UINT8)( & ( (USB_UP_PKT *)0 ) -> mBuffer );
Write374Byte( REG_USB_LENGTH, l );
Write374Block( RAM_ENDP2_TRAN, l, (PUINT8)&pudp->up ); // 向USB端點2的發送緩沖區寫入數據塊
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
// Write374Index( REG_USB_ENDP2 ); // 對于并口連接可以用本行及下面一行代替上一行的程序,減少寫一次index的時間,提高效率
// Write374Data( M_SET_EP2_TRAN_ACK( Read374Data0( ) ) ^ BIT_EP2_RECV_TOG );
}
}
break;
}
case USB_INT_EP2_IN: { // 批量端點上傳成功,未處理
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG );
// Write374Index( REG_USB_ENDP2 ); // 對于并口連接可以用本行及下面一行代替上一行的程序,減少寫一次index的時間,提高效率
// Write374Data( M_SET_EP2_TRAN_NAK( Read374Data0( ) ) ^ BIT_EP2_TRAN_TOG );
break;
}
case USB_INT_EP1_IN: { // 中斷端點上傳成功,未處理
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG );
break;
}
case USB_INT_EP0_SETUP: { // 控制傳輸
USB_SETUP_REQ SetupReqBuf;
l = Read374Byte( REG_USB_LENGTH );
if ( l == sizeof( USB_SETUP_REQ ) ) {
Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf );
SetupLen = SetupReqBuf.wLengthL;
if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F; // 限制總長度
l = 0; // 默認為成功并且上傳0長度
if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) { /* 只支持標準請求 */
l = 0xFF; // 操作失敗
}
else { // 標準請求
SetupReq = SetupReqBuf.bReq; // 請求碼
switch( SetupReq ) {
case DEF_USB_GET_DESCR:
switch( SetupReqBuf.wValueH ) {
case 1:
pDescr = (PUINT8)( &MyDevDescr[0] );
l = sizeof( MyDevDescr );
break;
case 2:
pDescr = (PUINT8)( &MyCfgDescr[0] );
l = sizeof( MyCfgDescr );
break;
case 3:
switch( SetupReqBuf.wValueL ) {
case 1:
pDescr = (PUINT8)( &MyManuInfo[0] );
l = sizeof( MyManuInfo );
break;
case 2:
pDescr = (PUINT8)( &MyProdInfo[0] );
l = sizeof( MyProdInfo );
break;
case 0:
pDescr = (PUINT8)( &MyLangDescr[0] );
l = sizeof( MyLangDescr );
break;
default:
l = 0xFF; // 操作失敗
break;
}
break;
default:
l = 0xFF; // 操作失敗
break;
}
if ( SetupLen > l ) SetupLen = l; // 限制總長度
l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次傳輸長度
Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加載上傳數據 */
SetupLen -= l;
pDescr += l;
break;
case DEF_USB_SET_ADDRESS:
SetupLen = SetupReqBuf.wValueL; // 暫存USB設備地址
break;
case DEF_USB_GET_CONFIG:
Write374Byte( RAM_ENDP0_TRAN, UsbConfig );
if ( SetupLen >= 1 ) l = 1;
break;
case DEF_USB_SET_CONFIG:
UsbConfig = SetupReqBuf.wValueL;
break;
case DEF_USB_CLR_FEATURE:
if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) { // 不是端點不支持
switch( SetupReqBuf.wIndexL ) {
case 0x82:
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) );
break;
case 0x02:
Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
break;
case 0x81:
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) );
break;
case 0x01:
Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) );
break;
default:
l = 0xFF; // 操作失敗
break;
}
}
else l = 0xFF; // 操作失敗
break;
case DEF_USB_GET_INTERF:
Write374Byte( RAM_ENDP0_TRAN, 0 );
if ( SetupLen >= 1 ) l = 1;
break;
case DEF_USB_GET_STATUS:
Write374Byte( RAM_ENDP0_TRAN, 0 );
Write374Byte( RAM_ENDP0_TRAN + 1, 0 );
if ( SetupLen >= 2 ) l = 2;
else l = SetupLen;
break;
default:
l = 0xFF; // 操作失敗
break;
}
}
}
else l = 0xFF; // 操作失敗
if ( l == 0xFF ) { // 操作失敗
Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) ); // STALL
}
else if ( l <= RAM_ENDP0_SIZE ) { // 上傳數據
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG ); // DATA1
}
else { // 下傳數據或其它
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG ); // DATA1
}
break;
}
case USB_INT_EP0_IN: {
switch( SetupReq ) {
case DEF_USB_GET_DESCR:
l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次傳輸長度
Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加載上傳數據 */
SetupLen -= l;
pDescr += l;
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG );
break;
case DEF_USB_SET_ADDRESS:
Write374Byte( REG_USB_ADDR, SetupLen );
default:
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 結束
break;
}
break;
}
case USB_INT_EP0_OUT: {
switch( SetupReq ) {
// case download:
// get_data;
// break;
case DEF_USB_GET_DESCR:
default:
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 結束
break;
}
break;
}
default: {
break;
}
}
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); // 清中斷標志
}
else if ( s & BIT_IF_USB_SUSPEND ) { // USB總線掛起
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND ); // 清中斷標志
Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF ); // 時鐘振蕩器停止振蕩,進入睡眠狀態
}
else if ( s & BIT_IF_WAKE_UP ) { // 芯片喚醒完成
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP ); // 清中斷標志
}
else { // 意外的中斷,不可能發生的情況,除了硬件損壞
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清中斷標志
}
/* IE0 = 0; 清中斷標志,與單片機硬件有關,對應于INT0中斷 */
}
/* 關閉CH374的所有USB通訊 */
void CH374OffUSB( void ) {
EX0 = 0; /* 關閉USB中斷,本程序中USB主機模式下使用查詢方式 */
Write374Byte( REG_USB_SETUP, 0x00 ); /* 關閉USB操作 */
// CH374Reset( ); /* 復位也可以 */
CH374DelaymS( 10 ); /* 為USB主從切換進行時間緩沖,這是必要的延時操作,用于讓計算機認為USB設備已經撤離 */
/* 如果CH374仍然連接著計算機,而程序使CH374切換到USB主機模式,那么會導致與計算機之間雙USB主機沖突 */
}
void device( ) {
CH374DeviceInit( ); /* 初始化USB設備模式 */
FreeUSBmS = 0; /* 清除USB空閑計時 */
while( 1 ) {
if ( IsKeyPress( ) ) { /* 有鍵按下 */
if ( FreeUSBmS >= 250 ) { /* USB空閑超過250毫秒 */
printf( "Exit USB device mode\n" );
CH374OffUSB( ); /* 關閉USB設備 */
return;
}
}
if ( FreeUSBmS < 250 ) FreeUSBmS ++; /* USB空閑計時,避免在USB通訊過程中由用戶按鍵導致USB主從切換 */
CH374DelaymS( 1 );
/* USB設備模式全部在中斷服務中處理,主程序可以做其它事情,當然也可以在主程序中使用查詢方式處理USB設備的通訊 */
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -