电子说
从参考手册中了解到,在软件运行时才能设置eFuse。如何设置BT_FUSE_SEL,使用Keil MDK烧写 eFuse进行批量生产呢?这样保持每次固定只从外部的 QSPI Flash引导,而不需要判断外部BOOT GPIO引脚电平,可以减少外部下拉电阻的设置,对于原理图设计会简化许多。根据手册,BT_FUSE_SEL位于熔丝地址 0x460的第四位。
当配置Boot_Mode在内部引导(b10)时,BT_FUSE_SEL的状态确定引导配置是否取自熔丝位或引脚状态。如果BT_FUSE_SEL=0,boot_cfg是从GPIO获取的。如果BT_FUSE_SEL=1,则从熔丝中获取引导配置cfg。
当配置Boot_Mode为BOOT_MODE[1:0]=b00:
——BT_FUSE_SEL=0,引导器件中没有应用程序,BootROM进入串行下载模式
——BT_FUSE_SEL=1,引导器件中有应用程序,BootROM从FUSE获取所有引导设备信息
当配置Boot_Mode为BOOT_MODE[1:0]=b10:
——BT_FUSE_SEL=0,引导器件中的有效应用程序,BootROM从boot_cfg引脚获取引导设备信息
——BT_FUSE_SEL=1,引导器件中的有效应用程序,BootROM从熔丝位获取所有引导设备信息
即使配置了 BT_FUSE_SEL=1,当配置了 BOOT_MODE[1:0]=01b时,仍然可以进入串行下载器模式,这与BT_FUSE_SEL没有关系,仅当配置BOOT_MODE[1:0]=00b时,ROM引导加载程序将检查BT_FUSE_SEL。所以,如果有BOOT_MODE两个引脚,仍然可以进入串行下载模式。
在MDK IDE环境下运行如下固件代码,该代码在固件首次启动时烧写BT_FUSE_SEL。在批量生产中,调试器对Flash进行编程并第一次调用启动。所以不再需要引导 Boot引脚判断。
//写熔丝位
if (!(SRC->SBMR2 & SRC_SBMR2_BT_FUSE_SEL_MASK))
{
int timing = OCOTP_TIMING_STROBE_PROG(1325) | OCOTP_TIMING_RELAX(2) | OCOTP_TIMING_STROBE_READ(11) |OCOTP_TIMING_WAIT(24); //ipg_clk=132MHz
OCOTP->TIMING = timing;
while ((OCOTP->CTRL & (1<
ocotp_ctrl &= ~OCOTP_CTRL_ADDR_MASK;
ocotp_ctrl|= OCOTP_CTRL_ADDR(6);
ocotp_ctrl &= ~OCOTP_CTRL_WR_UNLOCK_MASK ;
ocotp_ctrl|= OCOTP_CTRL_WR_UNLOCK(0x3E77);
OCOTP->CTRL = ocotp_ctrl; //写地址,解锁
OCOTP->DATA = (long)((1<<4)|(1<<16));//写入 BT_FUSE_SEL (1<<4) 和FORCE_INTERNAL_BOOT (1<<16)
}
那么如何在生产中做到这一点呢?使用MIMXRT1021CAG4B,之前BT_CFG_xx信号与GND相连,目前想利用这些GPIO 去连接外部的GPIO或者是LCD或者是ADC芯片,上面介绍的代码可以做到这一点。注意,当编程到外部 Flash中时,如何让MCU 执行这些代码?BT_CFG_xxx信号最初是否不需要正确设置才能执行代码,或者是否需要额外使用调试器工具进行了一些设置?在后台启动keil的批处理文件,也可以在下载到flash后开始代码处执行(参见如下µVision用户指南:命令行)。因此,它在编程Flash 后第一次使用调试器启动,届时熔丝位将被写入。
µVision User's Guide (arm.com)
当然 MCU BootUtility或者MFG都是比较好的烧录Fuse的工具。
参考文档"i.MX MCU Manufacturing User's Guide.pdf"Rev. 1, 01/2018, 第8部分有 load fuse命令,例如 load fuse 0x00000008 -> 0x06
意味着将32位的数值 0x00000008 写入到 OTP 区0, 字6 (ADDR = 0x06) 。在参考手册中,生产配置OTP Bank0 Word6 (HW_OCOTP_CFG5)] ,表示熔丝位的偏置是 460h 。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !