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