IOMUXC指IO多路复用控制器,IOMUXC和IOMUX使IMX51能够多个功能块共用一个BGA触点,共用触点是通过对BGA触点输入/输出信号的多路复用技术来实现的。对于每个BGA触点最多的有多达8个多路复用选项(成为ALT(alternate,理解为可变)模式)。因为不同的模块需要不同的BGA触点设置(比如pullup,keeper等等),所以IOMUXC也能控制BGA触点参数设置。
IOMUX只由几个基本IOMUX单元的组合逻辑组成,每个基本的IOMUX单元只处理一个BGA触点信号的复用
图1
因为IMX51集成了很多的功能模块,比如WDOG、I2C等等,但它的BGA封装容纳不了那么多引脚,所以就想到用IOMUXC的方式来解决此问题,也即一个功能模块的引脚,通过n选1的多路开关,把需要的外设连接到该引脚上,我的理解如下:
图2
具体的配置通过IOMUXC_SW_MUX_CTL_PAD_(BGAcontact NAME,比如UART3_RXD)寄存器来实现,然后通过配套的寄存器IOMUXC_SW_PAD_CTL_PAD_(PAD NAME, 比如UART3_RXD)来配置管脚的驱动电压,回转率,驱动强度,开漏,上拉, DDR 类型等等。下面根据IMX51评估板中OAL对UART3_RXD引脚的配置为例说明,先看原理图:
图3
评估板此引脚是用来判断主板的版本,其目的应该是通过把UART3_RXD作为普通的GPIO引脚,然后通过此引脚的电平不同来判断不同的版本(比如前一个版本没有R6001这个电阻,现在的版本通过R6001电阻接地来区分)
IOMUXC寄存器在代码中用PCSP_IOMUX_TO2_REGS结构体来描述,其定义如下:
typedefstruct
{
UINT32 GPR0; // 0x0000
UINT32 GPR1; // 0x0004
UINT32 OBSERVE[5]; // 0x0008~0x0018
UINT32 SW_MUX_CTL[245]; // 0x001C~0x03EC
UINT32 SW_PAD_CTL[309]; // 0x03F0~0x08C0
UINT32 SELECT_INPUT[89]; // 0x08C4~0x0A24
}CSP_IOMUX_TO2_REGS, *PCSP_IOMUX_TO2_REGS;
下面来说明这些寄存器的使用。
1. GPR0
GPR0指GeneralPurpose Registers 0,此寄存器的说明如下:
图4
EMI指(ExternalMemory Interface,外部存储器接口),包括外部DDR和FLASH接口,以及内部的RAM和ROM接口
对GPR0寄存器的操作主要是通过BOOLDDKIomuxSetGpr0(UINT32 data)和UINT32 DDKIomuxGetGpr0(VOID)函数来分写和读。
2. GPR1
GPR1指GeneralPurpose Registers 1,此寄存器的说明如下:
图5
此寄存器通用位用于SOC集成,对GPR1寄存器的操作主要是通过BOOLDDKIomuxSetGpr1(UINT32 data)和UINT32 DDKIomuxGetGpr1(VOID)函数来分写和读。
3. OBSERVE
这是一组寄存器组,有5个32位的寄存器OBSERVE[4:0],主要是为观察性的(Observability )IOMUXC_OBSERVE_MUX_0~4选择实体引脚(instance pin)
4. SW_MUX_CTL
IOMUXC_SW_MUX_CTL_PAD_(BGAcontact NAME)的寄存器有244个,从0x73FA801C到0x73FA83EC,我们以图3中UART3_RXD引脚来说明,OEMPlatformInit函数中的相关代码如下:
图6
OAL_IOMUX_SET_MUX函数的说明如下:
第1个参数:g_pIOMUX就是指向CSP_IOMUX_TO2_REGS结构体的全局变量。
第2个参数:DDK_IOMUX_PIN_UART3_RXD=137,表示245个寄存器的第137个(从第0个开始),这样就可以计算出UART3_RXD这个触点对应的IOMUXC_SW_MUX_CTL_PAD_UART3_RXD寄存器,137*4+0x73FA801C=0x73FA8240,就是此寄存器的地址。
第3个参数:DDK_IOMUX_PIN_MUXMODE_ALT3,用于设置UART3_RXD这个触点为GPIO1_22,对应此寄存器的MUX_MODE位。
图7
第4个参数:DDK_IOMUX_PIN_SION_REGULAR把寄存器的SION位设置为输入路径(inputpath)由选择的mux mode决定(regular)。
5. SW_PAD_CTL
这些寄存器主要是在SW_MUX_CTL寄存器选择了MUX_MODE和SION之后,对选定的引脚进行驱动电压,回转率,驱动强度,开漏,上拉, DDR 类型等设置,图6中的OAL_IOMUX_SET_PAD函数说明如下:
第1个参数:g_pIOMUX就是指向CSP_IOMUX_TO2_REGS结构体的全局变量。
第2个参数:DDK_IOMUX_PAD_UART3_RXD,表示309个IOMUXC_SW_PAD_CTL_PAD_PADNAME寄存器的第144个,也就是IOMUXC_SW_PAD_CTL_PAD_UART3_RXD寄存器。
第3个参数:DDK_IOMUX_PAD_SLEW_FAST,对应[0]位,选择此BGA触点输出值为快速转换速率。
第4个参数:DDK_IOMUX_PAD_DRIVE_HIGH,对应[2:1]位,选择为high驱动强度。
第5个参数:DDK_IOMUX_PAD_OPENDRAIN_DISABLE,表示禁用漏极开路,其实UART3_RXD这个BGA触点没有此功能,这几位是预留的,见图8。
第6个参数:DDK_IOMUX_PAD_PULL_NONE,对应[7]位,表示禁用pullup/pull down/keeper。
第7个参数:DDK_IOMUX_PAD_HYSTERESIS_ENABLE,对应[8]位,表示使能hysteresis。
第8个参数:DDK_IOMUX_PAD_INMODE_CMOS,表示选择CMOS还是DDR输入,但UART3_RXD没有这个属性设置。
第9个参数:DDK_IOMUX_PAD_OUTVOLT_LOWVOLT,表示低电压还是高电压输出模式,但UART3_RXD没有这个属性设置。
图8
6. SELECT_INPUT
在一些情况下,多个BGA触点可能驱动单个模块输入引脚。这样的情况下需要增加多层IOMUX复用:此模块的所有输入信号被多路复用和一个专门的受SW控制的寄存器控制mux,为了选择所需要的输入路径(input path),下面以I2C2控制器来说明此寄存器
图9
由图9可知,I2C2模块的输入引脚ipp_scl_in由EIM_D27、KEY_COL4、USBH1_CLK和GIO1_2这4个Pad来驱动,可以理解为,这四个pad都可以作为I2C2_SCL引脚,这取决于硬件的设计,当然了,其实硬件也可以迁就软件来修改,只不过一般不这么处理。评估板择KEY_COL4这个PAD作为I2C2_SCL功能,故要设置IOMUXC_I2C2_IPP_SCL_IN_SELECT_INPUT[DAISY]=01,此寄存器如下图:
图10
当然在配置此寄存器DAISY位之前,需要设置IOMUXC_SW_MUX_CTL_PAD_KEY_COL4和寄存器IOMUXC_SW_PAD_CTL_PAD__KEY_COL4寄存器,相关的代码在bspi2c.c下,如下:
图11