当前位置:网站首页>CH549/CH548学习笔记9 - USB Device端点处理过程
CH549/CH548学习笔记9 - USB Device端点处理过程
2022-07-18 01:07:00 【pq113_6】
目录
端点处理最重要的是端点0的处理过程,注意端点0和端点4都不支持自动翻转同步标志位的功能。
1. 端点读
当主机OUT数据后,芯片会把数据放在对应端点的buffer中,所以读这些buffer就可以得到对应的数据。注意,双向buffer中的前半段是OUT Buffer。而有效数据长度共用一个寄存器USB_RX_LEN。
uint8_t usbReadBuf(uint8_t port, uint8_t* buf, uint8_t len)
{
xdata uint8_t *pUsbBuf[] =
{
usbEp0Buffer,
#if(EP1_OUT_MEM_SIZE > 0)
usbEp1Buffer,
#else
NULL,
#endif
#if(EP2_OUT_MEM_SIZE > 0)
usbEp2Buffer,
#else
NULL,
#endif
#if(EP3_OUT_MEM_SIZE > 0)
usbEp3Buffer,
#else
NULL,
#endif
#if(EP4_OUT_MEM_SIZE > 0)
usbEp4Buffer,
#else
NULL,
#endif
};
uint8_t length;
if(port > USB_EP_MAX)
return 0;
if(len > USB_RX_LEN)
length = USB_RX_LEN;
if(pUsbBuf[port] != NULL)
{
memcpy(buf, pUsbBuf[port], length);
}
return length;
}2. 端点写
将数据拷贝到对应端点的缓冲区,然后设置端点的发送长度寄存器UEPn_T_LEN,最后设置UEPn_CTRL寄存器使能发送。
uint8_t usbWriteBuf(uint8_t port, uint8_t* buf, uint8_t len)
{
uint8_t length = 0;
switch(port)
{
case 0:
length = (len > EP0_IN_MEM_SIZE) ? len : EP0_IN_MEM_SIZE;
memcpy(usbEp0Buffer, buf, len);
UEP0_T_LEN = length;
UEP0_CTRL = (UEP0_CTRL & ~ MASK_UEP_T_RES) | UEP_T_RES_ACK;
break;
#if (EP1_IN_MEM_SIZE > 0)
case 1:
length = (len > EP1_IN_MEM_SIZE) ? len : EP1_IN_MEM_SIZE;
memcpy(usbEp1Buffer + EP1_OUT_MEM_SIZE, buf, len);
UEP1_T_LEN = length;
UEP1_CTRL = (UEP1_CTRL & ~ MASK_UEP_T_RES) | UEP_T_RES_ACK;
break;
#endif
#if (EP2_IN_MEM_SIZE > 0)
case 2:
length = (len > EP2_IN_MEM_SIZE) ? len : EP2_IN_MEM_SIZE;
memcpy(usbEp2Buffer + EP2_OUT_MEM_SIZE, buf, len);
UEP2_T_LEN = len;
UEP2_CTRL = (UEP2_CTRL & ~ MASK_UEP_T_RES) | UEP_T_RES_ACK;
break;
#endif
#if (EP3_IN_MEM_SIZE > 0)
case 3:
length = (len > EP3_IN_MEM_SIZE) ? len : EP3_IN_MEM_SIZE;
memcpy(usbEp3Buffer + EP3_OUT_MEM_SIZE, buf, len);
UEP3_T_LEN = length;
UEP3_CTRL = (UEP3_CTRL & ~ MASK_UEP_T_RES) | UEP_T_RES_ACK;
break;
#endif
#if (EP4_IN_MEM_SIZE > 0)
case 4:
length = (len > EP4_IN_MEM_SIZE) ? len : EP4IN_MEM_SIZE;
memcpy(usbEp4Buffer + EP4_OUT_MEM_SIZE, buf, len);
UEP4_T_LEN = length;
UEP4_CTRL = (UEP4_CTRL & ~ MASK_UEP_T_RES) | UEP_T_RES_ACK;
break;
#endif
}
return length;
}3. SETUP过程
对应中断处理case UIS_TOKEN_SETUP的情况。
3.1 预置NAK
UEP0_CTRL = UEP0_CTRL & (~MASK_UEP_T_RES )| UEP_T_RES_NAK;设置NAK表示端点0正忙。
3.2 处理SETUP数据
这一步与其他芯片处理方式一样。
3.3 设置ACK
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;SETUP必定是DATA0,所以这里将CTRL设置为 DATA1,并恢复ACK状态。
完整的Setup处理过程如下:
case UIS_TOKEN_SETUP:
if(ep != 0)
break;
if(USB_RX_LEN != (sizeof(gUsbReqInfo)))
{
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;//STALL
break;
}
usbReadBuf(USB_EP0, (uint8_t *)(&gUsbReqInfo), sizeof(gUsbReqInfo));
UEP0_CTRL = UEP0_CTRL & (~MASK_UEP_T_RES )| UEP_T_RES_NAK;
//Setup处理过程
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; //Default DATA1 and return ACK
break;4. IN过程
对应中断处理case UIS_TOKEN_IN的情况,这个过程分端点0和其他端点的情况。
端点0和端点4都不支持自动翻转同步标志位,所以要添加对应的翻转命令。端点0在数据大于0的情况下才翻转。
case UIS_TOKEN_IN:
if(ep == 0)
{
if(gUsbReqInfo.wLength > 0)
UEP0_CTRL ^= bUEP_T_TOG;
//端点0 IN操作
}
else
{
void(*usbEpnIntUser[])(void) =
{
usbEp1InUsr,
usbEp2InUsr,
usbEp3InUsr,
usbEp4InUsr,
};
if(ep == 4)
UEP4_CTRL ^= bUEP_T_TOG;
(*usbEpnIntUser[ep - 1])();
}
break;5. OUT过程
对应中断处理case UIS_TOKEN_OUT的情况,和IN类似。
case UIS_TOKEN_OUT:
if(ep == 0)
{
UEP0_CTRL ^= bUEP_R_TOG;
//端点0 OUT处理过程
}
else
{
void(*usbEpnIntUser[])(void) =
{
usbEp1OutUsr,
usbEp2OutUsr,
usbEp3OutUsr,
usbEp4OutUsr,
};
if(ep == 4)
UEP4_CTRL ^= bUEP_R_TOG;
(*usbEpnIntUser[ep - 1])();
}
break;边栏推荐
- Is online fund account opening safe? Find the answer online
- Excel cell settings drop-down options
- 保持淡然的心情
- 【C语言】万字文件操作总结
- PwnTheBox,Web:Double-S
- codeforce:B. Difference Array【前缀0的优化】
- Identity server 4 uses openid connect to add user authentication (3)
- Mysql 温故知新系列「触发器详解」
- [MCU simulation project] the nixie tube displays 0 to 5 in turn (Proteus schematic +keil code)
- Solidworks装配体常见问题汇总(随时更新)
猜你喜欢

A few lines of code, let black and white old photos regain their vitality!

Mogdb/opengauss permission collation

A Ye's new hairstyle
![Codeforce:b. mark the dust sweeper [fill 0 + move]](/img/c0/60756fac5f62054c76123a2ae400e1.png)
Codeforce:b. mark the dust sweeper [fill 0 + move]

Open3d library installation, CONDA common instructions, importing open3d times this error solving environment: failed with initial frozen solve Retrying w

Woman Yelling At a Cat

Solve the problem of "license manager error -8" after matlab installation (the personal test is valid)

Opencv image transparent area clipping imagecroppingtrn

Liquibase学习 - 问题解决:启动报错
![[FPGA]: IP core ----- CIC filter](/img/c4/43ce1992d03318b03ede6c77832a0d.png)
[FPGA]: IP core ----- CIC filter
随机推荐
几行代码,让黑白老照片重获新生!
在线摇骰子色子工具
我,35岁了。
努力锻炼游泳技能
2022/07 CSI TOOL 安装过程记录
JVM personal learning notes
Excel cell settings drop-down options
Next stop, embossed AI
深度学习环境配置TensorFlow2+Keras
如何正确重写hashCode方法?
MySQL - 表索引概述
Liquibase learning 1 - installation, simple use
Pwnthebox, Web: Double - S
MogDB/openGauss 权限整理
洗澡的新发现
The junior engineer in the group asked for help and said that if he wanted to collect the recruitment data, he must be arranged
网上基金开户安全吗?新手求指导
腾讯出品的良心产品?翻译君功能详细体验
JUC源码学习笔记2——AQS共享和Semaphore,CountDownLatch
金融银行软件测试超大型攻略,最受欢迎的金融银行大揭秘附面试题