CH582/CH592/CH585/CH584_全速USB中端点4、5、6、7的使用注意事项
博客转载自:USB设备在端点4~7交互数据 - JayWell - 博客园
在CH582的EVT包USB设备例程中,已有端点0~3的全部代码。端点4~7在手册中有描述,不过在例程中没有给出。
在端点0~7中,端点0与端点4与众不同。端点0只拥有64字节DMA缓存。这是符合USB协议标准的。作为USB设备都要默认支持的端点,USB协议要求设备的端点0是双向通信的;而其他端点是超级加倍,IN和OUT方向各有64字节的DMA缓存。
而端点4,其DMA地址是直接存放在64字节的端点0的DMA地址后的,配置了端点0的DMA地址后,就不必再次配置端点4的DMA。
原因未知,像是贴地砖时,用半块地砖填补到缝隙中,尽可能利用空间,不能浪费(把端点4的DMA区域塞到了端点0后面);后续建筑扩建,在新地方继续铺整块地砖(端点5~7都有独立的DMA缓存)。



不过这也带来一些麻烦,有更多的寄存器需要照顾。部分例程里已经配置好了,不必再关注端点4的配置。



以下是作为USB键鼠,在端点4、端点7中上传报表描述符的参考代码。
1 /********************************** (C) COPYRIGHT ******************************* 2 * File Name : Main.c 3 * Author : WCH 4 * Version : V1.1 5 * Date : 2022/01/25 6 * Description : 模拟USB复合设备,键鼠,支持类命令 7 ********************************************************************************* 8 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. 9 * Attention: This software (modified or not) and binary are used for 10 * microcontroller manufactured by Nanjing Qinheng Microelectronics. 11 *******************************************************************************/ 12 13 #include "CH58x_common.h" 14 15 uint8_t *pEP5_RAM_Addr; 16 uint8_t *pEP6_RAM_Addr; 17 uint8_t *pEP7_RAM_Addr; //XXX JW 增加端点配置 18 19 #define pEP5_OUT_DataBuf (pEP5_RAM_Addr) 20 #define pEP5_IN_DataBuf (pEP5_RAM_Addr + 64) 21 #define pEP6_OUT_DataBuf (pEP6_RAM_Addr) 22 #define pEP6_IN_DataBuf (pEP6_RAM_Addr + 64) 23 #define pEP7_OUT_DataBuf (pEP7_RAM_Addr) 24 #define pEP7_IN_DataBuf (pEP7_RAM_Addr + 64) //XXX JW 增加端点配置 25 26 /*增加函数声明*/ 27 void DevEP5_IN_Deal(uint8_t l); 28 void DevEP6_IN_Deal(uint8_t l); 29 void DevEP7_IN_Deal(uint8_t l); 30 void DevEP5_OUT_Deal(uint8_t l); 31 void DevEP6_OUT_Deal(uint8_t l); 32 void DevEP7_OUT_Deal(uint8_t l); 33 34 void DevEP5_OUT_Deal(uint8_t l) //XXX 增加端点OUT处理 35 { /* 用户可自定义 */ 36 uint8_t i; 37 38 for(i = 0; i < l; i++) 39 { 40 pEP5_IN_DataBuf[i] = ~pEP5_OUT_DataBuf[i]; 41 } 42 DevEP5_IN_Deal(l); 43 } 44 45 void DevEP6_OUT_Deal(uint8_t l) //XXX 增加端点OUT处理 46 { /* 用户可自定义 */ 47 uint8_t i; 48 49 for(i = 0; i < l; i++) 50 { 51 pEP6_IN_DataBuf[i] = ~pEP6_OUT_DataBuf[i]; 52 } 53 DevEP6_IN_Deal(l); 54 } 55 56 void DevEP7_OUT_Deal(uint8_t l) //XXX 增加端点OUT处理 57 { /* 用户可自定义 */ 58 uint8_t i; 59 60 for(i = 0; i < l; i++) 61 { 62 pEP7_IN_DataBuf[i] = ~pEP7_OUT_DataBuf[i]; 63 } 64 DevEP7_IN_Deal(l); 65 } 66 67 void DevEP5_IN_Deal(uint8_t l) //XXX 增加端点IN处理 68 { 69 R8_UEP5_T_LEN = l; 70 R8_UEP5_CTRL = (R8_UEP5_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; 71 } 72 73 void DevEP6_IN_Deal(uint8_t l) //XXX 增加端点IN处理 74 { 75 R8_UEP6_T_LEN = l; 76 R8_UEP6_CTRL = (R8_UEP6_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; 77 } 78 79 void DevEP7_IN_Deal(uint8_t l) //XXX 增加端点IN处理 80 { 81 R8_UEP7_T_LEN = l; 82 R8_UEP7_CTRL = (R8_UEP7_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; 83 } 84 85 /*鼠标键盘数据*/ 86 uint8_t HIDMouse[4] = {0x0, 0x0, 0x0, 0x0}; 87 uint8_t HIDKey[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 88 89 /********************************************************************* 90 * @fn DevHIDMouseReport 91 * 92 * @brief 上报鼠标数据 93 * 94 * @return none 95 */ 96 void DevHIDMouseReport(uint8_t mouse) //XXX 改到端点7 97 { 98 HIDMouse[0] = mouse; 99 for(uint8_t i=0; i<4; i++) 100 PRINT("%d ", HIDMouse[i]); 101 PRINT("\n"); 102 memcpy(pEP5_IN_DataBuf, HIDMouse, sizeof(HIDMouse)); 103 DevEP5_IN_Deal(sizeof(HIDMouse)); 104 memcpy(pEP7_IN_DataBuf, HIDMouse, sizeof(HIDMouse)); 105 DevEP7_IN_Deal(sizeof(HIDMouse)); 106 } 107 108 /********************************************************************* 109 * @fn DevHIDKeyReport 110 * 111 * @brief 上报键盘数据 112 * 113 * @return none 114 */ 115 void DevHIDKeyReport(uint8_t key) //XXX 改到端点4 116 { 117 HIDKey[2] = key; 118 for(uint8_t i=0; i<8; i++) 119 PRINT("%d ", HIDKey[i]); 120 PRINT("\n"); 121 memcpy(pEP4_IN_DataBuf, HIDKey, sizeof(HIDKey)); 122 DevEP4_IN_Deal(sizeof(HIDKey)); 123 } 124 125 #define DevEP0SIZE 0x40 126 127 // 支持的最大接口数量 128 #define USB_INTERFACE_MAX_NUM 2 129 // 接口号的最大值 130 #define USB_INTERFACE_MAX_INDEX 1 131 132 // 设备描述符 133 const uint8_t MyDevDescr[] = {0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, DevEP0SIZE, 0x3d, 0x41, 0x07, 0x21, 0x00, 0x00, 134 0x01, 0x02, 0x00, 0x01}; 135 // 配置描述符 136 const uint8_t MyCfgDescr[] = { 137 0x09, 0x02, 0x3b, 0x00, 0x02, 0x01, 0x00, 0xA0, 0x32, //配置描述符 138 0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x01, 0x00, //接口描述符,键盘 139 0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x3e, 0x00, //HID类描述符 140 0x07, 0x05, 0x84, 0x03, 0x08, 0x00, 0x0a, //端点描述符 //XXX JW 改到端点4 141 0x09, 0x04, 0x01, 0x00, 0x01, 0x03, 0x01, 0x02, 0x00, //接口描述符,鼠标 142 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0x34, 0x00, //HID类描述符 143 0x07, 0x05, 0x87, 0x03, 0x04, 0x00, 0x0a //端点描述符 //XXX JW 改到端点7 144 145 }; 146 /* USB速度匹配描述符 */ 147 const uint8_t My_QueDescr[] = {0x0A, 0x06, 0x00, 0x02, 0xFF, 0x00, 0xFF, 0x40, 0x01, 0x00}; 148 149 /* USB全速模式,其他速度配置描述符 */ 150 uint8_t USB_FS_OSC_DESC[sizeof(MyCfgDescr)] = { 151 0x09, 0x07, /* 其他部分通过程序复制 */ 152 }; 153 154 // 语言描述符 155 const uint8_t MyLangDescr[] = {0x04, 0x03, 0x09, 0x04}; 156 // 厂家信息 157 const uint8_t MyManuInfo[] = {0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0}; 158 // 产品信息 159 const uint8_t MyProdInfo[] = {0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '8', 0, 'x', 0}; 160 /*HID类报表描述符*/ 161 const uint8_t KeyRepDesc[] = {0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 162 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 163 0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02, 0x95, 0x05, 0x75, 0x01, 0x91, 164 0x01, 0x95, 0x06, 0x75, 0x08, 0x26, 0xff, 0x00, 0x05, 0x07, 0x19, 0x00, 0x29, 0x91, 0x81, 165 0x00, 0xC0}; 166 const uint8_t MouseRepDesc[] = {0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 167 0x03, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x03, 0x81, 0x02, 0x75, 0x05, 0x95, 0x01, 168 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 169 0x08, 0x95, 0x03, 0x81, 0x06, 0xC0, 0xC0}; 170 171 /**********************************************************/ 172 uint8_t DevConfig, Ready; 173 uint8_t SetupReqCode; 174 uint16_t SetupReqLen; 175 const uint8_t *pDescr; 176 uint8_t Report_Value[USB_INTERFACE_MAX_INDEX+1] = {0x00}; 177 uint8_t Idle_Value[USB_INTERFACE_MAX_INDEX+1] = {0x00}; 178 uint8_t USB_SleepStatus = 0x00; /* USB睡眠状态 */ 179 180 /******** 用户自定义分配端点RAM ****************************************/ 181 __attribute__((aligned(4))) uint8_t EP0_Databuf[64 + 64 + 64]; //ep0(64)+ep4_out(64)+ep4_in(64) 182 __attribute__((aligned(4))) uint8_t EP1_Databuf[64 + 64]; //ep1_out(64)+ep1_in(64) 183 __attribute__((aligned(4))) uint8_t EP2_Databuf[64 + 64]; //ep2_out(64)+ep2_in(64) 184 __attribute__((aligned(4))) uint8_t EP3_Databuf[64 + 64]; //ep3_out(64)+ep3_in(64) 185 __attribute__((aligned(4))) uint8_t EP5_Databuf[64 + 64]; 186 __attribute__((aligned(4))) uint8_t EP6_Databuf[64 + 64]; 187 __attribute__((aligned(4))) uint8_t EP7_Databuf[64 + 64]; //XXX 增加端点配置 188 189 190 /********************************************************************* 191 * @fn USB_DevTransProcess 192 * 193 * @brief USB 传输处理函数 194 * 195 * @return none 196 */ 197 void USB_DevTransProcess(void) 198 { 199 uint8_t len, chtype; 200 uint8_t intflag, errflag = 0; 201 202 intflag = R8_USB_INT_FG; 203 if(intflag & RB_UIF_TRANSFER) 204 { 205 if((R8_USB_INT_ST & MASK_UIS_TOKEN) != MASK_UIS_TOKEN) // 非空闲 206 { 207 switch(R8_USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) 208 // 分析操作令牌和端点号 209 { 210 case UIS_TOKEN_IN: 211 { 212 switch(SetupReqCode) 213 { 214 case USB_GET_DESCRIPTOR: 215 len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen; // 本次传输长度 216 memcpy(pEP0_DataBuf, pDescr, len); /* 加载上传数据 */ 217 SetupReqLen -= len; 218 pDescr += len; 219 R8_UEP0_T_LEN = len; 220 R8_UEP0_CTRL ^= RB_UEP_T_TOG; // 翻转 221 break; 222 case USB_SET_ADDRESS: 223 R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | SetupReqLen; 224 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 225 break; 226 227 case USB_SET_FEATURE: 228 break; 229 230 default: 231 R8_UEP0_T_LEN = 0; // 状态阶段完成中断或者是强制上传0长度数据包结束控制传输 232 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 233 break; 234 } 235 } 236 break; 237 238 case UIS_TOKEN_OUT: 239 { 240 len = R8_USB_RX_LEN; 241 if(SetupReqCode == 0x09) 242 { 243 PRINT("[%s] Num Lock\t", (pEP0_DataBuf[0] & (1<<0)) ? "*" : " "); 244 PRINT("[%s] Caps Lock\t", (pEP0_DataBuf[0] & (1<<1)) ? "*" : " "); 245 PRINT("[%s] Scroll Lock\n", (pEP0_DataBuf[0] & (1<<2)) ? "*" : " "); 246 } 247 } 248 break; 249 250 case UIS_TOKEN_OUT | 1: 251 { 252 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 253 { // 不同步的数据包将丢弃 254 R8_UEP1_CTRL ^= RB_UEP_R_TOG; 255 len = R8_USB_RX_LEN; 256 DevEP1_OUT_Deal(len); 257 } 258 } 259 break; 260 261 case UIS_TOKEN_IN | 1: 262 R8_UEP1_CTRL ^= RB_UEP_T_TOG; 263 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 264 break; 265 266 case UIS_TOKEN_OUT | 2: 267 { 268 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 269 { // 不同步的数据包将丢弃 270 R8_UEP2_CTRL ^= RB_UEP_R_TOG; 271 len = R8_USB_RX_LEN; 272 DevEP2_OUT_Deal(len); 273 } 274 } 275 break; 276 277 case UIS_TOKEN_IN | 2: 278 R8_UEP2_CTRL ^= RB_UEP_T_TOG; 279 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 280 break; 281 282 case UIS_TOKEN_OUT | 3: 283 { 284 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 285 { // 不同步的数据包将丢弃 286 R8_UEP3_CTRL ^= RB_UEP_R_TOG; 287 len = R8_USB_RX_LEN; 288 DevEP3_OUT_Deal(len); 289 } 290 } 291 break; 292 293 case UIS_TOKEN_IN | 3: 294 R8_UEP3_CTRL ^= RB_UEP_T_TOG; 295 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 296 break; 297 298 case UIS_TOKEN_OUT | 4: 299 { 300 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 301 { 302 R8_UEP4_CTRL ^= RB_UEP_R_TOG; 303 len = R8_USB_RX_LEN; 304 DevEP4_OUT_Deal(len); 305 } 306 } 307 break; 308 309 case UIS_TOKEN_IN | 4: 310 R8_UEP4_CTRL ^= RB_UEP_T_TOG; 311 R8_UEP4_CTRL = (R8_UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 312 break; 313 314 case UIS_TOKEN_OUT | 5: 315 { 316 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 317 { // 不同步的数据包将丢弃 318 R8_UEP5_CTRL ^= RB_UEP_R_TOG; 319 len = R8_USB_RX_LEN; 320 DevEP5_OUT_Deal(len); 321 } 322 } 323 break; 324 325 case UIS_TOKEN_IN | 5: 326 R8_UEP5_CTRL ^= RB_UEP_T_TOG; 327 R8_UEP5_CTRL = (R8_UEP5_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; //XXX 增加端点 328 break; 329 330 case UIS_TOKEN_OUT | 6: 331 { 332 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 333 { // 不同步的数据包将丢弃 334 R8_UEP6_CTRL ^= RB_UEP_R_TOG; 335 len = R8_USB_RX_LEN; 336 DevEP6_OUT_Deal(len); 337 } 338 } 339 break; 340 341 case UIS_TOKEN_IN | 6: 342 R8_UEP6_CTRL ^= RB_UEP_T_TOG; 343 R8_UEP6_CTRL = (R8_UEP6_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; //XXX 增加端点 344 break; 345 346 case UIS_TOKEN_OUT | 7: 347 { 348 if(R8_USB_INT_ST & RB_UIS_TOG_OK) 349 { // 不同步的数据包将丢弃 350 R8_UEP7_CTRL ^= RB_UEP_R_TOG; 351 len = R8_USB_RX_LEN; 352 DevEP7_OUT_Deal(len); 353 } 354 } 355 break; 356 357 case UIS_TOKEN_IN | 7: 358 R8_UEP7_CTRL ^= RB_UEP_T_TOG; 359 R8_UEP7_CTRL = (R8_UEP7_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; //XXX 增加端点 360 break; 361 362 default: 363 break; 364 } 365 R8_USB_INT_FG = RB_UIF_TRANSFER; 366 } 367 if(R8_USB_INT_ST & RB_UIS_SETUP_ACT) // Setup包处理 368 { 369 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK; 370 SetupReqLen = pSetupReqPak->wLength; 371 SetupReqCode = pSetupReqPak->bRequest; 372 chtype = pSetupReqPak->bRequestType; 373 374 len = 0; 375 errflag = 0; 376 if((pSetupReqPak->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) 377 { 378 /* 非标准请求 */ 379 /* 其它请求,如类请求,产商请求等 */ 380 if(pSetupReqPak->bRequestType & 0x40) 381 { 382 /* 厂商请求 */ 383 } 384 else if(pSetupReqPak->bRequestType & 0x20) 385 { 386 switch(SetupReqCode) 387 { 388 case DEF_USB_SET_IDLE: /* 0x0A: SET_IDLE */ //主机想设置HID设备特定输入报表的空闲时间间隔 389 Idle_Value[pSetupReqPak->wIndex] = (uint8_t)(pSetupReqPak->wValue>>8); 390 break; //这个一定要有 391 392 case DEF_USB_SET_REPORT: /* 0x09: SET_REPORT */ //主机想设置HID设备的报表描述符 393 break; 394 395 case DEF_USB_SET_PROTOCOL: /* 0x0B: SET_PROTOCOL */ //主机想设置HID设备当前所使用的协议 396 Report_Value[pSetupReqPak->wIndex] = (uint8_t)(pSetupReqPak->wValue); 397 break; 398 399 case DEF_USB_GET_IDLE: /* 0x02: GET_IDLE */ //主机想读取HID设备特定输入报表的当前的空闲比率 400 EP0_Databuf[0] = Idle_Value[pSetupReqPak->wIndex]; 401 len = 1; 402 break; 403 404 case DEF_USB_GET_PROTOCOL: /* 0x03: GET_PROTOCOL */ //主机想获得HID设备当前所使用的协议 405 EP0_Databuf[0] = Report_Value[pSetupReqPak->wIndex]; 406 len = 1; 407 break; 408 409 default: 410 errflag = 0xFF; 411 } 412 } 413 } 414 else /* 标准请求 */ 415 { 416 switch(SetupReqCode) 417 { 418 case USB_GET_DESCRIPTOR: 419 { 420 switch(((pSetupReqPak->wValue) >> 8)) 421 { 422 case USB_DESCR_TYP_DEVICE: 423 { 424 pDescr = MyDevDescr; 425 len = MyDevDescr[0]; 426 } 427 break; 428 429 case USB_DESCR_TYP_CONFIG: 430 { 431 pDescr = MyCfgDescr; 432 len = MyCfgDescr[2]; 433 } 434 break; 435 436 case USB_DESCR_TYP_HID: 437 switch((pSetupReqPak->wIndex) & 0xff) 438 { 439 /* 选择接口 */ 440 case 0: 441 pDescr = (uint8_t *)(&MyCfgDescr[18]); 442 len = 9; 443 break; 444 445 case 1: 446 pDescr = (uint8_t *)(&MyCfgDescr[43]); 447 len = 9; 448 break; 449 450 default: 451 /* 不支持的字符串描述符 */ 452 errflag = 0xff; 453 break; 454 } 455 break; 456 457 case USB_DESCR_TYP_REPORT: 458 { 459 if(((pSetupReqPak->wIndex) & 0xff) == 0) //接口0报表描述符 460 { 461 pDescr = KeyRepDesc; //数据准备上传 462 len = sizeof(KeyRepDesc); 463 } 464 else if(((pSetupReqPak->wIndex) & 0xff) == 1) //接口1报表描述符 465 { 466 pDescr = MouseRepDesc; //数据准备上传 467 len = sizeof(MouseRepDesc); 468 Ready = 1; //如果有更多接口,该标准位应该在最后一个接口配置完成后有效 469 } 470 else 471 len = 0xff; //本程序只有2个接口,这句话正常不可能执行 472 } 473 break; 474 475 case USB_DESCR_TYP_STRING: 476 { 477 switch((pSetupReqPak->wValue) & 0xff) 478 { 479 case 1: 480 pDescr = MyManuInfo; 481 len = MyManuInfo[0]; 482 break; 483 case 2: 484 pDescr = MyProdInfo; 485 len = MyProdInfo[0]; 486 break; 487 case 0: 488 pDescr = MyLangDescr; 489 len = MyLangDescr[0]; 490 break; 491 default: 492 errflag = 0xFF; // 不支持的字符串描述符 493 break; 494 } 495 } 496 break; 497 498 case 0x06: 499 pDescr = (uint8_t *)(&My_QueDescr[0]); 500 len = sizeof(My_QueDescr); 501 break; 502 503 case 0x07: 504 memcpy(&USB_FS_OSC_DESC[2], &MyCfgDescr[2], sizeof(MyCfgDescr) - 2); 505 pDescr = (uint8_t *)(&USB_FS_OSC_DESC[0]); 506 len = sizeof(USB_FS_OSC_DESC); 507 break; 508 509 default: 510 errflag = 0xff; 511 break; 512 } 513 if(SetupReqLen > len) 514 SetupReqLen = len; //实际需上传总长度 515 len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen; 516 memcpy(pEP0_DataBuf, pDescr, len); 517 pDescr += len; 518 } 519 break; 520 521 case USB_SET_ADDRESS: 522 SetupReqLen = (pSetupReqPak->wValue) & 0xff; 523 break; 524 525 case USB_GET_CONFIGURATION: 526 pEP0_DataBuf[0] = DevConfig; 527 if(SetupReqLen > 1) 528 SetupReqLen = 1; 529 break; 530 531 case USB_SET_CONFIGURATION: 532 DevConfig = (pSetupReqPak->wValue) & 0xff; 533 break; 534 535 case USB_CLEAR_FEATURE: 536 { 537 if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) // 端点 538 { 539 switch((pSetupReqPak->wIndex) & 0xff) 540 { 541 case 0x83: 542 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; 543 break; 544 case 0x03: 545 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK; 546 break; 547 case 0x82: 548 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; 549 break; 550 case 0x02: 551 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK; 552 break; 553 case 0x81: 554 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; 555 break; 556 case 0x01: 557 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK; 558 break; 559 default: 560 errflag = 0xFF; // 不支持的端点 561 break; 562 } 563 } 564 else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE) 565 { 566 if(pSetupReqPak->wValue == 1) 567 { 568 USB_SleepStatus &= ~0x01; 569 } 570 } 571 else 572 { 573 errflag = 0xFF; 574 } 575 } 576 break; 577 578 case USB_SET_FEATURE: 579 if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) 580 { 581 /* 端点 */ 582 switch(pSetupReqPak->wIndex) 583 { 584 case 0x83: 585 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL; 586 break; 587 case 0x03: 588 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL; 589 break; 590 case 0x82: 591 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL; 592 break; 593 case 0x02: 594 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL; 595 break; 596 case 0x81: 597 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_STALL; 598 break; 599 case 0x01: 600 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_STALL; 601 break; 602 default: 603 /* 不支持的端点 */ 604 errflag = 0xFF; // 不支持的端点 605 break; 606 } 607 } 608 else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE) 609 { 610 if(pSetupReqPak->wValue == 1) 611 { 612 /* 设置睡眠 */ 613 USB_SleepStatus |= 0x01; 614 } 615 } 616 else 617 { 618 errflag = 0xFF; 619 } 620 break; 621 622 case USB_GET_INTERFACE: 623 pEP0_DataBuf[0] = 0x00; 624 if(SetupReqLen > 1) 625 SetupReqLen = 1; 626 break; 627 628 case USB_SET_INTERFACE: 629 break; 630 631 case USB_GET_STATUS: 632 if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) 633 { 634 /* 端点 */ 635 pEP0_DataBuf[0] = 0x00; 636 switch(pSetupReqPak->wIndex) 637 { 638 case 0x83: 639 if((R8_UEP3_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL) 640 { 641 pEP0_DataBuf[0] = 0x01; 642 } 643 break; 644 645 case 0x03: 646 if((R8_UEP3_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL) 647 { 648 pEP0_DataBuf[0] = 0x01; 649 } 650 break; 651 652 case 0x82: 653 if((R8_UEP2_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL) 654 { 655 pEP0_DataBuf[0] = 0x01; 656 } 657 break; 658 659 case 0x02: 660 if((R8_UEP2_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL) 661 { 662 pEP0_DataBuf[0] = 0x01; 663 } 664 break; 665 666 case 0x81: 667 if((R8_UEP1_CTRL & (RB_UEP_T_TOG | MASK_UEP_T_RES)) == UEP_T_RES_STALL) 668 { 669 pEP0_DataBuf[0] = 0x01; 670 } 671 break; 672 673 case 0x01: 674 if((R8_UEP1_CTRL & (RB_UEP_R_TOG | MASK_UEP_R_RES)) == UEP_R_RES_STALL) 675 { 676 pEP0_DataBuf[0] = 0x01; 677 } 678 break; 679 } 680 } 681 else if((pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE) 682 { 683 pEP0_DataBuf[0] = 0x00; 684 if(USB_SleepStatus) 685 { 686 pEP0_DataBuf[0] = 0x02; 687 } 688 else 689 { 690 pEP0_DataBuf[0] = 0x00; 691 } 692 } 693 pEP0_DataBuf[1] = 0; 694 if(SetupReqLen >= 2) 695 { 696 SetupReqLen = 2; 697 } 698 break; 699 700 default: 701 errflag = 0xff; 702 break; 703 } 704 } 705 if(errflag == 0xff) // 错误或不支持 706 { 707 // SetupReqCode = 0xFF; 708 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; // STALL 709 } 710 else 711 { 712 if(chtype & 0x80) // 上传 713 { 714 len = (SetupReqLen > DevEP0SIZE) ? DevEP0SIZE : SetupReqLen; 715 SetupReqLen -= len; 716 } 717 else 718 len = 0; // 下传 719 R8_UEP0_T_LEN = len; 720 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; // 默认数据包是DATA1 721 } 722 723 R8_USB_INT_FG = RB_UIF_TRANSFER; 724 } 725 } 726 else if(intflag & RB_UIF_BUS_RST) 727 { 728 R8_USB_DEV_AD = 0; 729 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 730 R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 731 R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 732 R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 733 R8_USB_INT_FG = RB_UIF_BUS_RST; 734 } 735 else if(intflag & RB_UIF_SUSPEND) 736 { 737 if(R8_USB_MIS_ST & RB_UMS_SUSPEND) 738 { 739 ; 740 } // 挂起 741 else 742 { 743 ; 744 } // 唤醒 745 R8_USB_INT_FG = RB_UIF_SUSPEND; 746 } 747 else 748 { 749 R8_USB_INT_FG = intflag; 750 } 751 } 752 753 754 /********************************************************************* 755 * @fn DevWakeup 756 * 757 * @brief 设备模式唤醒主机 758 * 759 * @return none 760 */ 761 void DevWakeup(void) 762 { 763 R16_PIN_ANALOG_IE &= ~(RB_PIN_USB_DP_PU); 764 R8_UDEV_CTRL |= RB_UD_LOW_SPEED; 765 mDelaymS(2); 766 R8_UDEV_CTRL &= ~RB_UD_LOW_SPEED; 767 R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU; 768 } 769 770 /********************************************************************* 771 * @fn DebugInit 772 * 773 * @brief 调试初始化 774 * 775 * @return none 776 */ 777 void DebugInit(void) 778 { 779 GPIOA_SetBits(GPIO_Pin_9); 780 GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); 781 GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); 782 UART1_DefInit(); 783 } 784 785 /********************************************************************* 786 * @fn main 787 * 788 * @brief 主函数 789 * 790 * @return none 791 */ 792 int main() 793 { 794 SetSysClock(CLK_SOURCE_PLL_60MHz); 795 796 DebugInit(); 797 PRINT("start\n"); 798 799 pEP0_RAM_Addr = EP0_Databuf; 800 pEP1_RAM_Addr = EP1_Databuf; 801 pEP2_RAM_Addr = EP2_Databuf; 802 pEP3_RAM_Addr = EP3_Databuf; 803 pEP5_RAM_Addr = EP5_Databuf; 804 pEP6_RAM_Addr = EP6_Databuf; 805 pEP7_RAM_Addr = EP7_Databuf; //XXX 增加配置 806 807 R8_UEP567_MOD = RB_UEP5_RX_EN | RB_UEP5_TX_EN | RB_UEP6_RX_EN | RB_UEP6_TX_EN | RB_UEP7_RX_EN | RB_UEP7_TX_EN; //XXX 增加配置 808 809 R16_UEP5_DMA = (uint16_t)(uint32_t)pEP1_RAM_Addr; 810 R16_UEP6_DMA = (uint16_t)(uint32_t)pEP2_RAM_Addr; 811 R16_UEP7_DMA = (uint16_t)(uint32_t)pEP3_RAM_Addr; //XXX 增加配置 812 813 R8_UEP5_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 814 R8_UEP6_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 815 R8_UEP7_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; //XXX 增加配置 816 817 USB_DeviceInit(); 818 819 PFIC_EnableIRQ(USB_IRQn); 820 821 while(1) 822 { 823 mDelaymS(1000); 824 // //鼠标左键 825 // DevHIDMouseReport(0x01); 826 // mDelaymS(100); 827 DevHIDMouseReport(0x00); 828 mDelaymS(200); 829 // 830 // //键盘按键“wch” 831 // mDelaymS(1000); 832 // DevHIDKeyReport(0x1A); 833 // mDelaymS(100); 834 // DevHIDKeyReport(0x00); 835 // mDelaymS(200); 836 // DevHIDKeyReport(0x06); 837 // mDelaymS(100); 838 // DevHIDKeyReport(0x00); 839 // mDelaymS(200); 840 // DevHIDKeyReport(0x0B); 841 mDelaymS(100); 842 DevHIDKeyReport(0x00); 843 } 844 } 845 846 /********************************************************************* 847 * @fn DevEP1_OUT_Deal 848 * 849 * @brief 端点1数据处理 850 * 851 * @return none 852 */ 853 void DevEP1_OUT_Deal(uint8_t l) 854 { /* 用户可自定义 */ 855 uint8_t i; 856 857 for(i = 0; i < l; i++) 858 { 859 pEP1_IN_DataBuf[i] = ~pEP1_OUT_DataBuf[i]; 860 } 861 DevEP1_IN_Deal(l); 862 } 863 864 /********************************************************************* 865 * @fn DevEP2_OUT_Deal 866 * 867 * @brief 端点2数据处理 868 * 869 * @return none 870 */ 871 void DevEP2_OUT_Deal(uint8_t l) 872 { /* 用户可自定义 */ 873 uint8_t i; 874 875 for(i = 0; i < l; i++) 876 { 877 pEP2_IN_DataBuf[i] = ~pEP2_OUT_DataBuf[i]; 878 } 879 DevEP2_IN_Deal(l); 880 } 881 882 /********************************************************************* 883 * @fn DevEP3_OUT_Deal 884 * 885 * @brief 端点3数据处理 886 * 887 * @return none 888 */ 889 void DevEP3_OUT_Deal(uint8_t l) 890 { /* 用户可自定义 */ 891 uint8_t i; 892 893 for(i = 0; i < l; i++) 894 { 895 pEP3_IN_DataBuf[i] = ~pEP3_OUT_DataBuf[i]; 896 } 897 DevEP3_IN_Deal(l); 898 } 899 900 /********************************************************************* 901 * @fn DevEP4_OUT_Deal 902 * 903 * @brief 端点4数据处理 904 * 905 * @return none 906 */ 907 void DevEP4_OUT_Deal(uint8_t l) 908 { /* 用户可自定义 */ 909 uint8_t i; 910 911 for(i = 0; i < l; i++) 912 { 913 pEP4_IN_DataBuf[i] = ~pEP4_OUT_DataBuf[i]; 914 } 915 DevEP4_IN_Deal(l); 916 } 917 918 919 /********************************************************************* 920 * @fn USB_IRQHandler 921 * 922 * @brief USB中断函数 923 * 924 * @return none 925 */ 926 __INTERRUPT 927 __HIGH_CODE 928 void USB_IRQHandler(void) /* USB中断服务程序,使用寄存器组1 */ 929 { 930 USB_DevTransProcess(); 931 }

浙公网安备 33010602011771号