对技术执着
分类: 嵌入式
2013-07-03 13:59:04
原文地址:USB固件开发总结(二) 作者:jmyu2006
3.2 固件在USB设备设别阶段的编程思路
一般地,USB设备接口芯片会产生一些中断来通知程序员特定事件的发生。譬如说,EP0(缺省控制端点) SETUP包的到达,EP
这个例子的思路是,在响应USB产生的中断时,会用全局变量记录下中断的发生,然后在主循环里面进行具体处理。
/* USB服务程序伪代码 */
void USB_Service(void)
{
/*处理控制传输的3个阶段*/
switch (EP.EP0.Stage)
{
case C_STAGE_EP0_SETUP: /*处在建立阶段*/
if (!USB_Setup ()) /*如果请求是被支持的*/
EP.EP0.Stage = C_STAGE_EP0_DATA; /*转入数据阶段*/
break;
case C_STAGE_EP0_DATA: /*处在数据阶段*/
if (EP.EP0.Status == C_STATUS_EP0_IN_NACK) /*收到了IN令牌*/
{
USB_WriteEP0FIFO(); /*通过控制端点发送数据给主机*/
EP.EP0.Status = C_STATUS_RESET; /*已处理完毕,所以复位此状态*/
EP.EP0.Stage = C_STAGE_EP0_STATUS; /*转入状态阶段*/
重新使能EP0_IN_NACK中断; /*在ISR中会关掉此中断*/
}
break;
case C_STAGE_EP0_STATUS:
使能EP0_STATUS寄存器;
break;
default:
break;
}
}
/*USB中断服务程序伪代码(部分)*/
void USB_ISR(void)
{
if (SETUP包到达)
{
清中断;
EP.EP0.Stage = C_STAGE_EP0_SETUP;
EP.EP0.Status = C_STATUS_EP0_SETUP_ARRIVAL;
}
else
if (EP
{
清中断;
关闭此中断;
EP.EP0.Status = C_STATUS_EP0_IN_NACK;
}
}
/*USB控制传输的建立阶段处理程序伪代码*/
int USB_Setup (void)
{
通过各寄存器的值来得到请求的类型和相关数据;
if (请求类型是读取描述符)
{
switch (描述符值)
{
case 设备描述符值:
将全局的发送数据的指针指向设备描述符buffer;
break;
......
default: break;
}
}
else if (设备还需处理的其他请求)
{
处理;
}
else /*不支持的请求*/
{
发送STALL信号;
return 1; /*返回错误*/
}
return 0; /*返回正确*/
}
/*通过端点0发送数据*/
void USB_WriteEP0FIFO(void)
{
取得全局的发送数据的指针;
利用指针读取描述符的数据并填充至端点0的FIFO;
通知芯片EP
}