【裸机开发】SPI 通信接口(二)—— SPI 寄存器解析(ECSCPI)

I.MX6ULL 中,SPI 对应的模块是ECSPI(Enhanced Configurable SPI)


目录

一、硬件原理图分析

二、IO 复用寄存器解析

三、ECSPI 寄存器解析

3.1 时钟配置

3.2 ECSPI3_RXDATA

3.3 ECSPI3_TXDATA

3.4 ECSPI3_CONREG(ECSPI使能、分频)

3.5 ECSPI3_CONFIGREG(配置寄存器)

3.6 ECSPI3_INTREG(中断使能寄存器)

3.7 ECSPI3_STATREG(状态寄存器)

3.8 ECSPI3_PERIODREG(选择时钟源、采样周期)


一、硬件原理图分析

SPI 至少涉及到四个引脚,在开发板底板原理图找到 ECSPI 相关的四个引脚,以及这四个引脚关联到核心板的哪些引脚。比如下面的 SS0 是片选信号线,关联到核心板的 UART2_TXD

  • SS0:片选信号 —— UART2_TXD 
  • SCLK:时钟线 —— UART2_RXD
  • MISO:主设备接收 —— UART2_RTS
  • MOSI:主设备发送 —— UART2_CTS

注意:IMX6ULL 有四个 SPI 主控制器 ECSPI1~ECSPI4,每个主控制器包含四个片选引脚 SS0~SS3

二、IO 复用寄存器解析

以 SS0 为例,关联的核心板引脚是 UART2_TXD,UART2_TXD可能有多种用途,我们要将其复用为 SS0 功能。(其他引脚也是同理)

  • 设置复用的寄存器:IOMUXC_SW_MUX_CTL_PAD_UART2_TX_DATA
  • 设置电气属性的寄存器:IOMUXC_SW_PAD_CTL_PAD_UART2_TX_DATA
    • 初始值:0x10B1

/*************** SS0 复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART2_TX_DATA (0x20E0094)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART2_TX_DATA (0x20E0320)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART2_TX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA |= 8;         // 复用为SS0
 
    IOMUXC_SW_PAD_CTL_PAD_UART2_TX_DATA = 0x10B1;
 
/*************** SCL 复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART2_RX_DATA (0x20E0098)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART2_RX_DATA (0x20E0324)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART2_RX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART2_RX_DATA |= 8;         // 复用为SCL
 
    IOMUXC_SW_PAD_CTL_PAD_UART2_RX_DATA = 0x10B1;

/*************** MISO 复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART2_RTS_B (0x20E00A0)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART2_RTS_B (0x20E032C)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART2_RTS_B &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART2_RTS_B |= 8;         // 复用为MISO
 
    IOMUXC_SW_PAD_CTL_PAD_UART2_RTS_B = 0x10B1;


/*************** MOSI 复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART2_CTS_B (0x20E009C)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART2_CTS_B (0x20E0328)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART2_CTS_B &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART2_CTS_B |= 8;         // 复用为MOSI 
 
    IOMUXC_SW_PAD_CTL_PAD_UART2_CTS_B = 0x10B1;

三、ECSPI 寄存器解析

3.1 时钟配置

我们需要配置 CSCDR2 寄存器的 ECSPI_CLK_SEL 位(bit 18),选择时钟源为 pll3_sw_clk 八分频以后的 60MHz。CSCDR2 的 ECSPI_CLK_PODF 设为 1 分频。

寄存器: CCM_CSCDR2
基地址: 0x20C4038
初始化操作:
    /*
     * bit 18: 0 选择时钟源为 60MHz
     * bit 24-19: 000000 设为1分频
     */
    CCM_CSCDR2 &= ~(1 << 18);
    CCM_CSCDR2 &= ~(0x3F << 19);

3.2 ECSPI3_RXDATA

SPI 是全双工通信,可以同时进行收发。ECSPIx_RXDATA 是用于保存接收数据的寄存器。本质就是从一个 RXFIFO队列的队首取出一个字(32bit)的数据,RXFIFO(类似于队列)的大小为 64 × 32。

下面这个示意图可以理解为 RXFIFO(接收队列),每次读一行。

注意:ECSPI_STATREG 的 RR 位一旦被清零,从 RXFIFIO 读取到的数据是无意义的。

寄存器: ECSPI3_RXDATA
基地址: 0x2010000

3.3 ECSPI3_TXDATA

SPI 是全双工通信,可以同时进行收发。ECSPIx_TXDATA 是用于保存发送内容的寄存器,本质是向 TXFIFO 队列的队尾插入一个字(32bit)的数据。只要队列未满,即便是在对方接收数据的时候,也可以写入数据。

下面这个示意图可以理解为 TXFIFO(发送队列),每次写一行。

注意:写入一个字,并不代表就会传输一个字的数据。 传输多少 bit 的数据是由ECSPIx_CONREG寄存器的 BURST_LENGTH 位决定的。

寄存器: ECSPI3_TXDATA
基地址: 0x2010004

3.4 ECSPI3_CONREG(ECSPI使能、分频)

bit 0: SPI 使能(0: 关闭        1: 使能)

bit 2: 用于控制什么时候可以开始突发式访问,简单说就是什么时候可以开始传输数据,仅在主机模式下适用(0: 空闲状态下        1: 开始写入或者读取的时候)

bit 3: 开始模式控制,仅在主机模式下适用。0 表示通过 XCH 位 (bit 2) 和 SS_CTL 位来控制开始传输的时间点;1 表示一旦有数据写入 TXFIFO 的时候就开始传输。

bit 7- 4: 每个主控制器有四个片选通道,这里我们使用的是 SS0,该位控制的是本次通信,MCU是作为主设备还是从设备,来和片选通道的设备进行通信的。一般需要搭配 bit 19 - 18 使用(0: 从设备        1: 主设备)

bit 11 - 8(PRE_DIVIDER): ECSPI 模块在内部还会进行两次分频。这里设置的是第二次分频的分频值(分频值为n)

bit 15 - 12(POST_DIVIDER): ECSPI 模块在内部还会进行两次分频。这里设置的是第一次分频的分频值(分频值为2^n)

bit 17 - 16: SPI_RDY 信号控制位。(0: 无视SPI_RDY信号        1: SPI_RDY 信号为边沿触发        2: SPI_DRY 为电平触发)

bit 19 - 18: 一个 ECSPI 控制器有四个片选通道,这里使用的是 SS0,该位控制的是要选择和哪个片选通道通信,还需通过 bit 7-4 来选择主从设备。

bit 31 - 20: 每次实际传输的数据长度。写入数据的长度 ≠ 实际传输的数据长度,如果你写入数据的长度 > 实际传输的长度,多余部分会留到下一次传输。

寄存器: ECSPI3_CONREG
基地址: 0x2010008

3.5 ECSPI3_CONFIGREG(配置寄存器)

bit 3 - 0: 相位选择。ECSPI 有四个通道,我们使用的是通道 0。需要保证主从设备的相位、极性一致(0: CPHA=0        1: CPHA=1)

bit 7 - 4: 极性选择。ECSPI 有四个通道,我们使用的是通道 0。需要保证主从设备的相位、极性一致(0: CPOL=0        1: CPOL=1)

bit 15 - 12: 某个通道的SPI 片选信号极性设置。(0: 该通道片选信号低电平有效        1: 该通道片选信号高电平有效)

bit 19 - 16: 数据控制。该字段控制的是数据处于非活跃状态时的各个通道的电平。一般设为 0(0: 高电平        1: 低电平)

bit 23 - 20: 时钟控制。该字段控制的是非活跃状态时的各个通道的电平.一般设为 0(0: 高电平        1: 低电平)

寄存器: ECSPI3_CONFIGREG
基地址: 0x201000C

3.6 ECSPI3_INTREG(中断使能寄存器)

bit 0: TXFIFO 为空时,中断触发使能(0: 关闭        1: 使能)

bit 1: TXFIFO 有数据进入,但是数据长度小于TX_THRESHOLD,中断触发使能(0: 关闭        1: 使能)

bit 2: TXFIFO 为满时,中断触发使能(0: 关闭        1: 使能)

bit 3: RXFIFO 有数据就绪时,中断触发使能(0: 关闭        1: 使能)

bit 4: RXFIFO 有数据进入,但是数据长度小于RX_THRESHOLD,中断触发使能(0: 关闭        1: 使能)

bit 5: RXFIFO 为满时,中断触发使能(0: 关闭        1: 使能)

bit 6: RXFIFO 溢出时,中断触发使能(0: 关闭        1: 使能)

bit 7: 数据传输完成时,中断触发使能(0: 关闭        1: 使能)

寄存器: ECSPI3_INTREG
基地址: 0x2010010

3.7 ECSPI3_STATREG(状态寄存器)

bit 0: TXFIFO是否为空(0: TXFIFO 不为空        1: TXFIFO 为空)

bit 1: TXFIFO中的数据量是否超过TX_THRESHOLD(0: 是        1: 否)

bit 2: TXFIFO 是否满了(0: TXFIFO 没满        1: TXFIFO 已满)

bit 3: RXFIFO 是否有数据就绪(0: 尚未有数据就绪        1: 已有数据就绪)

bit 5: RXFIFO 是否满了(0: RXFIFO 没满        1: RXFIFO 已满)

bit 6(RO): RXFIFO 数据溢出(0: 没有溢出        1: 已经溢出)

  • 数据溢出:当接收的数据量超过 RXFIFO 的大小,SPI为了保证数据不会被覆盖,会舍弃最新接收的数据,此时溢出标志位 RO 会被置1

bit 7: 数据是否传输完毕(0: 数据传输中        1: 数据传输完毕)

寄存器: ECSPI3_STATREG
基地址: 0x2010018

3.8 ECSPI3_PERIODREG(选择时钟源、采样周期)

选择时钟源指的是选择系统高频时钟还是其他低频时钟;采样周期指的是相邻两次连续读 / 写数据之间的之间间隔, 假设SPI 的时钟是 10MHz。

如果采样周期数是 0x2000,说明在上一次读 / 写完毕以后要等待 0x2000 个周期才开始下一次读 / 写。等待的时间 = (1 / 10000000) * 0x2000 = 0.0008192 s = 0.8192 ms,即连续读取数据的时间间隔为 0.8 ms

bit 21-16: 设置片选信号和第一个SPI时钟周期产生时的时间差。

bit 15: 选择时钟源。这里我们选择 SPI Clock,这里的SPI Clock 并不是系统时钟源,而是经过SPI内部分频以后得到的时钟源(0: SPI 时钟源        1: 低频时钟)

bit 14-0: 设置采样周期。相邻两次读 / 写之间的时间间隔。

寄存器: ECSPI3_PERIODREG
基地址: 0x201001C
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值