痞子衡嵌入式:i.MXRT1010, 1170型號上不同的SNVS GPR寄存器讀寫控制設計


  你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們介紹的是i.MXRT1010, 1170型號上不同的SNVS GPR寄存器讀寫控制設計html

  痞子衡以前兩篇文章 《在SBL項目實戰中妙用i.MXRT1xxx裏SystemReset不復位的GPR寄存器》《對比i.MXRT與LPC在RTC外設GPREG寄存器使用上的異同》 介紹了 i.MXRT/LPC 上 System Reset 後不復位的 GPR 寄存器用法,可是有客戶(嗯,是野火電子,火哥但願我實名)發如今 i.MXRT1010 和 i.MXRT1170 上無法直接使用文中示例讀寫代碼,後來痞子衡檢查了一番,發現 SNVS GPR 寄存器在這兩款型號上確實不太同樣,今天痞子衡就來說講它們到底有啥不同:微信

1、SNVS GPR通常讀寫設計

  先來回顧一下 i.MXRT1015/1020/1024/1050/1060/1064 型號上的 SNVS GPR 設計,從參考手冊裏來看,SNVS GPR 一共有四個,其中 GPR2 - GPR0 是開放給用戶自由使用的,GPR3 裏面有一些系統控制功能,不建議使用。架構

  由於 CCM 模塊裏默認打開了 iomuxc_snvs_gpr 模塊的時鐘,因此在用戶代碼裏能夠直接讀寫 GPR2 - GPR0:測試

void snvs_gpr_rw_test(void)
{
    uint32_t flag = 0x5aa55aa5;
    // 測試 GPR0 - 2
    uint32_t *snvs_gpr;
    for (snvs_gpr = &IOMUXC_SNVS_GPR->GPR0; 
         snvs_gpr <= &IOMUXC_SNVS_GPR->GPR2;
         snvs_gpr++)
    {
        *snvs_gpr = flag;
        flag = *snvs_gpr;  // flag 爲 0x5aa55aa5
    }
}

2、i.MXRT1010上的精簡設計

  咱們知道 i.MXRT1010 是目前最入門級的 i.MXRT 型號,整個芯片設計相比主流型 i.MXRT1050 作了很多精簡,在 SNVS GPR 上也是,GPR2 - GPR0 直接被拿掉了(讀取永遠是0,不可寫入),僅剩 GPR3,好在這個 GPR3 上沒有系統控制功能,可供用戶自由讀寫,但也僅低 16bit 有效,高 16bit 是隻讀的。ui

  CCM 模塊裏默認也打開了 iomuxc_snvs_gpr 模塊時鐘,可在用戶代碼裏能夠直接讀寫 GPR3[15:0]:.net

void snvs_gpr_rw_test(void)
{
    uint32_t flag = 0x5aa5;
    // 測試 GPR3[15:0]
    IOMUXC_SNVS_GPR->GPR3 = (IOMUXC_SNVS_GPR->GPR3 & 0xFFFF0000u) | (uint16_t)flag;
    flag = IOMUXC_SNVS_GPR->GPR3 & 0x0000FFFFu;  // flag 爲 0x5aa5
}

3、i.MXRT1170上的加強設計

  i.MXRT1170 是目前最高端的 i.MXRT 型號,整個芯片設計相比主流型 i.MXRT1050 作了很大改動,在架構上有加強。具體到 SNVS GPR 上,咱們能夠看到增長了不少 GPR,其中 GPR31 - GPR0 是徹底可供用戶使用的(但須要在 Secure 狀態下才能被寫入,默認沒法寫入)。GPR32 默承認以直接寫入,但僅 bit15 - 1 可供用戶自由使用,高 16bit 作了低 16bit 的 lock 控制。而 GPR33 裏面則是一些系統控制功能,不建議使用。設計

  • Note: 在 i.MXRT1170 頭文件裏,你可能還會發現有 GPR37 - 34,因爲參考手冊裏並未開放,這裏不討論。

  CCM 模塊裏默認也打開了 iomuxc_snvs_gpr 模塊時鐘,可在用戶代碼裏能夠直接讀寫 GPR32[15:1],但要想寫入 GPR31 - 0,則須要先配置下 SNVS 模塊:code

void enable_snvs_gpr(void)
{
    // Write the proper value(4173_6166h) into LPLVDR
    SNVS->LPLVDR = 0x41736166u;
    // Clear the low-voltage event record
    SNVS->LPSR |= 0x8u;
}

void snvs_gpr_rw_test(void)
{
    uint32_t flag = 0x5aa5;

    // 測試 GPR32[15:1]
    IOMUXC_SNVS_GPR->GPR32 = (IOMUXC_SNVS_GPR->GPR32 & 0xFFFF0001u) | (uint16_t)(flag  << 1);
    flag = (IOMUXC_SNVS_GPR->GPR32 & 0x0000FFFEu) >> 1;  // flag 爲 0x5aa5

    flag = 0x5aa55aa5;
    // 測試 GPR0 - GPR31
    enable_snvs_gpr();
    volatile uint32_t *snvs_gpr;
    for (snvs_gpr = &IOMUXC_SNVS_GPR->GPR[0]; 
         snvs_gpr <= &IOMUXC_SNVS_GPR->GPR[31];
         snvs_gpr++)
    {
        *snvs_gpr = flag;
        flag = *snvs_gpr;  // flag 爲 0x5aa55aa5
    }
}

  最後再補充兩點:htm

  • Note 1: i.MXRT1160 和 i.MXRT1170 關於 SNVS GPR 設計是同樣的。
  • Note 2: i.MXRT1170 上執行了 enable_snvs_gpr() 後,SNVS_LPGPR[3] - SNVS_LPGPR[0] 才能被寫入。

  至此,i.MXRT1010, 1170型號上不同的SNVS GPR寄存器讀寫控制設計痞子衡便介紹完畢了,掌聲在哪裏~~~blog

歡迎訂閱

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

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

相關文章
相關標籤/搜索