你们好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给你们介绍的是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 寄存器在这两款型号上确实不太同样,今天痞子衡就来说讲它们到底有啥不同:微信
先来回顾一下 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.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 }
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主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就能够在手机上第一时间看了哦。