大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是i.MXRT1010, 1170型號上不一樣的SNVS GPR暫存器讀寫控制設計。
痞子衡之前兩篇文章 《在SBL專案實戰中妙用i.MXRT1xxx裡SystemReset不復位的GPR暫存器》、《對比i.MXRT與LPC在RTC外設GPREG暫存器使用上的異同》 介紹了 i.MXRT/LPC 上 System Reset 後不復位的 GPR 暫存器用法,但是有客戶發現在 i.MXRT1010 和 i.MXRT1170 上沒法直接使用文中示例讀寫程式碼,後來痞子衡檢查了一番,發現 SNVS GPR 暫存器在這兩款型號上確實不太一樣,今天痞子衡就來講講它們到底有啥不一樣:
一、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
}
}
二、i.MXRT1010上的精簡設計
我們知道 i.MXRT1010 是目前最入門級的 i.MXRT 型號,整個晶片設計相比主流型 i.MXRT1050 做了不少精簡,在 SNVS GPR 上也是,GPR2 - GPR0 直接被拿掉了(讀取永遠是0,不可寫入),僅剩 GPR3,好在這個 GPR3 上沒有系統控制功能,可供使用者自由讀寫,但也僅低 16bit 有效,高 16bit 是隻讀的。
CCM 模組裡預設也打開了 iomuxc_snvs_gpr 模組時鐘,可在使用者程式碼裡可以直接讀寫 GPR3[15:0]:
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
}
三、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 模組:
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
}
}
最後再補充兩點:
- 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暫存器讀寫控制設計痞子衡便介紹完畢了,掌聲在哪裡~~~
歡迎訂閱
文章會同時釋出到我的 部落格園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。