AT32 USB主机协议库
这部分主要介绍AT32 USB主机库的结构和库的使用方法,AT32 USB支持全速和低速,不支持USB2.0高速设备。这里库的作用是用来管理USB外设和实现USB的基本协议,使开发者能够更快的上手开发。
USB主机库包含以下几个模块 如图1:
此部分为开发者根据应用具体需求开发应用程序。
USB Core Driver:此部分实现USB设备标准协议栈,标准请求等接口。
USB主机类:此部分实现具体USB主机请求。
此部分实现硬件寄存器抽象接口
图1. USB主机库结构
AT32 USB库文件
如下是AT32 USB应用工程结构图:
图2. AT32工程结构
Core Driver库路径:OTGFS-->middlewares\usb_drivers
Host Class库路径:middlewares\usbh_class
如下是USB主机库文件列表:
表1. USB主机库文件列表
表2. USB主机类文件列表
USB主机库文件说明
USB库实现USB主机枚举标准请求,同时实现USB规格里面的4种传输类型(control,interrupt,bulk,isochronous)的函数接口。
图3 USB主机库文件结构
USB主机文件函数接口
usbh_int.c函数接口
usbh_int.c主要处理底层中断,包括设备连接,设备断开等。
表3 usbh_int函数接口
usbh_core.c函数接口
usbh_core.c此文件封装不同的usb主机函数接口用于不同的地方调用,包括一些接收,发送函数等。
表4 usbh_core函数接口
usbh_ctrl.c函数接口
usbh_ctrl.c此文件处理USB主机枚举过程中的一些标准请求。
表5 usbh_ctrl函数接口
支持的标准设备请求如下表:
表6 标准设备请求
usbh_xx_class.c函数接口
usbh_xx_class.c此文件为具体主机类型的数据处理,通过结构体函数来实现不同主机类型数据的处理。开发者根据不同的主机类型,来实现下面函数结构体中的函数,达到不同应用结果。
函数结构体如下:
表7 主机class函数结构体
表8 主机class函数接口
usbh_user.c函数接口
usbh_user.c此文件主要为一些给用户处理事件的函数如复位,断开连接等。
表9 用户事件函数结构体
表10 用户函数接口函数
其它参数函数
的参数结构体如下,USB主机库中参数传递使用结构体usbh_core_type,如下图:
图4 全局结构体
USB主机的状态机如下图:
图5 USB主机状态机
USB返回值,USB函数接口使用如下函数返回值。
图6 函数返回值
通道FIFO分配
USB主机要正常收发数据,在初始化时需要为通道分配FIFO,分配给所有通道FIFO大小的和不能超过系统分配给USB缓冲区的最大长度,具体USB的缓冲区大小参考RM上的描述。
开发者可以参考例程usb_conf.h为通道自定义分配FIFO。
OTGFS主机通道FIFO分配
主机模式下,所有通道共享一个接收FIFO,通道发送FIFO分为非周期性发送FIFO和周期性发送FIFO。注意usb_conf.h中对端点分配的FIFO大小单位为word(Byte)。
以hid_demo例程为例:
USB主机初始化
在使用USB主机功能时,需要对USB的寄存器做一些基本的初始化,通过调用USB主机的初始化函数完成这部分的操作。
OTGFS外设初始化
OTGFS初始化函数usbd_init包含5个参数:
例程主机hid_demo的初始化如下:
USB主机中断处理
USB主机中断入口函数usbh_irq_handler处理所有USB主机中断,包括连接状态,通道收发数据,SOF,唤醒等中断,下面介绍一些典型的中断处理。
图7 USB主机中断处理函数
通道中断处理
当USB主机与设备进行通信时,通道的收发状态都在通道中断中处理,通道的方向分为IN和OUT通过通道寄存器中的方向为进行判断。
中断处理函数:usbh_hch_handler
代码如下:
Wakeup 中断处理
当USB主机在挂起状态时,检测到设备触发的远程唤醒信号,将产生此中断。此中断会将当前主机状态改为WAKEUP状态:
中断处理函数:usbh_wakeup_handler
代码如下:
接收FIFO非空中断
此中断表示当前接收FIFO有数据,应用程序通过此中断读出接收到的数据,并存放到对应通道的FIFO当中,当数据读取完成之后,会产生对应的通道的中断。
中断处理函数:usbh_rx_qlvl_handler
代码如下:
主机端口中断处理
当USB主机断开发生状态改变时,会产生端口中断,应用程序通过此中断判断连接设备的速度等。
中断处理函数:usbh_port_handler
设备断开连接中断处理
当连接的设备断开是,会产生断开连接中断。
中断处理函数:usbh_disconnect_handler
代码:
USB主机枚举处理
USB主机状态机在usbh_loop_handler函数中处理,对应的主机状态机uhost->global_state,如下图是设备连接到主机的状态处理流程:
图8 设备连接状态机流程
USBH_IDLE:当USB启动或者设备断开连接之后在此状态
USBH_PORT_EN:USB主机端口使能之后在此状态
USBH_ATTACHED:USB设备连接稳定之后
USBH_ENUMERATION:USB设备标准的枚举流程
USBH_USER_HANDLER:枚举完成之后,调用主机类的初始化函数
USBH_CLASS_REQUEST:主机类初始化完成之后,进行主机类请求
USBH_CLASS:所有枚举完成,进行正常的数据处理。
USB主机枚举流程
当设备接到主机之后,通过控制端点(端点0)进行枚举动作,USB主机的枚举状态如下:
如下是主机枚举的状态机流程:
图9 USB主机枚举流程
ENUM_GET_MIN_DESC:获取8字节设备描述
ENUM_GET_FULL_DESC:获取18字节设备描述
ENUM_SET_ADDR:设置设备地址
ENUM_GET_CFG:获取9字节配置描述
ENUM_GET_FULL_CFG:获取完整的配置描述
ENUM_GET_MFC_STRING:获取设备厂商信息
ENUM_GET_PRODUCT_STRING:获取设备产品信息
ENUM_GET_SERIALNUM_STRING:获取设备序列号信息
ENUM_SET_CONFIG:SET CONFIGUREENUM_COMPLETE:枚举完成
USB控制传输过程包含SETUP-DATA-STATUS三个阶段,如下是一个主机获取设备信息的传输过程GET_DESCRIPTOR:
图10 Get Descriptor
如下是USB主机库一个SETUP-DATA-STATUS函数调用流程:
图11 USB主机SETUP函数调用
usbh_ctrl_transfer_loop函数中断对控制请求的各个状态阶段进行处理:
控制请求状态机:
图12 控制请求处理流程
USB主机类初始化
在USB标准枚举完成之后,会调用USB主机类的初始化,在初始化函数中解析当前枚举的设备是否支持,调用函数uhost->class_handler->init_handler(uhost)。
初始化代码例:
USB主机类请求
USB主机类初始化之后,可以发送主机类控制请求,根据不同的设备类,需要实现不同的设备类请求。调用函数uhost->class_handler->request_handler((void*)uhost);
主机类请求例:
USB主机数据处理
所有枚举完成之后,将进行主机数据处理
主机数据处理例:
USB主机类型例程
本章将说明使用AT32 USB主机库实现不同的主机类型的例程。目前实现的主机类例程如下:
HID例程
HID类支持鼠标和键盘设备,开发者可修改此例程用以实现支持其它HID类设备。
HID类:
HID类例程初始化
当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler, 调用此函数将解析接到主机上的设备类型,是鼠标还是键盘或者其它设备。通
过设备的配置描述信息进行如下流程解析:
查找HID接口
判断接口是鼠标还是键盘
查找对应接口的端点号
初始化对应通道
代码如下:
HID类请求
HID类请求实现一些HID设备的标准请求,调用函数uhost_request_handler
SET_IDLE
SET_PROTOCOL
GET_REPORT
代码如下:
HID类数据处理
HID枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。
通过usbh_interrupt_recv函数给设备发送IN请求
通过usbh_get_urb_status(puhost, phid->chin); 获取IN请求的状态
通过phid->in_poll判断多长时间发送一次IN请求
通过phid->protocol判断是鼠标还是键盘
代码如下:
MSC例程
msc_only_fat32实现一个简单的mass storage主机类,仅支持FAT32格式。
MSC类:
MSC 类初始化当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler,调用此函数将解析接到主机上的设备类型,判断是否是MSC类型。
通过设备的配置描述信息进行如下流程解析:
查找MSC接口
查找对应接口的端点号
初始化对应通道
初始化bulk-only和SCSI状态机
代码如下:
MSC类请求
MSC类请求实现一些MSC设备的标准请求,调用函数uhost_request_handler
代码如下:
MSC类数据处理
HID枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。
实现如下命令:
INQUIRY
TEST_UNIT_READY
READ_CAPACITY10
REQUEST_SENSE
代码如下:
MSC读写数据
MSC读写数据在通过FATFS接口进行实现,在usbh_msc_diskio.c中实现读写函数。
读函数:
写函数:
CDC例程
cdc实现一个简单的虚拟串口类。
CDC类:
CDC类例程初始化
当USB设备标准枚举完成之后,会进行初始化,调用uhost_init_handler, 调用此函数将解析接到主机上的设备类型。
通过设备的配置描述信息进行如下流程解析:
查找CDC接口
判断接口是否为虚拟串口
查找对应接口的端点号
初始化对应通道
代码如下:
CDC类请求
CDC类请求实现一些CDC设备的标准请求,调用函数uhost_request_handler
代码如下:
CDC类数据处理
CDC枚举设置完成之后,USB主机可以请求设备数据,通过调用uhost_process_handler来处理。
通过set_linecoding和get_linecoding配置linecoding
通过cdc_process_reception(puhost)函数给设备发送IN请求
通过cdc_process_transmission(puhost)函数发送数据给设备
代码如下:
two_otg_host_demo例程
AT32F435/437存在两个OTGFS,此例程说明同时使用两个OTGFS实现两个host功能。
实现功能:
OTGFS1实现MSC主机(参考MSC例程)
OTGFS2实现HID主机(参考HID例程)
配置与实现
在usb_conf.h中配置OTGFS1和OTGFS2:
在main中初始化:
来源:AT32 MCU 雅特力科技
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。