USB裝置在端點4~7互動資料

JayWell發表於2024-06-05

目錄

在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 }

相關文章