新手入门
- 积分
- 7
- 金钱
- 7
- 注册时间
- 2017-10-21
- 在线时间
- 0 小时
|
发表于 2014-12-30 10:05:36
|
显示全部楼层
本来不想回复了问题解决了就行了 但是看到最近还有人在问这个问题 我想还是回复下帮助广大嵌入式人员
本人解决办法:
本来改库是一件让人觉得不可取的事,但是没办法 ST库虽好用但是BUG确实不少,回到主题
看代码:
case CTRL_SETUP:
/* send a SETUP packet */
USBH_CtlSendSetup (pdev,
phost->Control.setup.d8 ,
phost->Control.hc_num_out);
phost->Control.state = CTRL_SETUP_WAIT;
break;
case CTRL_SETUP_WAIT:
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
/* case SETUP packet sent successfully */
if(URB_Status == URB_DONE)
{
direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
/* check if there is a data stage */
if (phost->Control.setup.b.wLength.w != 0 )
{
timeout = DATA_STAGE_TIMEOUT;
if (direction == USB_D2H)
{
/* Data Direction is IN */
phost->Control.state = CTRL_DATA_IN;
}
else
{
/* Data Direction is OUT */
phost->Control.state = CTRL_DATA_OUT;
}
}
/* No DATA stage */
else
{
timeout = NODATA_STAGE_TIMEOUT;
/* If there is No Data Transfer Stage */
if (direction == USB_D2H)
{
/* Data Direction is IN */
phost->Control.state = CTRL_STATUS_OUT;
}
else
{
/* Data Direction is OUT */
phost->Control.state = CTRL_STATUS_IN;
}
}
/* Set the delay timer to enable timeout for data stage completion */
phost->Control.timer = HCD_GetCurrentFrame(pdev);
}
else if(URB_Status == URB_ERROR)
{
phost->Control.state = CTRL_ERROR;
phost->Control.status = CTRL_XACTERR;
}
break;
。。。。。。。。。
看看 在 case CTRL_SETUP: 中有这句
phost->Control.state = CTRL_SETUP_WAIT;
程序下次进来就直接到:case CTRL_SETUP_WAIT:中去了
可是万万没想到
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
URB_Status的值居然还会有:URB_IDLE但是 这里只有:
if(URB_Status == URB_DONE)
{
。。。。。。。。。。。。
}
else if(URB_Status == URB_ERROR)
{
。。。。。
}
只要状态是URB_IDLE 就出现了死等;就其原因我们跟踪
case CTRL_SETUP_WAIT:中的
URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
发现是在
URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
{
return pdev->host.URB_State[ch_num] ;
}这里获取状态然而这个状态 的改变估计是usb host 中断里处理的 估计是接收超时中断处理就给它赋值了个URB_IDLE
所以看看库里的
case CTRL_SETUP:
/* send a SETUP packet */
USBH_CtlSendSetup (pdev,
phost->Control.setup.d8 ,
phost->Control.hc_num_out);
phost->Control.state = CTRL_SETUP_WAIT;
USB_OTG_BSP_mDelay(50);
break;
这里在发数据 估计这里是发送后要么usb device没收到 没响应 要么是回复了 结果我们的host 在哪里处理的时候给把状态清掉了 没收到 所以两边估计都在等但是我在想usb 作为master 必须主动传输所以这时候我们必须让host 再次发一次数据试试
就在 case CTRL_SETUP_WAIT:
后面加了 如下代码
else if(URB_Status==URB_IDLE)//modify by ÕÅĬ
{
phost->Control.state = CTRL_SETUP;
}
让它在回去再发一次。。。。。可是万万没想到啊 这个再次发送居然还没起效 还是不行。。。。。。
估计是不是发送了马上获取在 wait中获取状态 是不是单片机会在获取状态之后把状态给清了 所以一不做二不休 在发送完数据之后给加个延时
所以就成这样了
case CTRL_SETUP:
/* send a SETUP packet */
USBH_CtlSendSetup (pdev,
phost->Control.setup.d8 ,
phost->Control.hc_num_out);
phost->Control.state = CTRL_SETUP_WAIT;
USB_OTG_BSP_mDelay(50); //这是我自己加的
break;
再次编译运行 居然优盘认出来了 皆大欢喜
但是这修改的两处去掉一处 都不行 所以都保留着
这个办法 虽不可取 但是我坚定的认为这是 st库的bug 所以坚决的改了
以上是我的处理办法 本人接触单片机已 10年左右 喜欢交朋友 如果有愿意交行业朋友的可以加我qq2656045050 加我 我们互相交流 传输经验 |
|