求助:lpc17xx USB 通信数据包丢失的原因?
使用keil例子中的CDC改写中断程序
void USB_IRQHandler (void) {
U32 disr, val, n, m;
U32 episr, episrCur;
disr = LPC_USB->USBDevIntSt; /* Device Interrupt Status */
/* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
if (disr & DEV_STAT_INT) {
LPC_USB->USBDevIntClr = DEV_STAT_INT;
WrCmd(CMD_GET_DEV_STAT);
val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */
if (val & DEV_RST) { /* Reset */
USB_Reset();
#if USB_RESET_EVENT
USB_Reset_Event();
#endif
}
if (val & DEV_CON_CH) { /* Connect change */
#if USB_POWER_EVENT
USB_Power_Event(val & DEV_CON);
#endif
}
if (val & DEV_SUS_CH) { /* Suspend/Resume */
if (val & DEV_SUS) { /* Suspend */
USB_Suspend();
#if USB_SUSPEND_EVENT
USB_Suspend_Event();
#endif
} else { /* Resume */
USB_Resume();
#if USB_RESUME_EVENT
USB_Resume_Event();
#endif
}
}
goto isr_end;
}
#if USB_SOF_EVENT
/* Start of Frame Interrupt */
if (disr & FRAME_INT) {
DEV_INT_CLR = FRAME_INT;
USB_SOF_Event();
}
#endif
#if USB_ERROR_EVENT
/* Error Interrupt */
if (disr & ERR_INT) {
DEV_INT_CLR = ERR_INT;
WrCmd(CMD_RD_ERR_STAT);
val = RdCmdDat(DAT_RD_ERR_STAT);
USB_Error_Event(val);
}
#endif
/* Endpoint's Slow Interrupt */
if (disr & EP_SLOW_INT) {
episrCur = 0;
episr = LPC_USB->USBEpIntSt;
for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
if (episr == episrCur) break; /* break if all EP interrupts handled */
if (episr & (1 << n)) {
episrCur |= (1 << n);
m = n >> 1;
LPC_USB->USBEpIntClr = (1 << n);
while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0);
val = LPC_USB->USBCmdData;
if ((n & 1) == 0) { /* OUT Endpoint */
if (n == 0) { /* Control OUT Endpoint */
if (val & EP_SEL_STP) { /* Setup Packet */
if (USB_P_EP) {
USB_P_EP(USB_EVT_SETUP);
continue;
}
}
}
if (USB_P_EP) {
USB_P_EP(USB_EVT_OUT);
}
} else { /* IN Endpoint */
if (USB_P_EP) {
USB_P_EP(USB_EVT_IN);
}
}
}
}
LPC_USB->USBDevIntClr = EP_SLOW_INT;
}
#if USB_DMA
/* USB_DMA not yet supported */
#endif /* USB_DMA */
isr_end:
;
}端点读写/*
*Read USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* Return Value: Number of bytes read
*/
U32 USB_ReadEP (U32 EPNum, U8 *pData) {
U32 cnt, n;
LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
do {
cnt = LPC_USB->USBRxPLen;
} while ((cnt & PKT_RDY) == 0);
cnt &= PKT_LNGTH_MASK;
for (n = 0; n < (cnt + 3) / 4; n++) {
*((__packed U32 *)pData) = LPC_USB->USBRxData;
pData += 4;
}
LPC_USB->USBCtrl = 0;
if (((EP_MSK_ISO >> (EPNum & 0x0F)) & 1) == 0) { /* Non-Isochronous Endpoint */
WrCmdEP(EPNum, CMD_CLR_BUF);
}
return (cnt);
}
/*
*Write USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* cnt: Number of bytes to write
* Return Value: Number of bytes written
*/
U32 USB_WriteEP (U32 EPNum, U8 *pData, U32 cnt) {
U32 n;
LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
LPC_USB->USBTxPLen = cnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
LPC_USB->USBTxData = *((__packed U32 *)pData);
pData += 4;
}
LPC_USB->USBCtrl = 0;
WrCmdEP(EPNum, CMD_VALID_BUF);
return (cnt);
}
端点中断程序void USB_EndPoint2 (U32 event)
{
LED2_ON;
switch (event)
{
case USB_EVT_IN:
USBSndRdy=1;
break;
case USB_EVT_OUT:
USBRecRdy=1;
break;
}
}接收数据:
主机向端点2发送OUT包-》lpc产生USB中断(在此清除中断)-》调USB_EndPoint2 函数-》在主循环中检查 USBRecRdy状态,如果状态为1,调USB_ReadEP ,在USB_ReadEP 中读取数据
-》 调 WrCmdEP(EPNum, CMD_CLR_BUF); 释放缓存-》准备再次接受数据。
在此过程中如果不释放缓存,还会接收主机的数据吗?如果会,是否就覆盖当前缓存?
发送数据:
检查USBSndRdy状态,如果为1-》调USB_WriteEP 写数据到usb缓存,确认缓存后-》主机下一个in后数据发送到主机,产生USB_EndPoint2 IN中断, 设置 USBSndRdy=1;如果以后无数据直接写0字节数据。
此过程是否是只要确认缓存就产生in中断?确认缓存后如果主机没有in数据,接着再次写数据是否会覆盖原先的数据?
发送和接收是否不能小于1ms?
请大家帮忙分析一下! 实在是搞不定了,上位机用libusb开双线程读写,读写都会丢失数据。 想用dma,zlg的例子实在是看不明白,我觉得kei的代码风格比较易读。 用户手册上是这样写的;
按手册上说的,只要不读取端点,以后的OUT包全部会拒绝,直到清除缓存后。在主循环中检查接收状态,如果为1,再读取端点数据是没有问题的,有时候会检查不到接收状态。 批量模式可以1ms发送多个包! 如果不发送0字节数据,则发送接收不会丢失数据,应用上每次读取1024,下位机有时候只有64字节数据,发送完64字节后,必须发送0字节包,否则,上位机读取函数不返回。 今天测试一天,依然没有找到问题,不知道这个是不是lpc17的bug,明天到stm32上面试一下,希望没有这个问题。 测试stm32可以发送0字节数据包,bus hound 不会抓取到0字节数据包,使用正常。使用lpc17发送0字节数据包,bus hound 能抓取到0字节数据包。 为什么中断会覆盖呢? 本来中断是IN中断,结果执行OUT中断。 进入中断后,关闭usb中断,函数结束时,打开中断,问题依旧! 还是keil的例子有问题,stm32有时候也不稳定,最终使用st的库,目前测试正常! adongliu 发表于 2013-5-13 08:27 static/image/common/back.gif
用户手册上是这样写的;
楼主可以把你 使用的手册 共享1下吗 谢谢 去zlg下载 吧,上传太慢了! 最近在看USB,还不知道怎么弄,先MARK下吧{:biggrin:}
页:
[1]