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.

[参考译文] MSP430F6779A:关于 PMM_setVCoreUp 库的处理过程与用户指南中的不同

Guru**** 665180 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1316503/msp430f6779a-about-pmm_setvcoreup-library-does-not-process-same-as-the-user-s-guide

器件型号:MSP430F6779A

我检查了库版本2.91.13.01函数 PMM_setVCoreUp。

发现某些步骤与下面第3步和第4步中的用户指南不一致。

第71行对应于第4步:把 PMMCOREV 编程到下一个 VCORE 电平。

但是第74到78行对应于第3步:将 SVML 编程到下一个电平并等待 SVSMLDLYIFG 位为1。

库中的进程似乎在步骤3和步骤4之间交替进行。

我的理解是否正确? (如果是、我可能认为这与一个 lockaux 注册集问题有关。)

uint16_t PMM_setVCoreUp ( uint8_t level){
    uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;

    //The code flow for increasing the Vcore has been altered to work around
    //the erratum FLASH37.
    //Please refer to the Errata sheet to know if a specific device is affected
    //DO NOT ALTER THIS FUNCTION

    //Open PMM registers for write access
    HWREG8(PMM_BASE + OFS_PMMCTL0_H) = 0xA5;

    //Disable dedicated Interrupts
    //Backup all registers
    PMMRIE_backup = HWREG16(PMM_BASE + OFS_PMMRIE);
    HWREG16(PMM_BASE + OFS_PMMRIE) &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
                                          SVSLPE | SVMHVLRIE | SVMHIE |
                                          SVSMHDLYIE | SVMLVLRIE | SVMLIE |
                                          SVSMLDLYIE
                                          );
    SVSMHCTL_backup = HWREG16(PMM_BASE + OFS_SVSMHCTL);
    SVSMLCTL_backup = HWREG16(PMM_BASE + OFS_SVSMLCTL);

    //Clear flags
    HWREG16(PMM_BASE + OFS_PMMIFG) = 0;

    //Set SVM highside to new level and check if a VCore increase is possible
    HWREG16(PMM_BASE + OFS_SVSMHCTL) = SVMHE | SVSHE | (SVSMHRRL0 * level);

    //Wait until SVM highside is settled
    while ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMHDLYIFG) == 0) ;

    //Clear flag
    HWREG16(PMM_BASE + OFS_PMMIFG) &= ~SVSMHDLYIFG;

    //Check if a VCore increase is possible
    if ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVMHIFG) == SVMHIFG){
        //-> Vcc is too low for a Vcore increase
        //recover the previous settings
        HWREG16(PMM_BASE + OFS_PMMIFG) &= ~SVSMHDLYIFG;
        HWREG16(PMM_BASE + OFS_SVSMHCTL) = SVSMHCTL_backup;

        //Wait until SVM highside is settled
        while ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMHDLYIFG) == 0) ;

        //Clear all Flags
        HWREG16(PMM_BASE +
            OFS_PMMIFG) &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                             SVMLVLRIFG | SVMLIFG |
                             SVSMLDLYIFG
                             );

        //Restore PMM interrupt enable register
        HWREG16(PMM_BASE + OFS_PMMRIE) = PMMRIE_backup;
        //Lock PMM registers for write access
        HWREG8(PMM_BASE + OFS_PMMCTL0_H) = 0x00;
        //return: voltage not set
        return ( STATUS_FAIL) ;
    }

    //Set also SVS highside to new level
    //Vcc is high enough for a Vcore increase
    HWREG16(PMM_BASE + OFS_SVSMHCTL) |= (SVSHRVL0 * level);

    //Wait until SVM highside is settled
    while ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMHDLYIFG) == 0) ;

    //Clear flag
    HWREG16(PMM_BASE + OFS_PMMIFG) &= ~SVSMHDLYIFG;

    //Set VCore to new level
    HWREG8(PMM_BASE + OFS_PMMCTL0_L) = PMMCOREV0 * level;

    //Set SVM, SVS low side to new level
    HWREG16(PMM_BASE + OFS_SVSMLCTL) = SVMLE | (SVSMLRRL0 * level) |
                                         SVSLE | (SVSLRVL0 * level);

    //Wait until SVM, SVS low side is settled
    while ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMLDLYIFG) == 0) ;

    //Clear flag
    HWREG16(PMM_BASE + OFS_PMMIFG) &= ~SVSMLDLYIFG;
    //SVS, SVM core and high side are now set to protect for the new core level

    //Restore Low side settings
    //Clear all other bits _except_ level settings
    HWREG16(PMM_BASE + OFS_SVSMLCTL) &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
                                           SVSMLRRL1 + SVSMLRRL2
                                           );

    //Clear level settings in the backup register,keep all other bits
    SVSMLCTL_backup &=
        ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);

    //Restore low-side SVS monitor settings
    HWREG16(PMM_BASE + OFS_SVSMLCTL) |= SVSMLCTL_backup;

    //Restore High side settings
    //Clear all other bits except level settings
    HWREG16(PMM_BASE + OFS_SVSMHCTL) &= (SVSHRVL0 + SVSHRVL1 +
                                           SVSMHRRL0 + SVSMHRRL1 +
                                           SVSMHRRL2
                                           );

    //Clear level settings in the backup register,keep all other bits
    SVSMHCTL_backup &=
        ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);

    //Restore backup
    HWREG16(PMM_BASE + OFS_SVSMHCTL) |= SVSMHCTL_backup;

    //Wait until high side, low side settled
    while (((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMLDLYIFG) == 0) ||
           ((HWREG16(PMM_BASE + OFS_PMMIFG) & SVSMHDLYIFG) == 0)) ;

    //Clear all Flags
    HWREG16(PMM_BASE + OFS_PMMIFG) &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
                                          SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
                                          );

    //Restore PMM interrupt enable register
    HWREG16(PMM_BASE + OFS_PMMRIE) = PMMRIE_backup;

    //Lock PMM registers for write access
    HWREG8(PMM_BASE + OFS_PMMCTL0_H) = 0x00;

    return ( STATUS_SUCCESS) ;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Tink:

    代码与示例代码中的代码相似、但第112行  

    while (((HWREG16 (PMM_BASE + OFS_PMMIFG)& SVSMLDLYIFG)=0)||
    ((HWREG16 (PMM_BASE + OFS_PMMIFG)& SVSMHDLYIFG)== 0));

    具有"或"运算、而该运算应该是"与"运算。 这可能是导致高侧或低侧先稳定下来的原因、随后代码将继续运行、而另一侧却不保持稳定。

    ——

    我确实看到了 VCORE 在低侧之前设置的过程流程、但我认为代码函数会起作用。 (将或切换回 AND 操作后)。

    此致、
    卢克