痞子衡嵌入式:瞭解i.MXRTxxx系列ROM中靈活的串行NOR Flash啓動硬復位引腳選擇


  你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們介紹的是i.MXRTxxx系列ROM中靈活的串行NOR Flash啓動硬復位引腳選擇html

  關於 i.MXRT 系列 BootROM 中串行 NOR Flash 啓動流程,痞子衡寫過一篇很是詳細的文章 《深刻i.MXRT1050系列ROM中串行NOR Flash啓動初始化流程》,這篇文章主要針對 i.MXRT1xxx 四位數系列,但基本上也適用 i.MXRTxxx 三位數系列,僅一些細節處有區別。微信

  在串行 NOR Flash 熱啓動過程當中(非首次上電覆位,而是單純系統軟復位 NVIC_SystemReset),有不少場景下均須要先復位一下 Flash ,將其恢復到默認的 Normal 模式,而後 Flash 才能被 BootROM 正常啓動。這些場景包括 Flash 在上次系統運行時被配置到了某種特殊運行模式(QSPI 進入 Continuous Read 或者 QPI 模式,Octal Flash 進入 OPI 模式等),或者直接進到了低功耗模式(Deep Power Down)。測試

  本文就是介紹利用 BootROM 裏集成的 Flash 硬復位功能來完成 Flash 復位操做。閒話少敘,進入正文:flex

  • 備註1:本文主要針對已量產的 i.MXRT500/600 。
  • 備註2:本文僅適用那些包含獨立 RESET# 引腳的 Flash。

1、BootROM中實現

  在 《深刻i.MXRT1050系列ROM中串行NOR Flash啓動初始化流程》 一文的 2.1 節裏,咱們知道在 i.MXRT1xxx 四位數系列 BootROM 裏一樣集成了 Flash 硬復位功能,可是用於鏈接 Flash RESET# 引腳的 GPIO 是固定的(i.MXRT1050 上是GPIO1[9],i.MXRT1170 上是GPIO4[3] / GPIO2[8]),這對 PCB 設計有必定限制,若是被指定的 GPIO 在項目設計裏有不可替代的功能,那隻能放棄 BootROM 裏這個 Flash 復位功能了。ui

  鑑於 i.MXRT1xxx 裏 GPIO 指定不夠靈活的缺陷,恩智浦 ROM 小組在 i.MXRTxxx 系列裏作了改進,咱們來看 i.MXRT600 的 fusemap 表,其中 BOOT_CFG[1] 裏關於 QSPI_RESET_PIN 定義以下:.net

  咱們看到了 3bit GPIO_PORT (0-7) 和 5bit GPIO_PIN_NUM (0-31) 設置,有了這個設置,用於鏈接 Flash RESET# 引腳 的 GPIO 選擇就很是靈活了,基本能夠涵蓋全部 GPIO,所以項目 PCB 設計裏只要隨便找一個空閒的 GPIO 連到 Flash RESET# 引腳便可。設計

  該功能在 BootROM 裏實現代碼大概以下:code

const clock_ip_name_t k_GpioClocks[8] = { kCLOCK_HsGpio0, kCLOCK_HsGpio1, kCLOCK_HsGpio2, kCLOCK_HsGpio3,
                                          kCLOCK_HsGpio4, kCLOCK_HsGpio5, kCLOCK_HsGpio6, kCLOCK_HsGpio7 };

const RSTCTL_RSTn_t k_GpioResets[8] = { kHSGPIO0_RST_SHIFT_RSTn, kHSGPIO1_RST_SHIFT_RSTn, kHSGPIO2_RST_SHIFT_RSTn, kHSGPIO3_RST_SHIFT_RSTn, 
                                        kHSGPIO4_RST_SHIFT_RSTn, kHSGPIO5_RST_SHIFT_RSTn, kHSGPIO6_RST_SHIFT_RSTn, kHSGPIO7_RST_SHIFT_RSTn};

if (OCOTP->OTP_SHADOW[0x61] & 0x400)
{
    // Initialize Reset Pin
    uint32_t portInstance = (OCOTP->OTP_SHADOW[0x61] & 0x3800) >> 15;
    uint32_t gpioInstance = (OCOTP->OTP_SHADOW[0x61] & 0x7c000) >> 18;

    // Enable Clock before accessing registers
    CLOCK_EnableClock(k_GpioClocks[portInstance]);
    RESET_PeripheralReset(k_GpioResets[portInstance]);

    // Configure the port to GPIO mode with pull-up resistor enabled.
    IOPCTL->PIO[portInstance][gpioInstance] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_FULLDRIVE(1);
    GPIO->DIRSET[portInstance] = (1u << gpioInstance);

    // High
    GPIO->SET[portInstance] = (1u << gpioInstance);
    flexspi_sw_delay_us(250);
    // Low
    GPIO->CLR[portInstance] = (1u << gpioInstance);
    flexspi_sw_delay_us(250);
    // High
    GPIO->SET[portInstance] = (1u << gpioInstance);
    flexspi_sw_delay_us(500);
}

2、在MIMXRT685-EVK上實踐

  咱們如今在官方 MIMXRT685-EVK 上實測一下這個功能,EVK 上選用的 Flash 型號是旺宏的 MX25UM51345G,這顆 Flash 有獨立的 RESET# 引腳(A4),它被連到了主芯片的 PIO2_12 腳上。orm

  要想激活 BootROM 中 Flash 硬復位功能須要燒寫 eFuse(也能夠寫相應 OCOTP Shadow Register 來替代,Shadow Register 只在上電或者觸發 OCOTP refresh 命令時從 eFuse 中加載一次值,其後即便軟復位 Shadow Register 值也不丟失),咱們暫且用寫 Shadow Register 方式來測試。htm

  正好前段時間痞子衡在作 SBL 項目寫了篇文章 《在SBL項目實戰中妙用i.MXRT1xxx裏SystemReset不復位的GPR寄存器》,裏面就有系統軟復位需求,在支持 i.MXRT600 時就遇到了問題,由於第一次啓動後 MIMXRT685-EVK 上的這顆 Octal Flash 被配置到了 OPI 模式,須要復位後才能再次被 BootROM 正常啓動,因此咱們直接就用上了 BootROM 裏的 Flash 硬復位功能,代碼很簡單:

void isp_cleanup_enter(uint32_t flag)
{
    CLOCK_EnableClock(kCLOCK_Rtc);
    RTC->CTRL &= ~RTC_CTRL_SWRESET_MASK;
    RTC->GPREG[0] = flag;

    // Reset Flash to normal mode by BootROM
    // QSPI_RESET_PIN_ENABLE = 1'b1, GPIO_PORT = 3'b010, GPIO_PIN_NUM = 5'b01100
    OCOTP->OTP_SHADOW[0x61] = 0x314000;
    __DSB();

    NVIC_SystemReset();
}

  至此,i.MXRTxxx系列ROM中靈活的串行NOR Flash啓動硬復位引腳選擇痞子衡便介紹完畢了,掌聲在哪裏~~~

歡迎訂閱

文章會同時發佈到個人 博客園主頁CSDN主頁知乎主頁微信公衆號 平臺上。

微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就能夠在手機上第一時間看了哦。

相關文章
相關標籤/搜索