Closed supf1994 closed 1 year ago
keil没有问题,找其他原因吧
其次 hub出现的问题,只能自己解决了
大佬,readme底下有群,可以加群交流
复测了 O2 没有问题的。这个自己检查原因吧
经过我这边测试,问题出在 ` static void dwc2_inchan_irq_handler(uint8_t ch_num) { uint32_t chan_intstatus; struct dwc2_pipe chan; struct usbh_urb urb;
chan_intstatus = (USB_OTG_HC(ch_num)->HCINT) & (USB_OTG_HC((uint32_t)ch_num)->HCINTMSK);
chan = &g_dwc2_hcd.pipe_pool[ch_num];
urb = chan->urb;
//printf("s1:%08x\r\n", chan_intstatus);
for (uint32_t i = 0; i < 0xf; i++) {
}
if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
urb->errorcode = 0;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EIO;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EPERM;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EAGAIN;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
} else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EAGAIN;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
} else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EIO;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
} else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EIO;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EPIPE;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
} else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
urb->errorcode = -EIO;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
} else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
USB_MASK_HALT_HC_INT(ch_num);
if (urb->errorcode == 0) {
uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* size that has received */
uint32_t has_sent_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_DIEPTSIZ_PKTCNT) >> 19); /*how many packets has sent*/
chan->xfrd += count;
if ((has_sent_packets % 2) == 1) /* Flip in odd numbers */
{
if (chan->data_pid == HC_PID_DATA0) {
chan->data_pid = HC_PID_DATA1;
} else {
chan->data_pid = HC_PID_DATA0;
}
}
if (chan->ep_type == 0x00) {
if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) {
chan->ep0_state = DWC2_EP0_STATE_SETUP;
urb->actual_length = chan->xfrd;
dwc2_pipe_waitup(chan);
}
} else if (chan->ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
urb->iso_packet[chan->iso_frame_idx].actual_length = chan->xfrd;
urb->iso_packet[chan->iso_frame_idx].errorcode = urb->errorcode;
chan->iso_frame_idx++;
if (chan->iso_frame_idx == urb->num_of_iso_packets) {
dwc2_pipe_waitup(chan);
} else {
dwc2_iso_pipe_init(chan, &urb->iso_packet[chan->iso_frame_idx]);
}
} else {
urb->actual_length = chan->xfrd;
dwc2_pipe_waitup(chan);
}
} else if (urb->errorcode == -EAGAIN) {
/* re-activate the channel */
dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
} else {
dwc2_pipe_waitup(chan);
}
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
}
} ` 函数下的 for (uint32_t i = 0; i < 0xf; i++) {} 循环,这应该是一个延时,当我在Og模式下将这个延时注释掉之后,也会无法枚举成功
那就这样吧,没办法
我在keil上 O0~O2 Os 都是没问题的
刚又复测了一遍
刚又复测了一遍
这种情况比较奇怪,我在另一个工程里并没有出现这个问题,在当前工程里,debug模式下开的是Og优化,如果把 for (uint32_t i = 0; i < 0xf; i++) {} 延迟保留,则程序一切正常,将延迟注释掉,便无法正常枚举,开了O2优化及时保留延迟依然无法正常枚举,延迟放在这边感觉应该是O2将这个空循环给优化掉了,延迟再这边的作用是什么,进了中断后还有其他的寄存器状态没有切换完成,所以等待吗?
并且我在进入 dwc2_inchan_irq_handler 前加上一个字符的串口打印,也就可以正常的枚举,感觉像是中断程序运行过快会出问题
那个加不加无所谓的,只是为了减少 NAK 次数,之前调试没有删掉罢了。
这个 ip 的状态获取有点误差,中断来了但是状态没有切换,猜测是这样。我这边是没有重试机制的,超时就拜拜,不会重试
加群了吗,群里说吧
应该是全局变量优化问题,晚点我改下
好吧,不是全局变量问题,我把控制传输的 NAK 重传功能打开了,虽然中断会多点,但是会比较稳定。
不过用了dma,还会受到NAK ,这种ip挺垃圾的
不过用了dma,还会受到NAK ,这种ip挺垃圾的
是的,这样频繁进中断性能损耗大,我目前是改成 for (volatile uint32_t i = 0; i < 0xf; i++) {} 添加 volatile 来防止编译器优化掉该循环,在公司里测试是可以稳定枚举成功,做虚拟串口通信也正常,但不清楚在用户现场有干扰的情况下会不会出问题
我用 O2 是正常的,O0 需要加这个循环。不过我已经加了 NAK重传了,也无所谓了
先关了哈,大佬有问题再 reopen.
开启o2优化后便无法枚举成功,开Og是正常的