四、USB的“JoyStickMouse”工作过程详细分析
1、枚举第一步:获取设备的描述符
从USB_init()开始
(1)先要允许数据传输完成中断
在poweron()函数后面紧跟着几句话:
PowerOn();
//这句执行完,设备被主机检测到,并且能够响应复位中断了。
_SetISTR(0);
/* clear pending interrupts */
wInterrupt_Mask = IMR_MSK;
_SetCNTR(wInterrupt_Mask); /* set interrupts mask */
//以上这两句话将允许所有的USB中断
bDeviceState = UNCONNECTED;
//设备状态置位为未连接状态。这里我不太理解。这时候即使复位中断未发生,最起码设备已经算是连接入总线了,为什么这个状态还要设置为“未连接”呢?
(2)主机获取描述符
主机进入控制传输的第一阶段:建立事务,发setup令牌包、发请求数据包、设备发ACK包。
主机发出对地址0、端点0发出SETUP令牌包,首先端点0寄存器的第11位SETUP位置位,表明收到了setup令牌包。
由于此时端点0数据接收有效,所以接下来主机的请求数据包被SIE保存到端点0描述附表的 RxADDR里面,收到的字节数保存到 RxCount里面。
端点0寄存器的CTR_RX被置位为1,ISTR的CTR置位为1,DIR=1,EP_ID=0,表示端点0接收到主机来的请求数据。此时设备已经ACK主机,将触发正确传输完成中断,下面就进入中断看一看。
_SetISTR((u16)CLR_CTR); /*首先清除传输完成标志 */
EPindex = (u8)(wIstr & ISTR_EP_ID); //获取数据传输针对的端点号。
if (EPindex == 0)
//如果是端点0,这里的确是端点0
{
SaveRState = _GetEPRxStatus(ENDP0); //保存端点0状态,原本是有效状态。
SaveTState = _GetEPTxStatus(ENDP0);
_SetEPRxStatus(ENDP0, EP_RX_NAK); //在本次数据处理好之前,对主机发来的数据包以NAK回应
_SetEPTxStatus(ENDP0, EP_TX_NAK);
if ((wIstr & ISTR_DIR) == 0) //如果是IN令牌,数据被取走
{
_ClearEP_CTR_TX(ENDP0);
In0_Process();
//调用该程序处理固件数据输出后的工作。
_SetEPRxStatus(ENDP0, SaveRState);
_SetEPTxStatus(ENDP0, SaveTState);
return;
}
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |