是因为USB复位这一块设计有问题,正常情况下,只要USB主识别到USB从节点插入,会发送一个复位信号给USB从,USB从模块会捕捉到这个信号,然后复位USB从模块寄存器等相关配置,然后USB主会分配一个地址号给从,然后USB从会开始重新枚举配置符,最后根据PC的驱动建立USB端点连接。
下面是我的代码 这个例子是演示这个过程的
- void USB0_IRQHandler(void)
- {
- //DisableInterrupts;
- // 检测USB 模块是否解析到有效的复位。
- if(K60.USB0->ISTAT_Bit.USBRST)
- {
- USB_Reset_Handler();
- //EnableInterrupts;
- return;
- }
- if(K60.USB0->ISTAT_Bit.SOFTOK)
- {
- //K60.USB0->ISTAT_Bit.SOFTOK=1;
- K60.USB0->ISTAT=0x04;
- }
- // 检测STALL
- if(K60.USB0->ISTAT_Bit.STALL)
- {
- if(K60.USB0->ENDPOINT[0].ENDPT_Bit.EPSTALL)
- {
- K60.USB0->ENDPOINT[0].ENDPT_Bit.EPSTALL=0;
- }
- K60.USB0->ISTAT=0x80;
- //K60.USB0->ISTAT_Bit.STALL=1;
- }
- // 令牌完成中断
- if(K60.USB0->ISTAT_Bit.TOKDNE)
- {
- LED_SET_TimeOut_DATA(&LEDs.USB);
- // USB 处理函数
- handlers[K60.USB0->STAT_Bit.ENDP](K60.USB0->STAT);
- // 清除令牌完成中断
- //K60.USB0->ISTAT_Bit.TOKDNE=1;
- K60.USB0->ISTAT=0x08;
- }
- // SLEEP
- if(K60.USB0->ISTAT_Bit.SLEEP)
- {
- // 清除SLEEP中断
- //K60.USB0->ISTAT_Bit.SLEEP=1;
- K60.USB0->ISTAT=0x10;
- }
- // 错误
- if(K60.USB0->ISTAT_Bit.ERROR)
- {
- //K60.USB0->ISTAT_Bit.ERROR=1;
- K60.USB0->ISTAT=0x02;
- while(1);
- }
- //EnableInterrupts;
- }
- void USB_Reset_Handler(void)
- {
- K60.USB0->CTL_Bit.ODDRST=1;
- //禁止所有端点
- for(int i=0;i<16;i++)
- {
- K60.USB0->ENDPOINT[i].ENDPT=0;
- USB_States.EndPointStatus.EndPoint[i].Data=0;
- USB_States.EndPointStatus.EndPoint[i].EVEN=0;
- USB_States.EndPointStatus.EndPoint[i].ODD=0;
- USB_States.EndPointStatus.EndPoint[i].Status=0;
- }
-
- //K60.USB0->USBTRC0|=0x40;//强制设置第6位为1
- //端点0
- Table[BDT_INDEX(0, Rx, ODDx)].Addr = &USB_States.Buff_0[0][0];
- Table[BDT_INDEX(0, Rx, ODDx)].Desc = BDT_DESC2(ENDP_SIZE, 1);
- Table[BDT_INDEX(0, Rx, EVENx)].Addr = &USB_States.Buff_1[0][0];
- Table[BDT_INDEX(0, Rx, EVENx)].Desc = BDT_DESC2(ENDP_SIZE, 0);
- Table[BDT_INDEX(0, Tx, ODDx)].Addr=&USB_States.Buff_0_tx[0][0];
- Table[BDT_INDEX(0, Tx, ODDx)].Desc = 0;
- Table[BDT_INDEX(0, Tx, EVENx)].Addr=&USB_States.Buff_0_tx[1][0];
- Table[BDT_INDEX(0, Tx, EVENx)].Desc = 0;
-
- // 使能 EP0
- K60.USB0->ENDPOINT[0].ENDPT=0x0D;
- K60.USB0->CTL_Bit.ODDRST=0;
- // 清除所有的错误
- K60.USB0->ERRSTAT=0xFF;
- // 清除所有的中断标志
- K60.USB0->ISTAT=0xFF;
- // USB设备地址
- K60.USB0->ADDR=0x00;
- // 使能所有的错误中断
- K60.USB0->ERREN=0xFF;
- // USB模块中断使能
- K60.USB0->INTEN_Bit.TOKDNEEN=1;
- K60.USB0->INTEN_Bit.SOFTOKEN=1;
- K60.USB0->INTEN_Bit.ERROREN=1;
- K60.USB0->INTEN_Bit.USBRSTEN=1;
- K60.USB0->CTL_Bit.TXSUSPENDTOKENBUSY=0;
- }
|