深入解析OMAP5912 USB OTG控制器:双角色设备与低功耗设计

1. 项目概述与核心价值

在嵌入式系统,尤其是早期的移动计算和便携式设备领域,如何让一个设备既能作为U盘被电脑读取,又能作为读卡器去读取另一个U盘,是一个既基础又充满挑战的问题。这背后依赖的核心技术就是USB On-The-Go(OTG)。今天,我们就以TI经典的OMAP5912应用处理器为例,深入拆解其内置的USB OTG控制器,特别是它如何实现“双角色设备”(Dual-Role Device, DRD)的动态切换,以及如何通过精细的电源管理在资源受限的嵌入式环境中实现高效节能。

OMAP5912作为一款集成了ARM9和DSP的高性能处理器,其USB子系统设计颇具代表性。它并非简单地集成一个USB设备或主机控制器,而是通过一个独立的OTG控制器,桥接了设备控制器(UDC)和主机控制器(UHC),并附加了一套复杂的状态机和寄存器组来管理角色切换、会话发起与电源控制。对于从事嵌入式USB驱动开发、系统电源架构设计,或是单纯对底层硬件协议实现感兴趣的朋友来说,理解OMAP5912的OTG设计,就如同掌握了一把解开USB双向通信奥秘的钥匙。它不仅关乎功能实现,更直接影响到设备的功耗、响应速度和连接可靠性。

2. OMAP5912 USB OTG控制器架构解析

2.1 整体架构与角色定位

OMAP5912的USB OTG解决方案是一个“三合一”的复合体。它并非一个独立的、功能完整的物理层+链路层控制器,而是一个协调与仲裁中心。其核心由三部分组成:

  1. USB设备控制器(UDC):负责当OMAP5912作为外设(如大容量存储设备、串口调试设备)时的所有协议处理和数据传输。
  2. USB主机控制器(UHC,此处特指其中一个端口):负责当OMAP5912作为主机(如读取U盘、连接鼠标)时,对总线进行枚举、调度和管理。
  3. USB OTG控制器:这是本文的重点。它作为上述两个控制器的“大脑”和“开关”,包含控制逻辑、状态机和一系列配置寄存器。它的主要职责是:
    • 协议实现:根据USB OTG补充协议,实现会话请求协议(SRP)和主机协商协议(HNP)的硬件状态机。
    • 角色仲裁:根据ID引脚电平(连接器类型)和软件请求,决定当前是A设备(默认主机)还是B设备(默认外设),并动态切换UDC和UHC对USB物理端口的控制权。
    • 信号路由与复用:控制USB数据线(D+/D-)、VBUS电源线等信号的物理路径,在UDC、UHC和外部收发器(Transceiver)之间进行切换。
    • 电源与时钟管理:协同系统电源管理单元,对UDC、UHC和自身进行时钟门控和电源域控制,以降低功耗。

这种架构的优势在于复用和效率。OMAP5912可以在仅增加有限硅面积的情况下,通过OTG控制器的智能调度,让同一套物理引脚和部分底层硬件在不同的时间片服务于不同的角色,实现了极高的硬件利用率。

2.2 关键特性与限制

从技术手册中,我们可以提炼出OMAP5912 OTG控制器的几个关键特性和重要限制:

  • 协议兼容性:完全兼容USB 2.0规范及OTG补充协议1.0版。这意味着它支持标准的全速(12 Mbps)和低速(1.5 Mbps)通信。
  • 速度限制仅支持12 Mbps全速模式,不支持480 Mbps的高速(High-Speed)模式。这是OMAP5912时代的一个典型限制,对于当时的主流移动设备(如PDA、早期智能手机)来说,全速用于数据传输(如同步文件)和打印等应用已基本足够,但与大容量存储设备交换大量数据时会成为瓶颈。
  • 双角色设备(DRD)支持:这是核心价值。设备可以根据连接的电缆(Micro-AB插座上的ID引脚是否接地)决定初始角色(A-device或B-device),并能在会话中通过HNP交换角色。
  • 外设-only模式:可通过配置,让设备仅作为外设使用,即使连接了A设备(如PC)也无法发起主机功能,这为某些专用设备提供了灵活性。
  • 多端口扩展:在实现一个OTG端口的同时,OMAP5912的USB主机控制器还支持额外的两个主机端口。这意味着一个OMAP5912系统可以同时连接一个OTG设备(如另一部手机)和两个标准USB外设(如键盘和鼠标),扩展能力很强。

注意:硬件设计上的一个关键点:OMAP5912的OTG功能严重依赖外部USB OTG收发器芯片。这颗收发器负责物理层的电平转换、驱动能力控制,以及ID引脚、VBUS电压的检测。OTG控制器通过I2C等总线配置和控制这颗收发器。因此,在原理图设计和驱动开发中,收发器的选型(如Philips ISP1301)及其与OMAP5912的接口连接(是3线、4线还是6线模式)是首要确定的,这直接决定了OTG_SYSCON_1寄存器中USBx_TRX_MODE字段的配置。

3. 核心寄存器详解与软件驱动框架

驱动OMAP5912的USB OTG功能,本质上是正确配置和响应其OTG控制器寄存器。这些寄存器是软件与OTG硬件状态机交互的唯一窗口。下面我们跳出手册的罗列,以功能模块和驱动流程的视角重新组织这些关键寄存器。

3.1 系统配置与使能(OTG_SYSCON_1 & OTG_SYSCON_2)

这两个寄存器是OTG控制器的“总开关”和“模式选择器”。

OTG_SYSCON_1:基础配置与复位管理

  • USBx_TRX_MODE(x=0,1,2):这三个字段至关重要,用于配置连接到不同USB引脚组的收发器类型。OMAP5912支持多种收发器接口模式:
    • 0x00x3:6引脚DAT/SE0单向信号模式。这是最复杂的模式,需要独立的发送和接收数据线。
    • 0x1:4引脚VP/VM双向信号模式。这是一种差分信号模式。
    • 0x2:3引脚DAT/SE0双向信号模式。这是最常用、最节省引脚的模式,DAT线双向复用。
    • 配置依据:必须严格根据硬件原理图上收发器与OMAP5912的连接方式来设置。配错了会导致无法通信。
  • OTG_IDLE_EN,HST_IDLE_EN,DEV_IDLE_EN:这三个位分别控制OTG控制器、主机控制器、设备控制器的时钟门控。这是电源管理的核心。当相应功能空闲时(如设备处于挂起状态),软件可以置位这些位以关闭时钟,显著降低动态功耗。需要注意的是,DEV_IDLE_EN置位后,如果USB总线产生唤醒事件(Resume),UDC会产生一个中断,驱动必须在处理该中断前清除DEV_IDLE_EN以恢复时钟。
  • SOFT_RESETRESET_DONE:软件复位位和复位完成状态位。这是一个经典的操作序列:写1到SOFT_RESET发起复位,然后轮询或等待中断,直到RESET_DONE变为1,表示复位完成。务必在复位完成后再进行其他寄存器配置

OTG_SYSCON_2:OTG功能与高级控制

  • OTG_EN:OTG功能总使能位。0:OTG控制器电路不工作,UDC和UHC可作为独立模块使用。1:激活OTG控制器,启用HNP状态机等OTG专属功能。当不需要OTG功能时,清空此位并置位OTG_IDLE_EN可以省电。
  • SRP_GPDATA,SRP_GPDVBUS,SRP_GPUVBUS:这组寄存器精细控制B设备发起SRP时的信号行为。
    • SRP_GPDATA:控制D+脉冲的宽度(6ms或9ms)。更长的脉冲可能对某些A设备更易检测,但也更耗电。
    • SRP_GPDVBUS:是否在VBUS脉冲后执行放电。放电可以确保VBUS电压完全回落,为下一次SRP提供干净的起点。
    • SRP_GPUVBUS:控制VBUS充电脉冲的持续时间(从0.5ms到40ms)。这个值需要根据实际硬件调整:VBUS驱动电路的电流能力、线缆阻抗、对端设备的输入电容都会影响VBUS上升速度。目标是在连接OTG双角色设备时,脉冲期间VBUS能升至2V以上;而在连接标准USB主机时,应确保VBUS不会升至2V以上(以防误触发)。
  • A_WAIT_VRISE:A设备在开启VBUS后,等待其电压上升到有效阈值(VA_VBUS_VLD)的最大时间(200ms ~ 548ms)。如果超时,OTG控制器会进入A_VBUS_ERR状态并产生中断,通常意味着VBUS负载过重(如短路或设备电流需求太大)。
  • OTG_PADENHMC_PADEN:这两个位决定了控制信号的来源。
    • OTG_PADEN=0:OTG控制器寄存器(OTG_CTRL中的ID, VBUSVLD等)的值由软件读写,用于反映和控制器状态。这是启用OTG功能时的标准模式
    • OTG_PADEN=1:这些状态位被内部绑定或连接到特定GPIO(如VBUS检测)。这是仅使用USB设备功能(非OTG)时的简化模式
    • HMC_PADEN:类似,控制USB信号复用和主机控制器使能的配置源是来自OTG控制器还是系统级的配置模块。为了软件兼容性和灵活性,通常建议设置为0,即由OTG_SYSCON_2控制

3.2 状态与控制(OTG_CTRL)

这个寄存器是软件与OTG状态机实时交互的核心,分为状态反馈区和软件命令区。

状态反馈区(只读/软件反映)

  • ID,VBUSVLD,BSESSVLD,BSESSEND,ASESSVLD:这些位必须由软件根据外部收发器的实际状态实时更新。例如,当ID引脚被拉低(连接A-to-B线缆),软件应立即将ID位写为0。当VBUS电压比较器输出变化时,软件需更新VBUSVLD等位。这些值是OTG状态机进行决策(如判断会话开始/结束、角色切换)的直接输入。通常,这需要一个由GPIO中断触发的任务或Bottom Half来处理。
  • DRIVER_SEL:只读位,指示当前哪个驱动程序(主机驱动还是设备驱动)拥有总线控制权。在HNP成功切换后,此位会变化,并产生DRIVER_SWITCH中断,驱动需根据此位卸载一个驱动并加载另一个。

软件命令区(读写)

  • A_BUSREQB_BUSREQ:角色请求位。当A设备想放弃主机角色(如进入休眠)时,可清除A_BUSREQ;想重新获取时再置位。当B设备想请求成为主机时,置位B_BUSREQ,OTG控制器将自动发起SRP(若无会话)或HNP(若有会话)。
  • B_HNPENA_SETB_HNPEN:HNP使能位。在B设备端,当收到主机发来的SetFeature(B_HNP_ENABLE)标准USB请求后,设备驱动应置位B_HNPEN。在A设备端,软件在设置A_SETB_HNPEN为1后,才会响应B设备发来的HNP请求。
  • OTG_BUSDROP:A设备软件请求结束会话。
  • OTG_PU,OTG_PD,OTG_DRV_VBUS,OTG_PU_VBUS,OTG_PD_VBUS:这些是OTG控制器输出给外部收发器的控制命令,指示收发器应执行的操作(如上拉D+、驱动VBUS等)。当这些位变化时,会产生OPRT_CHG中断,驱动应在中断服务程序中通过I2C将相应的命令写入物理收发器芯片。

3.3 中断处理(OTG_IRQ_EN & OTG_IRQ_SRC)

可靠的中断处理是OTG驱动稳定性的关键。OMAP5912的OTG中断设计得比较清晰,每个重要状态转换都有对应中断。

关键中断及其处理逻辑

中断位触发条件软件处理动作
OPRT_CHGOTG_CTRL[5:0](输出控制位)发生改变。读取OTG_CTRL[5:0],通过I2C更新外部收发器的对应控制寄存器。处理完成后必须写1清除该中断位
DRIVER_SWITCHHNP完成,DRIVER_SEL改变;或OTG_EN从0写为1。根据DRIVER_SEL,执行驱动上下文切换:卸载当前不活动的控制器驱动,加载并初始化获得控制权的控制器驱动。
A_SRP_DETECTA设备检测到B设备发来的有效SRP(数据线或VBUS脉冲)。置位VBUSVLD(如果SRP是VBUS脉冲),然后置位A_BUSREQ以开启VBUS,开始会话。
B_SRP_DONEB设备发起的SRP流程完成。启动一个定时器,等待A设备开启VBUS(即等待BSESSVLD变1)。如果超时(B_SRP_TMROUT),则SRP失败。
B_HNP_FAILB设备发起的HNP失败(超时或A设备回应错误)。通知上层应用HNP请求失败,可能需要进行重试或提示用户。
A_VBUS_ERRA设备在A_WAIT_VRISE状态超时,VBUS未有效建立。进行错误处理:检查VBUS驱动电路、负载是否短路,并可能终止会话。
A_REQ_TMROUTA设备开启VBUS后,在a_wait_bcon状态超时未检测到设备连接。可能线缆未连接好或对端设备故障,可关闭VBUS并提示。

中断处理编程要点

  1. 初始化时,根据需求使能相关中断位(OTG_IRQ_EN)。
  2. 在中断服务程序(ISR)中,首先读取OTG_IRQ_SRC确定中断源。
  3. 按位处理,对于每个置位的中断源,执行相应的操作。
  4. 清除中断:通过向OTG_IRQ_SRC的对应位写1来清除中断标志。务必注意,对于OPRT_CHG中断,在清除之前,OTG_CTRL[5:0]的值会被“冻结”,保持中断发生时的状态,这确保了软件能读到正确的控制命令。清除后,这些位才会更新为最新值。

4. 双角色设备(DRD)工作流程与协议实现

理解了寄存器,我们来看OTG控制器如何运用它们来实现复杂的协议交互。整个过程就像一场精心编排的双人舞,OMAP5912既是舞者,也是部分的编舞。

4.1 初始连接与角色判定(ID引脚检测)

一切始于物理连接。OMAP5912通过外部OTG收发器检测ID引脚的电平:

  • ID = 0(接地):设备连接的是A插头(如标准USB-A公头转Micro-AB的线),OMAP5912被认定为A设备(默认主机)。软件需将OTG_CTRL.ID写为0。
  • ID = 1(悬空/上拉):设备连接的是B插头(如标准USB-B公头转Micro-AB),OMAP5912被认定为B设备(默认外设)。软件需将OTG_CTRL.ID写为1。

这个初始角色决定了会话初期的行为模式。

4.2 会话请求协议(SRP)流程

当B设备(无供电能力)希望发起一个会话时,它需要“唤醒”作为A设备的对方。这就是SRP。

B设备发起SRP(软件视角)

  1. 条件检查:B设备驱动检测到用户请求(如插入U盘)。检查OTG_CTRL.BSESSVLD为0(无有效会话),OTG_CTRL.ID为1(是B设备)。
  2. 启动SRP:软件置位OTG_CTRL.B_BUSREQ
  3. 硬件接管:OTG控制器硬件自动执行以下序列: a. 触发B_SRP_STARTED中断。 b. 根据OTG_SYSCON_2.SRP_GPDATA配置,控制收发器在D+线上产生一个脉冲。 c. 根据OTG_SYSCON_2.SRP_GPUVBUS配置,控制收发器对VBUS进行充电脉冲。 d. 如果SRP_GPDVBUS使能,则在充电脉冲后对VBUS进行放电。 e. 整个SRP序列完成后,触发B_SRP_DONE中断。
  4. 等待响应:软件在B_SRP_DONE中断后,开始监控OTG_CTRL.BSESSVLD位(需根据收发器中断更新)。如果VBUS在5.5秒内有效升起(BSESSVLD=1),则SRP成功,会话开始。如果超时,则触发B_SRP_TMROUT中断,SRP失败。

A设备响应SRP(软件视角)

  1. 中断响应:A设备OTG驱动收到A_SRP_DETECT中断。
  2. 状态更新:如果是VBUS脉冲SRP,软件需根据收发器状态更新OTG_CTRL.VBUSVLD(如果需要的话,对于数据脉冲SRP,此步可能省略)。
  3. 开启会话:软件置位OTG_CTRL.A_BUSREQ
  4. 硬件响应:OTG控制器置位OTG_CTRL.OTG_DRV_VBUS,触发OPRT_CHG中断。
  5. 驱动VBUS:软件在OPRT_CHG中断服务程序中,通过I2C命令外部收发器开始驱动VBUS。
  6. 等待连接:A设备进入a_wait_bcon状态,等待B设备连接(检测到D+上拉)。如果超时,触发A_REQ_TMROUT中断。

4.3 主机协商协议(HNP)流程

当会话已经建立(VBUS有效),B设备希望临时接管主机角色时,使用HNP。这要求A设备事先通过SetFeature(B_HNP_ENABLE)请求使能了B设备的HNP能力(此时B设备驱动已置位OTG_CTRL.B_HNPEN)。

B设备发起HNP

  1. 软件请求:B设备应用层请求主机功能。设备驱动置位OTG_CTRL.B_BUSREQ(此时已有会话,BSESSVLD=1)。
  2. 硬件协商:OTG控制器硬件自动执行HNP序列: a. B设备(当前是外设)停止所有USB活动,然后关闭其D+上拉电阻(通过OTG_CTRL.OTG_PU变0,触发OPRT_CHG,软件控制收发器实现)。 b. A设备检测到D+上拉消失,意识到B设备请求HNP。A设备随后关闭VBUS驱动(如果它正在驱动),并开启自己的D+上拉电阻,将自己转变为外设。 c. B设备检测到总线空闲和A设备的上拉,于是开启自己的VBUS驱动(如果需要)并作为主机开始枚举A设备。
  3. 角色切换完成:HNP成功后,OTG控制器改变DRIVER_SEL的值,并产生DRIVER_SWITCH中断。
  4. 驱动切换:两端设备的驱动根据DRIVER_SEL进行切换。在OMAP5912端,如果它从设备变成了主机,就需要卸载USB设备驱动,加载并启动USB主机驱动,反之亦然。

A设备响应HNP: A设备驱动在使能了B设备的HNP后(A_SETB_HNPEN=1),其主要工作就是监控状态。当它通过OPRT_CHG中断感知到OTG_DRV_VBUS需要关闭,以及OTG_PU需要开启时,控制收发器执行相应操作。随后,在DRIVER_SWITCH中断中,执行从主机驱动到设备驱动的切换。

5. 电源管理深度实践与低功耗设计

对于嵌入式设备,功耗就是生命线。OMAP5912的USB OTG子系统提供了多层级的电源管理机制。

5.1 时钟门控(Clock Gating)

这是最直接的动态功耗节省手段,通过OTG_SYSCON_1中的三个*_IDLE_EN位实现。

  • DEV_IDLE_EN:当USB设备控制器处于挂起(Suspend)状态超过3ms后,软件可以置位此位。硬件会自动关闭UDC的时钟,但寄存器访问仍可进行。关键点:当总线有唤醒(Resume)信号时,UDC会产生一个中断。驱动的中断服务程序必须首先清除DEV_IDLE_EN位,恢复时钟,然后才能去读取UDC的状态寄存器来处理唤醒事件。如果顺序颠倒,访问未时钟驱动的模块可能导致总线错误或死机。
  • HST_IDLE_EN:类似,当主机控制器空闲时,可置位以节省功耗。
  • OTG_IDLE_EN:当OTG功能未使用(OTG_EN=0)时,可以置位此位关闭OTG控制器时钟。

5.2 基于状态机的功耗优化

OTG状态机本身也定义了低功耗状态。例如,在a_idleb_idle状态(无会话),OTG控制器和相应的USB控制器(主机或设备)可以进入更深的低功耗模式。驱动需要配合状态机:

  1. 在进入空闲状态时,除了置位*_IDLE_EN,还可以考虑降低相关电源域电压(如果芯片支持)。
  2. 正确配置DS_WAKE_REQ_ON等唤醒信号,确保在需要时(如检测到SRP、VBUS插入)能可靠唤醒系统。

5.3 信号复用与收发器控制

OTG_SYSCON_1中的USBx_TRX_MODE配置也影响功耗。例如,选择3线模式通常比6线模式功耗更低,因为驱动的引脚更少。此外,在非活动状态,通过OTG_OUTCTRL寄存器(或间接通过OTG_CTRLOPRT_CHG中断)控制外部收发器关闭驱动器和终端电阻,可以进一步降低静态功耗。

5.4 深度睡眠(Deep Sleep)进入流程

参考手册中的流程图,进入深度睡眠的软件流程可以归纳为:

  1. 确保USB设备控制器处于挂起状态(DEVSTAT.SUS位为1)。
  2. 等待并处理GENI.DS_CHG中断(这是通用中断,指示可以进入深度睡眠的状态变化)。
  3. 在中断处理程序中,清除GENI.DS_CHG中断位。
  4. 此时,接口时钟可以被关闭,直到DS_WAKE_REQ_ON引脚被拉低(有唤醒事件)来重新开启时钟。

这个过程需要驱动、电源管理框架和系统调度器的紧密协作。

6. 常见问题排查与调试心得

在OMAP5912上开发OTG功能,我踩过不少坑,这里分享一些实战经验。

6.1 连接与通信失败排查表

现象可能原因排查步骤
插入线缆无任何反应1. 电源问题。
2. ID引脚检测错误。
3. OTG控制器未使能或时钟未开。
1. 测量VBUS电压和收发器供电。
2. 用示波器或逻辑分析仪抓取ID引脚电平,检查软件是否正确写入OTG_CTRL.ID
3. 检查OTG_SYSCON_2.OTG_EN是否为1,OTG_SYSCON_1.*_IDLE_EN是否误关闭了时钟。检查系统级时钟和复位配置。
SRP无法发起或总是超时1. SRP脉冲参数配置不当。
2. VBUS驱动能力不足。
3. 对端设备不支持SRP或响应慢。
1. 调整SRP_GPUVBUSSRP_GPDATA,增加脉冲宽度/时长。用示波器观察D+和VBUS波形是否符合协议。
2. 检查VBUS驱动电路(如PMIC或分立元件)的电流输出能力。在VBUS上并联一个适当容值的电容(如100uF)可能有助于电压建立。
3. 确认对端设备是OTG双角色设备,并支持SRP。
HNP切换失败1. HNP未使能。
2. 定时器超时。
3. 驱动切换不及时。
1. 确认A设备发送了SetFeature(B_HNP_ENABLE),且B设备驱动正确置位了OTG_CTRL.B_HNPEN,A设备置位了A_SETB_HNPEN
2. 检查总线状态,确保在HNP过程中没有意外的复位或暂停信号。用分析仪抓取USB总线数据包。
3. 优化DRIVER_SWITCH中断处理程序,确保主机和设备驱动的加载/卸载、控制器初始化/去初始化快速完成。
角色切换后通信异常1. 引脚复用配置错误。
2. 控制器复位不彻底。
3. DMA或缓冲区未重新配置。
1. 在DRIVER_SWITCH中断中,确认HMC_MODE等引脚复用配置已根据新角色正确切换。
2. 在切换驱动前,考虑对即将激活的控制器(UHC或UDC)执行一次软复位(SOFT_RESET),并等待RESET_DONE
3. 主机和设备驱动可能使用不同的DMA通道或缓冲区描述符,切换后需重新初始化这些资源。
OPRT_CHG中断频繁或丢失1. I2C通信缓慢或失败。
2. 中断清除顺序问题。
3. 收发器状态不稳定。
1. 确保I2C驱动稳定,在OPRT_CHGISR中读取OTG_CTRL[5:0]后,应尽快完成对收发器的I2C写操作。
2.必须在I2C操作成功完成后,再写1清除OTG_IRQ_SRC.OPRT_CHG位。过早清除可能导致丢失中间状态。
3. 检查收发器供电和参考电压是否稳定。

6.2 调试技巧与工具

  1. 寄存器诊断:编写一个简单的诊断程序,定期(或在关键中断中)打印所有OTG相关寄存器的值。对比手册中的状态机图,可以清晰看出卡在哪个状态。
  2. 信号测量
    • VBUS:使用万用表或示波器观察SRP、HNP过程中的电压变化,确保能上升到4V以上(有效会话),并能正确跌落到0.8V以下(会话结束)。
    • D+/D-:使用示波器观察数据线脉冲。SRP的D+脉冲、HNP前后的上拉电阻变化,都是关键信号。
    • ID:确认电平正确。
  3. 协议分析仪:如果条件允许,使用USB协议分析仪(如Ellisys, Beagle)是终极武器。它可以捕获并解码所有USB数据包,清晰展示枚举、描述符获取、HNP请求(SetFeature)等过程,对于解决复杂的协议交互问题无可替代。
  4. 软件日志:在驱动的关键路径(初始化、SRP开始/结束、HNP开始/结束、角色切换、中断入口)添加详细的日志。通过日志的时间戳,可以分析状态转换的时序是否符合协议要求。

6.3 一个典型的初始化序列

最后,分享一个我认为比较稳健的OTG控制器初始化序列(假设硬件已上电,收发器已初始化):

  1. 全局使能与复位:确保系统给USB和OTG控制器的时钟和电源已开启。
  2. 软复位:写OTG_SYSCON_1.SOFT_RESET = 1。轮询OTG_SYSCON_1.RESET_DONE直到为1。同时,也需要按照主机和设备控制器各自的文档对它们进行复位。
  3. 配置收发器模式:根据硬件连接,设置OTG_SYSCON_1.USBx_TRX_MODE
  4. 配置OTG参数:设置OTG_SYSCON_2中的SRP相关参数(SRP_GPDATA,SRP_GPUVBUS等)、A_WAIT_VRISE等。
  5. 使能OTG功能:写OTG_SYSCON_2.OTG_EN = 1。此时可能会立即产生一个DRIVER_SWITCH中断。
  6. 初始化中断:配置OTG_IRQ_EN,使能所需的中断(如OPRT_CHG_EN,DRIVER_SWITCH_EN,A_SRP_DETECT_EN,B_SRP_DONE_EN等)。将OTG控制器的中断线连接到系统中断控制器并注册ISR。
  7. 初始状态同步:读取外部收发器状态(通过I2C或GPIO),将ID,VBUSVLD等初始值写入OTG_CTRL对应位。
  8. 启动状态机:根据初始的IDVBUSVLD状态,软件可以决定下一步动作。例如,如果初始为A设备且VBUSVLD=0,则可以等待SRP或用户操作;如果为B设备且VBUSVLD=0,则等待用户请求来发起SRP。

OMAP5912的USB OTG控制器是一个功能完整但略显复杂的模块,它完美体现了在嵌入式系统中实现高度集成和灵活性的设计思路。吃透它的寄存器设计和状态机流程,不仅能让你搞定OMAP5912的USB开发,其设计理念对理解其他芯片的OTG实现乃至更复杂的USB Type-C PD协议都有极大的借鉴意义。