目录
1. USB固件模块的实现简介
USB固件模块实现对USB设备的枚举,USB1.1或者USB2.0设备的识别,数据的传输和发送的功能。整个流程是遵照USB标准,但在具体实现上是结合了Usb芯片的枚举流程的中断处理和寄存器的设置。
2. USB固件执行流程
2.1 USB枚举流程示意图
该流程是硬件在插入usb端口之后,到整个枚举过程结束,硬件的所有中断和处理过程。目的是为了详细说明每一步骤的操作过程。在实际编程实现可以参看第3节的实现流程说明。
2.2 初始化usb设备
初始化描述符表,初始化usb配置寄存器,使能usb中断
2.3 reset过程
在usb设备插入PC机的usb端口的时候,产生reset中断。中断处理流程如下:
伪码:
清除reset中断
设置usb设备配置寄存器的软件复位位
设置usb设备配置寄存器的连接状态和高速位
设置usb设备地址寄存器为0
再等待2-5ms
获取usb设备状态寄存器的高速检测位
配置ep0、ep1、ep2寄存器
初始化描述符表
设置usb当前状态为default状态
2.4 第一次获取设备描述符的过程
在reset完成之后,固件已经配置好EP0,EP1,EP2的配置寄存器和中断寄存器。以及EP0的RESPONSE寄存器的状态为:
rENDP0_RESPONSE = EP_RSP_ENABLE | EP_RSP_CTRL_DIR_OUT ;
准备接收第一个setup包
2.4.1 流程的抓包分析
1)然后HOST端开始获取第一次描述符,首先是向0地址发送setup包,内容如下:
2)然后读取设备描述符信息:
3)HOST端发出0包,表示整个过程结束
2.4.2 流程的中断分析
在获取第一次设备描述符的过程中,spec core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
0x320 | CTRL_STAT_CMP/EP |
(*) 注:SOF中断没有影响,已经屏蔽了。不处理。
2.4.3 固件对各个步骤的处理
1)第一次收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_DEV;
把设备描述符写入到ep0的buffer中,等待host端读取。
2)HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3)core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4)HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5)清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.5 set address过程
2.5.1 流程的抓包分析
HOST端发出SETUP包,设置地址
HOST端读取一个空包,表示事务结束。
2.5.2 流程的中断分析
在设置地址的过程中,usb core一共产生2次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x320 | CTRL_STAT_CMP/EP | 0x1 | 对应IN包 |
2.5.3 固件对设置地址各个步骤的处理
1)当有setup中断产生的时候,首先是从缓存中读取数据,解析setup包,
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据,是设置地址,读取地址值
rENDP0_RESPONSE = rENDP0_RESPONSE & (~(EP_RSP_NAK | EP_RSP_HALT)) | (EP_RSP_ZERO_LEN_DATA|EP_RSP_DATA1_PID),清除NAK和HALT位,并置上EP_RSP_ZERO_LEN_DATA位,表示0包数据已经准备好。准备HOST端读取零包。
2)在Host端读取0包之后,core产生一个中断。表示事务已经结束。core发出ctrl_stat_cmp中断,清除ctrl_stat_cmp中断 ,并把步骤1中读取的usb 地址值设到地址寄存器中。整个过程结束。
2.6 第二次获取设备描述符的流程
2.6.1 流程的抓包分析
1)然后HOST端开始获取第二次描述符,向地址1(上一步设置的usb地址)发送setup包,请求的设备描述符的长度为0x12字节长。内容如下:
2)然后读取设备描述符信息:
3)HOST端发出0包,表示整个过程结束
2.6.2 流程的中断分析
在获取第一次设备描述符的过程中,usb core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
0x320 | CTRL_STAT_CMP/EP |
2.6.3. 固件对各个步骤的处理
1) 收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_DEV;
把设备描述符写入到ep0的buffer中,等待host端读取。
2) HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3) core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4) HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5) 清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.7. 获取配置描述符的流程
2.7.1. 流程的抓包分析
1)然后HOST端开始获取配置描述符,向地址1发送setup包,请求的配置描述符的长度为0x09字节长。内容如下:
2)然后读取配置描述符信息:
3)HOST端发出0包,表示整个过程结束
2.7.2. 流程的中断分析
在获取第一次设备描述符的过程中,spec core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
0x320 | CTRL_STAT_CMP/EP |
2.7.3. 固件对各个步骤的处理
1) 收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_CFG_ONLY;
把配置描述符写入到ep0的buffer中,等待host端读取。
2) HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3) core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4) HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5) 清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.8. 获取完整的配置描述符的流程
2.8.1. 流程的抓包分析
1)然后HOST端开始获取配置描述符,向地址1发送setup包,请求的配置描述符的长度为0xFF字节长。内容如下:
2)然后读取配置描述符信息:
3)HOST端发出0包,表示整个过程结束
2.8.2. 流程的中断分析
在获取第一次设备描述符的过程中,usb core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
0x320 | CTRL_STAT_CMP/EP |
2.8.3. 固件对各个步骤的处理
1) 收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_CFG_FULL;
把配置描述符写入到ep0的buffer中,等待host端读取。
2) HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3) core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4) HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5) 清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.9. 获取String 0描述符的流程
2.9.1. 流程的抓包分析
1)然后HOST端开始获取string 0描述符,向地址1发送setup包,
2)然后读取string 0描述符信息:
3)HOST端发出0包,表示整个过程结束
2.9.2. 流程的中断分析
在获取第一次设备描述符的过程中,usb core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
0x320 | CTRL_STAT_CMP/EP |
2.9.3. 固件对各个步骤的处理
1) 收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_STR_I0;
把string 0描述符写入到ep0的buffer中,等待host端读取。
2) HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3) core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4) HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5) 清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.10. 获取String 2描述符的流程
2.10.1. 流程的抓包分析
1)然后HOST端开始获取string 2描述符,向地址1发送setup包,
2)然后读取string 2描述符信息:
3)HOST端发出0包,表示整个过程结束
2.10.2. 流程的中断分析
在获取第一次设备描述符的过程中,usb core一共产生5次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x220 | EP | 0x1 | 对应IN包 |
0x220 | EP | 0x2 | 数据已经发送到HOST端,缓存可用 |
0x220 | EP | 0x20 | HOST端发送一空包,表示过程结束。 |
2.10.3. 固件对各个步骤的处理
1) 收到setup之后,首先是从缓存中读取数据,解析setup包,并把将要发送到host端的描述符准备好。
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据
把ep0_state 置为EP0_STATE_GD_STR_I2;
把string 2描述符写入到ep0的buffer中,等待host端读取。
2) HOST端的IN Token进来,准备buffer中的描述符读走。在中断服务程序中,设Endpoint0 响应寄存器的值为 = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE,目的是为了Host端可以读取设备描述符。
设置状态为ep0_state = EP0_STATE_INIT;
3) core在发送成功了设备描述符之后,会产生一个buf available中断,由于设备描述符是一次发送上去,所以这个中断可以不用处理。
4) HOST端在读取了设备描述符之后,会发出一个OUT包。数据为0长度的空包。core产生一个中断。清除中断源即可。core根据这个空包发出ctrl_stat_cmp中断,来表示整个事务的结束。
5) 清除ctrl_stat_cmp中断。获取设备描述符的过程结束。
2.11. set configuration的流程
2.11.1. 流程的抓包分析
1)HOST端开始set configuration,向地址1发送setup包,
2)HOST端读取一个空包,表示事务结束。
2.11.2. 流程的中断分析
在设置地址的过程中,usb core一共产生2次中断。中断状态寄存器的值和EP0中断状态寄存器的值分别如下:
rINTR_SOURCE_EP的值 | 中断类型说明 | rENDP0_INTR_REG的值 | ep0中断的解释 |
0x260 | setup中断/EP中断(*) | 0x1 | 缓存中有setup包 |
0x320 | CTRL_STAT_CMP/EP | 0x1 | 对应IN包 |
2.11.3. 固件对各个步骤的处理
1) 当有setup中断产生的时候,首先是从缓存中读取数据,解析setup包,
先置rENDP0_RESPONSE |= EP_RSP_CTRL_DIR_OUT;
读取数据
分析数据,读取configuration值
rENDP0_RESPONSE = rENDP0_RESPONSE & (~(EP_RSP_NAK | EP_RSP_HALT)) | (EP_RSP_ZERO_LEN_DATA|EP_RSP_DATA1_PID),清除NAK和HALT位,并置上EP_RSP_ZERO_LEN_DATA位,表示0包数据已经准备好。准备HOST端读取零包。
2) 再Host端读取0包之后,core产生一个中断。表示事务已经结束。core发出ctrl_stat_cmp中断,清除ctrl_stat_cmp中断 ,并把步骤1中读取的usb 地址值设到地址寄存器中。整个过程结束。
3. USB中断服务程序流程分析
3.1. 中断服务程序框架
伪码:
begin:
读取usb中断指示寄存器;
读取ep中断指示寄存器;
if(中断源是suspend)
清除中断源;
设置当前状态为suspend状态
else if(中断源是resume)
清除中断源
设置当前状态为前一状态
else if(中断源是高速指示中断)
清除中断源;
设置当前usb速度为usb2.0
else if(当前中断是reset)
见usb固件执行流程reset一节
else if(当前中断是dma结束)
清除中断源;
调用dma处理函数
else if(当前中断是ep中断)
if(是ep0)
检查是否是setup包,如果是则清除setup token标记位
清除ep0中断源标记位
清除ep中断标记位
调用ep0处理函数
if(ep1)
调用ep1处理函数
if(ep2)
调用ep2处理函数
else if(control state complete中断)
清除中断源
置ep0响应寄存器位EP_RSP_ENABLE | EP_RSP_NAK; (指示整个setup事务结束,发nak帧。)
如果是set address状态,则设置usb地址寄存器的值为host端传递的地址值。
函数返回;
end
3.2. EP0处理流程
伪码:
begin:
读取ep0中断状态寄存器
清除ep0中断源
if(ep0的中断是setup包引起的)
if(ep0中断状态为EP_INT_DATA_AVALIABLE)
设置ep0响应寄存器为transfer direction out
设置访问的寄存器为ep0
访问方式为read和buffer access
读取setup包长的数据到缓冲区
清除ep0 buffer,设置访问为disable
else
返回
解析setup包:
switch(setup包请求类型)
case:获取描述符
switch(描述符类型)
case:设备描述符
设置ep0_state 为EP0_STATE_GD_DEV;
描述符指针指向设备描述符地址
描述符长度设为设备描述符的长度
case:配置描述符
判断需要的配置描述符是完整的还是简单的
描述符指针指向配置描述符地址
描述符长度设为配置描述符的长度
case:string描述符
判断需要的string0、1、2描述符的类型
描述符指针指向相应的描述符地址
描述符长度设为对应的长度
case:接口描述符
设置ep0_state为EP0_STATE_GD_IF_ONLY
描述符指针指向接口描述符地址
描述符长度设为接口描述符的长度
case:端点描述符
判断需要哪个端点描述符
描述符指针指向对应的端点描述符地址
描述符长度设为端点描述符的长度
default:设置ep0_state为EP0_STATE_INIT;
返回
if(ep0_state不是EP0_STATE_INIT)
置ep0响应寄存器位EP_RSP_ENABLE | EP_RSP_NAK; (指示整个setup事务结束,发nak帧。)
把描述符写入到ep0 buffer
case:设置地址
ep0响应寄存器设置非NAK和非HALT,同时设置为0包状态,让host读取0包
读取usb地址
置usb当前状态为USB_ADDRESSED_STATE
case:设置配置描述符
ep0响应寄存器设置非NAK和非HALT,同时设置为0包状态,让host读取0包
读取配置值,如果为0,则设置当前状态为address状态,地址寄存器设为0
如果不是0,则表示整个枚举过程结束。
default:
设置ep0响应寄存器为:
rENDP0_RESPONSE = rENDP0_RESPONSE & (~(EP_RSP_NAK | EP_RSP_HALT)) | (EP_RSP_ZERO_LEN_DATA|EP_RSP_DATA1_PID);
ep0_state设为EP0_STATE_INIT
else // 不是setup包的中断
如果ep0的中断状态为数据可以获取并且ep0_state的状态不是初始状态。设置ep0的响应寄存器为:
rENDP0_RESPONSE = EP_RSP_ENABLE|EP_RSP_CTRL_DIR_IN|EP_RSP_DATA1_PID |EP_RSP_PID_ENABLE;
目的是为了Host端可以把数据读走。
设置ep0_state为初始状态。
返回
end
2.3. EP1处理流程
见中断处理的分析和实现一章
2.4. EP2处理流程
见中断处理的分析和实现一章
2.5. DMA中断处理流程
见中断处理的分析和实现一章
4. 数据结构定义
4.1 setup包结构定义
typedef struct st_usb_setup_data
{
INT8U bmRequestType;
INT8U bRequest;
INT8U bValueL;
INT8U bValueH;
INT8U bIndexL;
INT8U bIndexH;
INT8U bLengthL;
INT8U bLengthH;
} st_usb_setup_data;
4.2 描述符结构定义
typedef struct st_usb_device_descriptor
{
INT8U bLength;
INT8U bDescriptorType;
INT8U bcdUSBL;
INT8U bcdUSBH;
INT8U bDeviceClass;
INT8U bDeviceSubClass;
INT8U bDeviceProtocol;
INT8U bMaxPacketSize0;
INT8U idVendorL;
INT8U idVendorH;
INT8U idProductL;
INT8U idProductH;
INT8U bcdDeviceL;
INT8U bcdDeviceH;
INT8U iManufacturer;
INT8U iProduct;
INT8U iSerialNumber;
INT8U bNumConfigurations;
} st_usb_device_descriptor;
typedef struct st_usb_configuration_descriptor
{
INT8U bLength;
INT8U bDescriptorType;
INT8U wTotalLengthL;
INT8U wTotalLengthH;
INT8U bNumInterfaces;
INT8U bConfigurationValue;
INT8U iConfiguration;
INT8U bmAttributes;
INT8U maxPower;
} st_usb_configuration_descriptor;
typedef struct st_usb_interface_descriptor
{
INT8U bLength;
INT8U bDescriptorType;
INT8U bInterfaceNumber;
INT8U bAlternateSetting;
INT8U bNumEndpoints;
INT8U bInterfaceClass;
INT8U bInterfaceSubClass;
INT8U bInterfaceProtocol;
INT8U iInterface;
} st_usb_interface_descriptor;
typedef struct st_usb_endpoint_descriptor
{
INT8U bLength;
INT8U bDescriptorType;
INT8U bEndpointAddress;
INT8U bmAttributes;
INT8U wMaxPacketSizeL;
INT8U wMaxPacketSizeH;
INT8U bInterval;
} st_usb_endpoint_descriptor;
typedef struct st_usb_configuration_full_descriptor
{
INT8U bLength;
INT8U bDescriptorType;
INT8U wTotalLengthL;
INT8U wTotalLengthH;
INT8U bNumInterfaces;
INT8U bConfigurationValue;
INT8U iConfiguration;
INT8U bmAttributes;
INT8U maxPower;
st_usb_interface_descriptor usb_if;
st_usb_endpoint_descriptor usb_ep1;
st_usb_endpoint_descriptor usb_ep2;
} st_usb_configuration_full_descriptor;
5. 函数定义
5.1. usb.c文件
5.1.1. 初始化usb设备
函数名:void init_usb(void)
输入:无
输出:无
功能描述:初始化描述符表,初始化usb配置寄存器,使能usb中断
5.1.2. usb中断服务程序
函数名:void usbd_isr(void)
输入:
输出:
功能描述:处理usb中断,包括复位、EP0、EP1、EP2等usb相应的中断。
5.1.3. 配置usb描述符
函数名:void config_usbd(void)
输入:无
输出:无
功能描述:配置ep0、ep1、ep2的相关寄存器、以及usb设备寄存器,打开usb中断。
5.1.4. USB DMA中断处理程序
函数名:void usb_dma_irq(void)
输入:无
输出:无
功能描述:ep1和ep2使用dma搬移数据之后的中断处理
5.1.5. USB DMA写端点函数
函数名:void usb_dma_write(INT32U *src_addr, INT16U data_size)
输入:src_addr 数据在ram中缓存地址
data_size 数据长度
输出:无
功能描述:启动usb dma把数据从ram区搬到usb 端点缓冲区
5.1.6. USB DMA读端点函数
void usb_dma_read(void);
输入:无
输出:无
功能描述:启动usb dma把数据从usb 端点缓冲区搬到ram区
5.2. usbsetup.c文件
5.2.1. ep0中断处理函数
函数名:void ep0_handler(INT32S b_setup_packet);
输入:b_setup_packet 是否为setup包产生的中断
TRUE:是
FALSE:否
输出:无
功能描述:处理ep0中断,包括整个枚举过程
5.2.2. 初始化描述符表
函数名:void init_descriptor_table(void);
功能描述:初始化描述符的值
5.3. usbin.c文件
5.3.1. ep1中断处理函数
函数名:ep1_handler(void);
功能描述:处理ep1中断,指示数据已经被host端读走
5.4. usbout.c文件
5.4.1. ep2中断处理函数
函数名:ep2_handler(void);
功能描述:处理ep2中断,接收从host端发来的数据