日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

沁恒CH583 USB 自定义HID调试记录

發(fā)布時(shí)間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 沁恒CH583 USB 自定义HID调试记录 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用USB HID主要是為了免驅(qū),通過(guò)自定義USB HID可以利用USB口來(lái)做很多事,比如串口打印,串口升級(jí)都可以通過(guò)usb口來(lái)實(shí)現(xiàn),這樣可以省去一個(gè)USB轉(zhuǎn)串口器件同時(shí)也不用裝驅(qū)動(dòng),如下實(shí)現(xiàn)可以通過(guò)usb hid進(jìn)行自定義收發(fā),類似串口自定義收發(fā)。

如下代碼基本都是基于沁恒EVT改造而來(lái),

GitHub - iot-lorawan/ch58x_usbhid_custom: custom usb hid in ch58x

usb配置相關(guān),該配置聲明了使用usb 自定義hid,

#include "CH58x_common.h" #define RepDataLoadLen 64#define DevEP0SIZE 0x40 // 設(shè)備描述符 /* Device Descriptor */ const UINT8 MyDevDescr[] = {0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, DevEP0SIZE,0x86, 0x1A, 0xE1, 0xE6,0x00, 0x01, 0x01, 0x02, 0x00, 0x01, };/* USB配置描述符(全速) */ UINT8 MyCfgDescr[ ] = {0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23, //配置描述符0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05, //接口描述符0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00, //HID類描述符0x07,0x05,0x81,0x03,0x40,0x00,0x01, //端點(diǎn)描述符(全速間隔時(shí)間改成1ms)0x07,0x05,0x01,0x03,0x40,0x00,0x01, //端點(diǎn)描述符 };/* USB報(bào)告描述符 */ const UINT8 CompatibilityHIDRepDesc[ ] = {0x06, 0x00,0xff,0x09, 0x01,0xa1, 0x01, //集合開(kāi)始0x09, 0x02, //Usage Page 用法0x15, 0x00, //Logical Minimun0x26, 0x00,0xff, //Logical Maximun0x75, 0x08, //Report Size0x95, RepDataLoadLen, //Report Counet0x81, 0x06, //Input0x09, 0x02, //Usage Page 用法0x15, 0x00, //Logical Minimun0x26, 0x00,0xff, //Logical Maximun0x75, 0x08, //Report Size0x95, RepDataLoadLen, //Report Counet0x91, 0x06, //Output0xC0 };/* Language Descriptor */ const UINT8 MyLangDescr[] = {0x04, 0x03, 0x09, 0x04 };/* Manufactor Descriptor */ const UINT8 MyManuInfo[] = {0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 };/* Product Information */ const UINT8 MyProdInfo[] = {0x0C, 0x03, 'C', 0, 'H', 0, '1', 0, '0', 0, 'x', 0 };/* USB序列號(hào)字符串描述符 */ const UINT8 MySerNumInfo[ ] = {/* 0123456789 */22,03,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0 };/* USB設(shè)備限定描述符 */ const UINT8 MyUSBQUADesc[ ] = {0x0A, 0x06, 0x00, 0x02, 0xFF, 0x00, 0xFF, 0x40, 0x01, 0x00, };/**********************************************************/ uint8_t DevConfig, Ready; uint8_t SetupReqCode; uint16_t SetupReqLen; const uint8_t *pDescr; uint8_t Report_Value = 0x00; uint8_t Idle_Value = 0x00; uint8_t USB_SleepStatus = 0x00; /* USB睡眠狀態(tài) *//*鼠標(biāo)鍵盤(pán)數(shù)據(jù)*/ uint8_t HIDMouse[4] = {0x0, 0x0, 0x0, 0x0}; uint8_t HIDKey[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /******** 用戶自定義分配端點(diǎn)RAM ****************************************/ __attribute__((aligned(4))) uint8_t EP0_Databuf[64 + 64 + 64]; //ep0(64)+ep4_out(64)+ep4_in(64) __attribute__((aligned(4))) uint8_t EP1_Databuf[64 + 64]; //ep1_out(64)+ep1_in(64) __attribute__((aligned(4))) uint8_t EP2_Databuf[64 + 64]; //ep2_out(64)+ep2_in(64) __attribute__((aligned(4))) uint8_t EP3_Databuf[64 + 64]; //ep3_out(64)+ep3_in(64)

USB邏輯交互,放在usb中斷函數(shù)里執(zhí)行

void USB_DevTransProcess(void) {uint8_t len, chtype;uint8_t intflag, errflag = 0;intflag = R8_USB_INT_FG;if(intflag & RB_UIF_TRANSFER){if((R8_USB_INT_ST & MASK_UIS_TOKEN) != MASK_UIS_TOKEN) // 非空閑{switch(R8_USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))// 分析操作令牌和端點(diǎn)號(hào){case UIS_TOKEN_IN:{switch(SetupReqCode){case USB_GET_DESCRIPTOR:len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen; // 本次傳輸長(zhǎng)度memcpy(pEP0_DataBuf, pDescr, len); /* 加載上傳數(shù)據(jù) */SetupReqLen -= len;pDescr += len;R8_UEP0_T_LEN = len;R8_UEP0_CTRL ^= RB_UEP_T_TOG; // 翻轉(zhuǎn)break;case USB_SET_ADDRESS:R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | SetupReqLen;R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;break;case USB_SET_FEATURE:break;default:R8_UEP0_T_LEN = 0; // 狀態(tài)階段完成中斷或者是強(qiáng)制上傳0長(zhǎng)度數(shù)據(jù)包結(jié)束控制傳輸R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;break;}}break;case UIS_TOKEN_OUT:{len = R8_USB_RX_LEN;if(SetupReqCode == 0x09){if(pEP0_DataBuf[0])PRINT("Light on Num Lock LED!\n");else if(pEP0_DataBuf[0] == 0)PRINT("Light off Num Lock LED!\n");}}break;case UIS_TOKEN_OUT | 1:{if(R8_USB_INT_ST & RB_UIS_TOG_OK){ // 不同步的數(shù)據(jù)包將丟棄R8_UEP1_CTRL ^= RB_UEP_R_TOG;len = R8_USB_RX_LEN;DevEP1_OUT_Deal(len);}}break;case UIS_TOKEN_IN | 1:R8_UEP1_CTRL ^= RB_UEP_T_TOG;R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;break;case UIS_TOKEN_OUT | 2:{if(R8_USB_INT_ST & RB_UIS_TOG_OK){ // 不同步的數(shù)據(jù)包將丟棄R8_UEP2_CTRL ^= RB_UEP_R_TOG;len = R8_USB_RX_LEN;DevEP2_OUT_Deal(len);}}break;case UIS_TOKEN_IN | 2:R8_UEP2_CTRL ^= RB_UEP_T_TOG;R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;break;case UIS_TOKEN_OUT | 3:{if(R8_USB_INT_ST & RB_UIS_TOG_OK){ // 不同步的數(shù)據(jù)包將丟棄R8_UEP3_CTRL ^= RB_UEP_R_TOG;len = R8_USB_RX_LEN;DevEP3_OUT_Deal(len);}}break;case UIS_TOKEN_IN | 3:R8_UEP3_CTRL ^= RB_UEP_T_TOG;R8_UEP3_CTRL = (R8_UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;break;case UIS_TOKEN_OUT | 4:{if(R8_USB_INT_ST & RB_UIS_TOG_OK){R8_UEP4_CTRL ^= RB_UEP_R_TOG;len = R8_USB_RX_LEN;DevEP4_OUT_Deal(len);}}break;case UIS_TOKEN_IN | 4:R8_UEP4_CTRL ^= RB_UEP_T_TOG;R8_UEP4_CTRL = (R8_UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;break;default:break;}R8_USB_INT_FG = RB_UIF_TRANSFER;}if(R8_USB_INT_ST & RB_UIS_SETUP_ACT) // Setup包處理{R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;SetupReqLen = pSetupReqPak->wLength;SetupReqCode = pSetupReqPak->bRequest;chtype = pSetupReqPak->bRequestType;len = 0;errflag = 0;if((pSetupReqPak->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD){/* 非標(biāo)準(zhǔn)請(qǐng)求 *//* 其它請(qǐng)求,如類請(qǐng)求,產(chǎn)商請(qǐng)求等 */if(pSetupReqPak->bRequestType & 0x40){/* 廠商請(qǐng)求 */}else if(pSetupReqPak->bRequestType & 0x20){switch(SetupReqCode){case DEF_USB_SET_IDLE: /* 0x0A: SET_IDLE */Idle_Value = EP0_Databuf[3];break; //這個(gè)一定要有case DEF_USB_SET_REPORT: /* 0x09: SET_REPORT */break;case DEF_USB_SET_PROTOCOL: /* 0x0B: SET_PROTOCOL */Report_Value = EP0_Databuf[2];break;case DEF_USB_GET_IDLE: /* 0x02: GET_IDLE */EP0_Databuf[0] = Idle_Value;len = 1;break;case DEF_USB_GET_PROTOCOL: /* 0x03: GET_PROTOCOL */EP0_Databuf[0] = Report_Value;len = 1;break;default:errflag = 0xFF;}}}else /* 標(biāo)準(zhǔn)請(qǐng)求 */{switch(SetupReqCode){case USB_GET_DESCRIPTOR:{switch(((pSetupReqPak->wValue) >> 8)){case USB_DESCR_TYP_DEVICE:/* 獲取設(shè)備描述符 */pDescr = MyDevDescr;len = MyDevDescr[0];break;case USB_DESCR_TYP_CONFIG:/* 獲取配置描述符 */pDescr = MyCfgDescr;len = sizeof( MyCfgDescr );break;case USB_DESCR_TYP_STRING:/* 獲取字符串描述符 */switch( (pSetupReqPak->wValue)&0xff ){case 0:/* 語(yǔ)言字符串描述符 */pDescr = MyLangDescr;len = MyLangDescr[0];break;case 1:/* USB產(chǎn)商字符串描述符 */pDescr = MyManuInfo;len = MyManuInfo[0];break;case 2:/* USB產(chǎn)品字符串描述符 */pDescr = MyProdInfo;len = MyProdInfo[0];break;case 3:/* USB序列號(hào)字符串描述符 */pDescr = MySerNumInfo;len = sizeof( MySerNumInfo );break;default:errflag = 0xFF;break;}break;case USB_DESCR_TYP_REPORT:/* USB設(shè)備報(bào)告描述符 */pDescr = CompatibilityHIDRepDesc;len = sizeof( CompatibilityHIDRepDesc );break;case USB_DESCR_TYP_QUALIF:/* 設(shè)備限定描述符 */pDescr = ( PUINT8 )&MyUSBQUADesc[ 0 ];len = sizeof( MyUSBQUADesc );break;case USB_DESCR_TYP_SPEED:/* 其他速度配置描述符 */errflag = 0xFF;break;default :errflag = 0xff;break;}if(SetupReqLen > len)SetupReqLen = len; //實(shí)際需上傳總長(zhǎng)度len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;memcpy(pEP0_DataBuf, pDescr, len);pDescr += len;}break;case USB_SET_ADDRESS:SetupReqLen = (pSetupReqPak->wValue) & 0xff;break;case USB_GET_CONFIGURATION:pEP0_DataBuf[0] = DevConfig;if(SetupReqLen > 1)SetupReqLen = 1;break;case USB_SET_CONFIGURATION:DevConfig = (pSetupReqPak->wValue) & 0xff;break;case USB_CLEAR_FEATURE:{if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) // 端點(diǎn){switch((pSetupReqPak->wIndex) & 0xff){case 0x83:R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK;break;case 0x03:R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK;break;case 0x82:R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK;break;case 0x02:R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK;break;case 0x81:R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK;break;case 0x01:R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK;break;default:errflag = 0xFF; // 不支持的端點(diǎn)break;}}else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE){if(pSetupReqPak->wValue == 1){USB_SleepStatus &= ~0x01;}}else{errflag = 0xFF;}}break;case USB_SET_FEATURE:if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP){/* 端點(diǎn) */switch(pSetupReqPak->wIndex){case 0x83:R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL;break;case 0x03:R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL;break;case 0x82:R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL;break;case 0x02:R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL;break;case 0x81:R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL;break;case 0x01:R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL;break;default:/* 不支持的端點(diǎn) */errflag = 0xFF; // 不支持的端點(diǎn)break;}}else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE){if(pSetupReqPak->wValue == 1){/* 設(shè)置睡眠 */USB_SleepStatus |= 0x01;}}else{errflag = 0xFF;}break;case USB_GET_INTERFACE:pEP0_DataBuf[0] = 0x00;if(SetupReqLen > 1)SetupReqLen = 1;break;case USB_SET_INTERFACE:break;case USB_GET_STATUS:if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP){/* 端點(diǎn) */pEP0_DataBuf[0] = 0x00;switch(pSetupReqPak->wIndex){case 0x83:if((R8_UEP3_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;case 0x03:if((R8_UEP3_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;case 0x82:if((R8_UEP2_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;case 0x02:if((R8_UEP2_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;case 0x81:if((R8_UEP1_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;case 0x01:if((R8_UEP1_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL){pEP0_DataBuf[0] = 0x01;}break;}}else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE){pEP0_DataBuf[0] = 0x00;if(USB_SleepStatus){pEP0_DataBuf[0] = 0x02;}else{pEP0_DataBuf[0] = 0x00;}}pEP0_DataBuf[1] = 0;if(SetupReqLen >= 2){SetupReqLen = 2;}break;default:errflag = 0xff;break;}}if(errflag == 0xff) // 錯(cuò)誤或不支持{// SetupReqCode = 0xFF;R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; // STALL}else{if(chtype & 0x80) // 上傳{len = (SetupReqLen > DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;SetupReqLen -= len;}elselen = 0; // 下傳R8_UEP0_T_LEN = len;R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; // 默認(rèn)數(shù)據(jù)包是DATA1}R8_USB_INT_FG = RB_UIF_TRANSFER;}}else if(intflag & RB_UIF_BUS_RST){R8_USB_DEV_AD = 0;R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;R8_USB_INT_FG = RB_UIF_BUS_RST;}else if(intflag & RB_UIF_SUSPEND){if(R8_USB_MIS_ST & RB_UMS_SUSPEND){;} // 掛起else{;} // 喚醒R8_USB_INT_FG = RB_UIF_SUSPEND;}else{R8_USB_INT_FG = intflag;} }__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) /* USB中斷服務(wù)程序,使用寄存器組1 */ {USB_DevTransProcess(); }

USB端點(diǎn)收發(fā)部分接口,IN OUT都是從host端即電腦端而言

/********************************************************************** @fn DevEP1_OUT_Deal** @brief 端點(diǎn)1數(shù)據(jù)處理** @return none*/ void DevEP1_OUT_Deal(uint8_t l) { /* 用戶可自定義 */uint8_t i;for(i = 0; i < l; i++){pEP1_IN_DataBuf[i] = pEP1_OUT_DataBuf[i];}DevEP1_IN_Deal(l);PRINT("DevEP1_OUT_Deal:%d\r\n",l); }/********************************************************************** @fn DevEP2_OUT_Deal** @brief 端點(diǎn)2數(shù)據(jù)處理** @return none*/ void DevEP2_OUT_Deal(uint8_t l) { /* 用戶可自定義 */uint8_t i;PRINT("DevEP2_OUT_Deal:%d\r\n",l);for(i = 0; i < l; i++){pEP2_IN_DataBuf[i] = pEP2_OUT_DataBuf[i];}DevEP2_IN_Deal(l); }/********************************************************************** @fn DevEP3_OUT_Deal** @brief 端點(diǎn)3數(shù)據(jù)處理** @return none*/ void DevEP3_OUT_Deal(uint8_t l) { /* 用戶可自定義 */uint8_t i;PRINT("DevEP3_OUT_Deal:%d\r\n",l);for(i = 0; i < l; i++){pEP3_IN_DataBuf[i] = pEP3_OUT_DataBuf[i];}DevEP3_IN_Deal(l); }/********************************************************************** @fn DevEP4_OUT_Deal** @brief 端點(diǎn)4數(shù)據(jù)處理** @return none*/ void DevEP4_OUT_Deal(uint8_t l) { /* 用戶可自定義 */uint8_t i;PRINT("DevEP4_OUT_Deal:%d\r\n",l);for(i = 0; i < l; i++){pEP4_IN_DataBuf[i] = pEP4_OUT_DataBuf[i];}DevEP4_IN_Deal(l); }

主函數(shù):

int main() {SetSysClock(CLK_SOURCE_PLL_60MHz);DebugInit();PRINT("start\n");pEP0_RAM_Addr = EP0_Databuf;pEP1_RAM_Addr = EP1_Databuf;pEP2_RAM_Addr = EP2_Databuf;pEP3_RAM_Addr = EP3_Databuf;USB_DeviceInit();PFIC_EnableIRQ(USB_IRQn);while(1){mDelaymS(100);#if 0uint8_t i;for(i = 0; i < 64; i++){pEP1_IN_DataBuf[i] = 0x30+i;}DevEP1_IN_Deal(64);#endif} }

使用usb hid收發(fā)助手調(diào)試

總結(jié)

以上是生活随笔為你收集整理的沁恒CH583 USB 自定义HID调试记录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。