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 }
USB Process

 

posted @ 2026-01-30 13:35  oTvTo  阅读(5)  评论(0)    收藏  举报