iMX RT FlexSPI 时序及驱动程序参数设置解析 (二)

接上一篇

iMX RT FlexSPI 时序及驱动程序参数设置解析 (一)

本次介绍FlexSpi程序设置中的问题。

FlexSPI外接设备描述

官方的FlexSPI驱动程序中对外接设备定义了一个结构体:flexspi_device_config_t,注意这个结构体和SPI flash启动时设置FDCB的结构体不同,官方搞了两套代码。

/*! @brief External device configuration items. */
typedef struct _flexspi_device_config
{
    uint32_t flexspiRootClk;                         /*!< FLEXSPI serial root clock. */
    bool isSck2Enabled;                              /*!< FLEXSPI use SCK2. */
    uint32_t flashSize;                              /*!< Flash size in KByte. */
    flexspi_cs_interval_cycle_unit_t CSIntervalUnit; /*!< CS interval unit, 1 or 256 cycle. */
    uint16_t CSInterval;                             /*!< CS line assert interval, mutiply CS interval unit to
                                                      get the CS line assert interval cycles. */
    uint8_t CSHoldTime;                              /*!< CS line hold time. */
    uint8_t CSSetupTime;                             /*!< CS line setup time. */
    uint8_t dataValidTime;                           /*!< Data valid time for external device. */
    uint8_t columnspace;                             /*!< Column space size. */
    bool enableWordAddress;                          /*!< If enable word address.*/
    uint8_t AWRSeqIndex;                             /*!< Sequence ID for AHB write command. */
    uint8_t AWRSeqNumber;                            /*!< Sequence number for AHB write command. */
    uint8_t ARDSeqIndex;                             /*!< Sequence ID for AHB read command. */
    uint8_t ARDSeqNumber;                            /*!< Sequence number for AHB read command. */
    flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit;  /*!< AHB write wait unit. */
    uint16_t AHBWriteWaitInterval;                   /*!< AHB write wait interval, mutiply AHB write interval
                                                      unit to get the AHB write wait cycles. */
    bool enableWriteMask;                            /*!< Enable/Disable FLEXSPI drive DQS pin as write mask
                                                      when writing to external device. */
} flexspi_device_config_t;

结构体中成员的作用含义

flexspiRootClk  就是基础时钟的频率,单位为Hz,这里只是供计算延迟使用,并不会影响RT芯片实际的FlexSPI基础时钟。

isSck2Enabled 使能SCK2输出,每个FlexSPI控制器提供了两个SCK端口;

flashSize      外设器件的空间大小,单位是KB,和片选信号有关,见FlexSPI的连接 和 地址空间分配 手册1655页

CSIntervalUnit  CS片选信号间隔单位,枚举类型,这个参数设置和手册描述不同

CSInterval         CS片选信号间隔时钟个数。

CSHoldTime    最后一个SCK时钟到CS上升沿 的 serial root clock 时钟个数。

CSSetupTime  CS下降沿到第一个SCK时钟的 serial root clock 时钟个数。

dataValidTime   DLL设置相关,单位是0.1ns, SCK边沿到数据边沿的时间,DLL延迟线一个单元延迟是75~225pS

columnspace 列地址宽度 bit

enableWordAddress  字寻址,4字节对齐

AWRSeqIndex  AHB 写方式 LUT表索引,用AHB方式读的时候FlexSPI自动调用的指令在LUT中的索引

AWRSeqNumber  AHB写执行的指令序列个数

ARDSeqIndex  AHB读指令索引

ARDSeqNumber   AHB读执行的指令个数

AHBWriteWaitUnit     AHB写入后等待的时间单位,枚举型   默认配置 AHB时钟频率为528MHz,2个周期约3.8ns

AHBWriteWaitInterval    AHB写入命令后等待的 周期  ( AHBWriteWaitInterval  * AHBWriteWaitUnit )    使用AHB命令时FlexSPI不会查询外部设备的状态,所以加上这个固定的延时保证外部设备的逻辑执行完成

enableWriteMask   设置FlexSPI写外部设备时,是否驱动DQS引脚作为写脉冲。

关于LUT的说明看 iMX TR1052芯片FlexSPI接口的使用 这一篇。 野火的iMX RT库开发指南中也有详细解读。

如果外接的是Flash或RAM芯片,需要按照芯片手册的时序和命令进行设置,如果外接的是FPGA器件,那命令都可以自定义。当然参考RAM的指令也是可以的。

设置结构体生效

设备的结构体配置完成后可以调用

FLEXSPI_SetFlashConfig(EXAMPLE_FLEXSPI, &deviceconfig, kFLEXSPI_PortA2);

函数将参数写入片内寄存器。最后一个参数  kFLEXSPI_PortA2  是表明这个设备接入到哪个FlexSPI端口,

当然前提是引脚都配置正确了

FlexSPI时钟设置

flexSPI有 serial root clock和SCK两个时钟,不要搞混,看上一篇 iMX RT FlexSPI 时序及驱动程序参数设置解析 (一) 。

SCK是与外部芯片通信连接用的时钟,serial root clock是RT芯片内的逻辑时钟。

借用野火例程里边的注释说明,时钟结构见上一篇文章。

  const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};

  /* 初始化USB1PLL,即PLL3,loopDivider=0,
      所以USB1PLL=PLL3 = 24*20 = 480MHz */
  CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
  /* 设置PLL3 PFD0频率为:PLL3*18/24 = 360MHZ. */
  CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);  
  /* 选择PLL3 PFD0作为flexspi时钟源
      00b derive clock from semc_clk_root_pre
      01b derive clock from pll3_sw_clk
      10b derive clock from PLL2 PFD2
      11b derive clock from PLL3 PFD0 */  
  CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); 
  /* 设置flexspiDiv分频因子,得到FLEXSPI_CLK_ROOT = PLL3 PFD0/(flexspiDiv+1) = 120M. */
  CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);  
  

FlexSPI设置

和外部设备描述一样,官方驱动程序也是提供了一个结构体,来描述FlexSPI的各种设置  :flexspi_config_t

/*! @brief FLEXSPI configuration structure. */
typedef struct _flexspi_config
{
    flexspi_read_sample_clock_t rxSampleClock; /*!< Sample Clock source selection for Flash Reading. */
    bool enableSckFreeRunning;                 /*!< Enable/disable SCK output free-running. */
    bool enableCombination;                    /*!< Enable/disable combining PORT A and B Data Pins
                                               (SIOA[3:0] and SIOB[3:0]) to support Flash Octal mode. */
    bool enableDoze;                           /*!< Enable/disable doze mode support. */
    bool enableHalfSpeedAccess;                /*!< Enable/disable divide by 2 of the clock for half
                                                speed commands. */
    bool enableSckBDiffOpt;                    /*!< Enable/disable SCKB pad use as SCKA differential clock
                                                output, when enable, Port B flash access is not available. */
    bool enableSameConfigForAll;               /*!< Enable/disable same configuration for all connected devices
                                                when enabled, same configuration in FLASHA1CRx is applied to all. */
    uint16_t seqTimeoutCycle;                  /*!< Timeout wait cycle for command sequence execution,
                                               timeout after ahbGrantTimeoutCyle*1024 serial root clock cycles. */
    uint8_t ipGrantTimeoutCycle;               /*!< Timeout wait cycle for IP command grant, timeout after
                                                ipGrantTimeoutCycle*1024 AHB clock cycles. */
    uint8_t txWatermark;                       /*!< FLEXSPI IP transmit watermark value. */
    uint8_t rxWatermark;                       /*!< FLEXSPI receive watermark value. */
    struct
    {
        bool enableAHBWriteIpTxFifo;  /*!< Enable AHB bus write access to IP TX FIFO. */
        bool enableAHBWriteIpRxFifo;  /*!< Enable AHB bus write access to IP RX FIFO. */
        uint8_t ahbGrantTimeoutCycle; /*!< Timeout wait cycle for AHB command grant,
                                       timeout after ahbGrantTimeoutCyle*1024 AHB clock cycles. */
        uint16_t ahbBusTimeoutCycle;  /*!< Timeout wait cycle for AHB read/write access,
                                      timeout after ahbBusTimeoutCycle*1024 AHB clock cycles. */
        uint8_t resumeWaitCycle;      /*!< Wait cycle for idle state before suspended command sequence
                                       resume, timeout after ahbBusTimeoutCycle AHB clock cycles. */
        flexspi_ahbBuffer_config_t buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer size. */
        bool enableClearAHBBufferOpt; /*!< Enable/disable automatically clean AHB RX Buffer and TX Buffer
                                       when FLEXSPI returns STOP mode ACK. */
        bool enableReadAddressOpt;    /*!< Enable/disable remove AHB read burst start address alignment limitation.
                                       when eanble, there is no AHB read burst start address alignment limitation. */
        bool enableAHBPrefetch;       /*!< Enable/disable AHB read prefetch feature, when enabled, FLEXSPI
                                       will fetch more data than current AHB burst. */
        bool enableAHBBufferable;     /*!< Enable/disable AHB bufferable write access support, when enabled,
                                       FLEXSPI return before waiting for command excution finished. */
        bool enableAHBCachable;       /*!< Enable AHB bus cachable read access support. */
    } ahbConfig;
} flexspi_config_t;

参考野火说明

rxSampleClock 

枚举类型,选择读时序的时候数据采样信号源常用的有三个,见上一篇中 27.5.14 FlexSPI输入时序;

enableSckFreeRunning

使能SCK时钟自由输出,不受CS时序控制;

enableCombination

绑定功能,使能后PortA的4Bit和PortB的4Bit绑定,形成8Bit并行输出模式;

enableDoze

使能 Doze 模式,使能了 doze 模式后,即使 RT1052 芯片处于低功耗 stop 运行状态时 FlexSPI 也能正常工作。

enableHalfSpeedAccess

配置是否使能对 SCK 时钟进行 2 分频以降低访问速率;

enableSckBDiffOpt
配置是否把 SCKB 用作 SCKA 的差分时钟,使用 2 线差分的形式可以提高抗干扰的能力,不过此时 PORT B 就不能再用于 FLASH 的时钟信号,也就是无法使用了;
 

enableSameConfigForAll
配置是否使能所有连接的设备都用同样的配置,如果使能的话, FLASHA1CRx 寄存器的配置会被应用到所有的设备。
seqTimeoutCycle
设置命令序列执行的等待超时周期, 设置结果为 seqTimeoutCycle*1024 个 FlexSPI 根时钟周期后超时,超时后可产生中断且会忽略 AHB 命令。 若本成员设置为 0 则不使用本功能;
ipGrantTimeoutCycle
配置 IP 命令授予等待超时周期, 即触发 IP 命令后,若命令仲裁器在 ipGrantTimeoutCycle*1024 个 AHB 时钟周期后还不允许执行该命令,则可触发中断。 注意本功能仅支持调试模式,使用时直接设置为默认值即可,且不能设置为 0!
txWatermark
配置 IP 发送的水印值,单位为字节。当IP_TX_FIFO 的空余的程度大于或等于该水印值时,可触发 IPTXWE 中断,同时也可触发 DMA 请求从而往 IP_TX_FIFO 填充要传输的数据。
rxWatermark
配置接收的水印值,单位为字节。 当IP_RX_FIFO 接收的数据超过该水印值时,可触发 IPRXWA 中断,同时也可触发DMA 请求把数据从 IP_RX_FIFO 转移出去。
ahbConfig    是一个和AHB总线配置相关的结构体

enableAHBWriteIpTxFifo
配置是否使能 AHB 总线通过映射地址(0x7F800000-0x11000400) 对 IP_TX_FIFO 的写访问。使能后,可通过 AHB 总线映射的地址向 IP_TX_FIFO 写入内容,此时通过 IP 总线写入 IP_TX_FIFO 的操作(即直接向寄存器进行写入操作) 会被忽略,但不会出现错误标志;若不使能,可通过 IP 总线写入 IP_TX_FIFO, 此时通过 AHB 总线的写入操作会被忽略,且会产生错误标志;

enableAHBWriteIpRxFifo
配置是否使能 AHB 总线通过映射地址(0x7FC00000 -0x10000200) 对 IP_RX_FIFO 的读访问。 与enableAHBWriteIpTxFifo 的类似,用于控制使用 AHB 还是 IP 进行读操作。
ahbGrantTimeoutCycle
与 ipGrantTimeoutCycle 成员类似,ahbGrantTimeoutCycle 用于配置 AHB 命令授予等待超时周期, 即触发 AHB 命令后,若命令仲裁器在在 ahbGrantTimeoutCyle*1024 个 AHB 时钟周期后还不允许执行该命令,会触发中断。 注意本功能同样仅支持调试模式,使用时直接设置为默认值即可,且不能设置为 0!
ahbBusTimeoutCycle
配置 AHB 读写访问超时周期, 在超过ahbBusTimeoutCycle*1024 个 AHB 时钟周期后, 仍没接收到数据或没发送出数据则表示访问超时,触发时可产生 AHBBUSTIMEOUT 中断。
resumeWaitCycle
配置在暂停命令序列恢复之前, 等待空闲状态的周期, 等待超过 resumeWaitCycle 个 AHB 时钟后超时。
buffer      是一个结构体  flexspi_ahbBuffer_config_t

typedef struct _flexspi_ahbBuffer_config
{
    uint8_t priority;    /*!< This priority for AHB Master Read which this AHB RX Buffer is assigned. */
    uint8_t masterIndex; /*!< AHB Master ID the AHB RX Buffer is assigned. */
    uint16_t bufferSize; /*!< AHB buffer size in byte. */
    bool enablePrefetch; /*!< AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master, allows
                          prefetch disable/enable seperately for each master. */
} flexspi_ahbBuffer_config_t;


配置 AHB 缓冲区的一些信息,它包含的配置参数分别为缓冲区的优先级、主索引号以及缓冲区的大小这些信息;

enableClearAHBBufferOpt
配置是否使能自动清除 AHB RX 和 TX 缓冲的功能,使能后, 当 FLEXSPI 退出停止模式时自动清除。
enableAHBPrefetch
配置是否使能 AHB 预读取特性,当使能时,FLEXSPI 会读取比当前 AHB 突发读取方式更多的数据,提高效率。
enableAHBBufferable
配置是否使能 AHB 缓冲写访问的功能,当使能时, FLEXSPI 会在命令执行完成前就返回,否则会等待至 AHB 总线准备好并把数据传输至外部设备且命令执行完成后才返回。
enableAHBCachable
配置是否使能 AHB 总线缓冲读访问的功能。

在应用初始化配置结构体时,通常先直接调用库函数FLEXSPI_GetDefaultConfig(); 赋予常用默认配置,然后再针对性地把初始化配置结构体修改成自己需要的内容
 

和FPGA连接的话其实需要关心的是时序和AHB访问方式,后面会着重看AHB相关的内容。关于AHB访问和IP访问,可以看看前面几篇内容。

使用IP Command方式访问Flash 手册1673页

FlexSPI使用AHB命令访问 手册1680页

FlexSPI应用于FPGA器件的一些要点 手册1719页

未完,下篇继续

猜你喜欢

转载自blog.csdn.net/catshit322/article/details/108422803
rt