This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3507: 外部低速时钟LFXT失效后如何切换到内部LFOSC

Part Number: MSPM0G3507
Other Parts Discussed in Thread: SYSCONFIG,

根据技术资料了解到MSPM0系列的MCU外部晶体失效后无自动切换功能,如果低功耗模式下,RTC及WDT时钟源都是LFCLK,当LFCLK失效后,程序如同死机一般,无法进入RTC周期中断,也无法看门狗超时复位。请问如何写代码实现以下功能:1)、开启LFCLK失效中断、并在外部LFXT失效后切换到LFOSC;2)、开启LFXT恢复GOOD中断,并在中断中及时切换为LFXT。

  • 根据技术资料了解到MSPM0系列的MCU外部晶体失效后无自动切换功能

    能告诉我具体是在手册哪个章节吗?

  • 我的意思就是设计一个我手动切换的功能,技术手册上有失效中断或者GOOD中断,请看下图,我想着如果失效后我手动切换到内部的LFOSC,不至于程序一直死机不再运行啊

  • 我想你应该是指LFCLKFAIL这个中断事件名。有关该中断写法请参考user guide第6.3.5章节。

  • 这段我看过几次,但是代码一直写不出来无法调试,能否给出一段如何配置中断及中断进入后如何查询标志的示例

  • 能否给出一段如何配置中断及中断进入后如何查询标志的示例

    我也没有配置过。我在国外论坛问下看是否有人写过。

  • 目前内测样片也就是pre-production版本的板子只有一种方法换回使用LFOSC就是通过BOOTRST。

    如果能接受这种方式的话可以给你一个简单参考。

  • 现在我测试用的开发板如果外部LFXT失效后,程序貌似不运行了,看门狗 也停止了,直到外部LFXT恢复正常后,程序继续运行也没发现复位的。所以这种现象我觉得是一个很大的 bug,因为我们无法保证外部LFXT永远正常允许,特别是潮湿环境。所以我的目的就是寻求一种方法:当外部LFXT失效后,MCU自动或者我通过代码手动切换到内部LFOSC就可以了。保证MCU可靠的运行,即便损失一部分由于精度导致的时间问题。注:失效后再复位后能切换到LFOSC也行

  • 好的,已向工程师跟进。

  • 你好,工程师推荐使用LFCLK Monitor,相关细节在TRM中有描述。

    你需要在连接之前检查LFXT的状态是否良好。你是否在连接之前检查了LFXT的状态是否良好?

  • 我知道,能否给出代码示例?TI的文档看了之后一般没有示例很难写出代码的

  • 好的,已向工程师跟进。

  • 你好,请参考工程师的回复:

    目前是没有相关LFCLK Monitor的类似这样的处理的例程,但是有类似

    • 检查LFXT是否稳定
      • 检查 LFXTGOOD 寄存器,如果设置了此寄存器则将 LFCLK 设置为 LFXT
      • 为 LFXTGOOD 检查设置一个定时器超时,如果达到超时则保持 LFCLK = LFOSC 并继续程序。您可以定期检查 LFXTGOOD 是否设置,以查看晶体是否恢复然后设置。
    • 如果 LFXT 设置后失败
      • 如果 LFXT 是 MCLK 源,那么这是一个致命错误,设备将复位,否则您将需要检查处理 LFCLK 监视器中断。同样,这在 TRM 中有详细说明。

    以下是 DriverLibrary 中的代码,您可以使用该流程。这个函数不能直接满足您的需求,但它是一个很好的构建参考。我添加了注释以希望有帮助。

    void DL_SYSCTL_setLFCLKSourceLFXT(DL_SYSCTL_LFCLKConfig *config)
    {
        
        DL_Common_updateReg(&SYSCTL->SOCLOCK.LFCLKCFG,
            ((uint32_t) config->lowCap << SYSCTL_LFCLKCFG_LOWCAP_OFS) |
                ((uint32_t) config->monitor << SYSCTL_LFCLKCFG_MONITOR_OFS) |
                (uint32_t) config->xt1Drive,
            (SYSCTL_LFCLKCFG_XT1DRIVE_MASK | SYSCTL_LFCLKCFG_MONITOR_MASK |
                SYSCTL_LFCLKCFG_LOWCAP_MASK));
        // start the LFXT oscillator
        SYSCTL->SOCLOCK.LFXTCTL =
            (SYSCTL_LFXTCTL_KEY_VALUE | SYSCTL_LFXTCTL_STARTLFXT_TRUE);
        // wait until LFXT oscillator is stable
        // if it does not stabilize, check the hardware/IOMUX settings
        //ADD A TIMER OR SYSTICK FOR A TIMEOUT BEFORE THIS STEP
        while ((DL_SYSCTL_getClockStatus() & SYSCTL_CLKSTATUS_LFXTGOOD_MASK) !=
               DL_SYSCTL_CLK_STATUS_LFXT_GOOD) {
            ;
        }
        //IF NO TIMEOUT SET LFCLK, OTHERWISE HANDLE TIMEOUT AND SKIP THIS
        // switch LFCLK source from LFOSC to LFXT
        SYSCTL->SOCLOCK.LFXTCTL =
            (SYSCTL_LFXTCTL_KEY_VALUE | SYSCTL_LFXTCTL_SETUSELFXT_TRUE);
    }

  • 现在关键问题就是一旦LFXT有故障(比如我把一个负载电容短路),程序执行“SYSCTL->SOCLOCK.LFXTCTL =
    (SYSCTL_LFXTCTL_KEY_VALUE | SYSCTL_LFXTCTL_STARTLFXT_TRUE);”到这里,就貌似死机一样,不再继续运行了(这条指令后面的不再执行),问过FAE说是进入了不可屏蔽中断,所以目前不知道这个中断怎么写代码,根本做不到超时后再继续LFOSC的执行

  • 在 sysconfig 中确保启用“Enable to use monitor for LFXT, EXLF failure”。

    然后你会想要 NVIC_EnableIRQ(SYSCTL_INT_IRQn); 在调用 SYSCFG_DL_init() 之后;

    SYSCTL 中断在 GROUP0_IRQHandler 中。

    对于ISR你会想要类似这样的:

    //Setup LFCLK_Fail Interrupt
    void GROUP0_IRQHandler(void)
    {
        //checks pending in the SYSCTRL interrupt register
        switch(DL_SYSCTL_getPendingInterrupt(DL_SYSCTL_IIDX)){
            case DL_SYSCTL_IIDX_LFCLK_FAIL: //We want to check if the LFCLK failed
            /* The below function will reset the device, the parameter can be changed to 
                change the level of a reset, I suggest doing CTRL+Left Click to go into
                the header file and see all the reset options*/
                DL_SYSCTL_resetDevice(DL_SYSCTL_RESET_BOOT); 
                break;
            default:
                break;
        }
    }

    我注意到 SYSCTL 中断屏蔽没有正确设置,我将检查原因

  • 貌似这都编译不过,DL_SYSCTL_getPendingInterrupt()是没有入口参数的

  • 的确是这样,这与量产芯片有些差异,工程师正在等待确认这些差异,并且可能需要改变配置方式。

    You're correct there is no parameter for the getPendingInterrupt function, I had accidently kept that when testing. I have found a difference between this and the production silicon so I am awaiting confirmation on the change. Based on this change we may need to find a different avenue. 

  • 对于量产版本的MSPM0G3507芯片来说,LFCLK_FAIL 在 NMI中(正如您的FAE朋友所说),所以它现在在DL_SYSCTL_NMI_IIDX.

    下面这段代码你可以试一下:

    void NMI_Handler(void)
    {
        switch(DL_SYSCTL_getPendingNonMaskableInterrupt()){
        case DL_SYSCTL_NMI_IIDX_LFCLK_FAIL:
            //__BKPT();
        default:
            break;
        }
    }

    这是量产芯片的新改动。