USB Device固件实现设计文档

目录

1. USB固件模块的实现简介

2. USB固件执行流程

2.1 USB枚举流程示意图

2.2 初始化usb设备

2.3 reset过程

2.4 第一次获取设备描述符的过程

2.4.1 流程的抓包分析

2.4.2 流程的中断分析

2.4.3 固件对各个步骤的处理

2.5 set address过程

2.5.1 流程的抓包分析

2.5.2 流程的中断分析

2.5.3 固件对设置地址各个步骤的处理

2.6 第二次获取设备描述符的流程

2.6.1  流程的抓包分析

​编辑 2.6.2 流程的中断分析

         2.6.3.    固件对各个步骤的处理

2.7.    获取配置描述符的流程

2.7.1.    流程的抓包分析

2.7.2.    流程的中断分析

2.7.3.    固件对各个步骤的处理

2.8.    获取完整的配置描述符的流程

2.8.1.    流程的抓包分析

2.8.2.    流程的中断分析

2.8.3.    固件对各个步骤的处理

2.9.    获取String 0描述符的流程

2.9.1.    流程的抓包分析

2.9.2.    流程的中断分析

2.9.3.    固件对各个步骤的处理

2.10.    获取String 2描述符的流程

2.10.1.    流程的抓包分析

​编辑 2.10.2.    流程的中断分析

2.10.3.    固件对各个步骤的处理

2.11.    set configuration的流程

2.11.1.    流程的抓包分析

2.11.2.    流程的中断分析

2.11.3.    固件对各个步骤的处理

3.    USB中断服务程序流程分析

3.1.    中断服务程序框架

3.2.    EP0处理流程

2.3.    EP1处理流程

2.4.    EP2处理流程

2.5.    DMA中断处理流程

4. 数据结构定义

4.1 setup包结构定义

4.2 描述符结构定义

5.    函数定义

5.1.    usb.c文件

5.1.1.    初始化usb设备

5.1.2.    usb中断服务程序

5.1.3.    配置usb描述符

5.1.4.    USB DMA中断处理程序

5.1.5.    USB DMA写端点函数

5.1.6.    USB DMA读端点函数

5.2.    usbsetup.c文件

5.2.1.    ep0中断处理函数

5.2.2.    初始化描述符表

5.3.    usbin.c文件

5.3.1.    ep1中断处理函数

5.4.    usbout.c文件

5.4.1.    ep2中断处理函数


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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup包
0x220EP0x1对应IN包
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。
0x320CTRL_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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x320CTRL_STAT_CMP/EP0x1对应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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x220EP0x1对应IN
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。
0x320CTRL_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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x220EP0x1对应IN
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。
0x320CTRL_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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x220EP0x1对应IN
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。
0x320CTRL_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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x220EP0x1对应IN
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。
0x320CTRL_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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x220EP0x1对应IN
0x220EP0x2数据已经发送到HOST端,缓存可用
0x220EP0x20HOST端发送一空包,表示过程结束。

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中断的解释
0x260setup中断/EP中断(*)0x1缓存中有setup
0x320CTRL_STAT_CMP/EP0x1对应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端发来的数据

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分享一个很好的毕业设计——USB照相机,传感器用的是MT9M001C12STM芯片(MT9M001C12STM数据手册),USB微控制器用的是CY7C68013A芯片(CY7C68013A-56PVXC数据手册)。 CY7C68013A概述: CY7C68013A是个带8051的高速USB控制器,优点是开发方便(Cypress提供了开发包)、开发成本低(直接通过USB下载程序)、便宜(中发零售价¥20)、保密性差(程序不能存在单片机里,只能每次上电后从PC下载或者存24Cxx里,要保密的话就要额外想一点损招,我给的电路原理图中在I2C总线上挂了个AVR就是打算干这个用的) USB照相机设计流程如下: 从零开始学68013的开发(当然零包含会8051,否则就先去学一下51……),Cypress官方网站下一个叫做Cy3684的开发包,也可以下Cy4604,这两个大同小异,如果上位机要用C#的话就下SuiteUSB.Net2.0,下载完后把该安的安上,包括Keil C(Cy3684)里有一个限制版的Keil C,足够用了。 读开发包里的文档,明确每种传输都能干什么,适合干什么,根据自己的需求决定要用的传输方式; 写固件,Cypress有个固件框架,在里面填上自己的程序就能用,怎么写有个叫trm的文档里也写得挺清楚的; 用USB Console调固件,由于Cypress提供了个效率还不错的驱动CyUSB,所以一般应用不用自己写驱动,直接用那个就行; 写上位机程序,用CyAPI这个API就行……如果要传得比较快的话可以参考我的上位机程序; 调完上位机程序,把最终的固件下载到EEPROM里; 附件内容包括:USB照相机电路原理图,固件的工程,上位机程序,还有release里是需要准备的东西。 希望对大家有帮助~总得来说还是那句话,68013是个不错的东西,个人觉得比PSoC系列要成功多了。 USB照相机电路:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值