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.

MSP430F5438A: VCORE change - Delay flags do not work

Other Parts Discussed in Thread: MSP430F5438A

Hi!

I utilize the code provided in MSP430x5xx Family User Guide section 2.2.4 to increase the VCORE voltage. However, I have found out that the delays do obviously not work but are simply overridden - I don't find another reason.

For instance, I run the MCLK at 8MHz from the DCO, increase the VCORE step by step and then get back to VCORE=0. Starting from VCORE=0 at 1.43V a slope can be found which ends 35µs later at about 1.62V - this is practically the minimum number of MCLK code instruction cycles for 3 increases with 8MHz. Btw: If I include a delay of >=100us after the VCORE change the voltage goes to its final value as expected and provided in the datasheet. Each step then takes about 100µs (470nF cap, VCC=3V) until the plateau is reached.

Obviously the delay flag for SVM does not work (I included a counter register in the loops and there were practically no counts).

One thing that I tried out was to use the SVSMLDLYST flag in the SVSMLCTL register rather than the SVSMLDLYIFG in PMMIFG. Guess what happens? Just polling that flag causes a system reset. WTF how can that happen?

You can find the code below - sorry, it's a little bit hard-core assembler for faster processing and reduced code size ;)

L_SYS_IncVCore:
                mov     &PMMCTL0,R12                        // { Get actual VCORE.
                and     #3,R12                              // }
                inc     R12                                 // 1 Set to new value
                bit     #BIT4,R12                           // 1 already overflow to 3rd bit?
                jnz     IncVCore_End                        // 2 If yes, then VCORE=3 already given
                mov.b   #0xA5,PMMCTL0_H                     // 4 Open PMM registers for write access
IncVCore_Lp0:   bit     #SVSMHDLYIFG,&PMMIFG                // 4 SVS/SVM high-side delay expired?
                jz      IncVCore_Lp0                        // 2
IncVCore_Lp1:   bit     #SVSMLDLYIFG,&PMMIFG                // 3 SVS/SVM low-side delay expired?
                jz      IncVCore_Lp1                        // 2

                mov     &SVSMHCTL,R13                       // 3 { Modify SVS/SVM for High side
                bis     #SVSHE+SVMHE,R13                    // 2 ..
                bic     #0x0307,R13                         // 2 ..
                add     R12,R13                             // 1 ..
                swpb    R12                                 // 1 ..
                add     R12,R13                             // 1 ..
                mov     R13,&SVSMHCTL                       // 3 }

                mov     &SVSMLCTL,R13                       // 3 { Modify SVM (not SVS!) for Low Side
                bis     #SVSLE+SVMLE,R13                    // 2 ..
                bic     #0x0307,R13                         // 2 ..
                sub     #SVSLRVL0,R12                       // 1 .. Keep SVSLRVL on old level
                add     R12,R13                             // 1 ..
                swpb    R12                                 // 1 ..
                inc     R12                                 // 1 ..
                add     R12,R13                             // 1 ..
                mov     R13,&SVSMLCTL                       // 3 }

//IncVCore_LpX:   bit     #SVSMLDLYST,&SVSMLCTL             // Using this loop rather than the next one
//                jc      IncVCore_LpX                      // causes resets & undefined behaviour.

IncVCore_Lp2:   bit     #SVSMLDLYIFG,&PMMIFG                // 3 Wait till SVM is settled
                jz      IncVCore_Lp2                        // 2

                bic     #SVMLVLRIFG + SVMLIFG,&PMMIFG       // 5 Clear already set flags
                mov.b   R12,&PMMCTL0_L                      // 4 Set VCore to new level
                bit     #SVMLIFG,&PMMIFG                    // 3
                jz      IncVCore_Jmp0                       // 2
IncVCore_Lp3:   bit     #SVMLVLRIFG,&PMMIFG                 // 4 Wait till new level reached
                jz      IncVCore_Lp3                        // 2
IncVCore_Jmp0:  add.b   #SVSLRVL0_H,&SVSMLCTL_H             // Set SVSLRVL to new (higher) level
                mov.b   #0,&PMMCTL0_H                       // 3 Lock PMM registers
IncVCore_End:   ret                                         // 4

  • Hello wissenwasserj,

    For 8MHz operation, changing VCORE is not needed for it is a valid frequency for VCORE level 0. If you still want to step up the VCORE voltage, then we highly recommend using the SetVCore function provided within our example codes. For this device, we actually have an example for C and Assembly. You can see these examples with MSPWare within TI Resource Explorer in CCS. alternatively, you can visit our cloud based version of Resource Explorer at dev.ti.com . Navigate to Resource Explorer > MSPWare > Devices > MSP430 > MSP430F5438A > Code Examples > Assembly and check out example msp430x54xA_UCS_3.asm . this example is SW Toggle of a pin at 12 MHz and includes an assembly version of the SetVCore function.

    Regards,

    JH

  • Hi!

    The code written above follows exactly the code examples for changing VCORE. Moreover, I even preserve the High-performance and mask-flags.  However, it does not work correctly - the delays don't work.

    Using the outcommented part for delay causes the MCU to occasionally reset;

    Using the (regular) loop at label 'IncVCore_Lp2' does not even work - I included a counter into each loop - it didn't show any increase that would be related to a delay at any MCLK speed.
     
    I have a system running with limited battery capacity and, depending on the required performance, I will switch between RTC crystal, DCO @ up to 24MHz and a crystal @ 24MHz (24MHz crystal only where low jitter is required). I need VCORE to change for minimized power consumption and need that stuff to work accurately.
     
    Jürgen

  • Jurgen,

    Please see the suggested method of changing Vcore below.

                mov.w	#PMMCOREV_1, R12		; Set VCore to 1.6V to support 12MHz clock 
                calla	#SetVCore
    
    
    ;-------------------------------------------------------------------------------
    SetVCore   ; SetVCore function
               ; In order to support high speed MCLK , The voltage level of Vcore  must be sufficiently high
               ; The voltage level of Vcore must be increased by one step one time
    ;-------------------------------------------------------------------------------
                mov.b   #PMMPW_H, &PMMCTL0_H     ;Open PMM registers for write
       ;  Set SVS/SVM high side new level
                mov.w   R12,R15                 ; R12--->R15
    			and.w   #0xff,R15
                swpb    R15                     ;exchange the high and low byte of R15
                add.w   R12,R15                 ;add src to dst src+dst--->dst
                add.w   #0x4400,R15             ;SVM high-side enable ,SVS high-side enable
                mov.w   R15,&SVSMHCTL            ;
       ;  Set SVM low side to new level
    			mov.w   R12,R15
    			add.w   #0x4400,R15
    			mov.w   R15,&SVSMLCTL
       ; Wait till SVM is settled
    do_while1   bit.w   #SVSMLDLYIFG,&PMMIFG     ; Test SVSMLDLYIFG
    			jz     do_while1
       ; Clear already set flags
                bic.w   #SVMLIFG,&PMMIFG         ;clear SVM low-side interrupt flag
                bic.w   #SVMLVLRIFG,&PMMIFG      ;clear  SVM low-side voltage level reached interrupt flag
       ; Set VCore to new level
                mov.b  R12,&PMMCTL0_L
       ; Wait till new level reached
                bit.w   #SVMLIFG,&PMMIFG
                jz     low_set
    do_while2   bit.w   #SVMLVLRIFG,&PMMIFG      ; Test SVMLvLrIFG
    			jz     do_while2
        ;Set SVS/SVM low side to new level
    low_set     mov.w   R12,R15
                and.w   #0xff,R15
                swpb    R15
                add.w   R15,R12
                add.w   #0x4400,R12
                mov.w   R12,&SVSMLCTL
    	;Lock PMM registers for write access
    			clr.b   &PMMCTL0_H
                RETA

    Regards,

    JH

  • Even your code does not work.

    Just for your information: For verification I run the MCLK from the DCO at 8 MHz and execute the routine at the end of this post. The function fSys_SetVCore requests R12 to hold the new VCORE-setting and then calls SetVCore as often as necessary.
     
    With this routine I see a triangular VCORE starting from 1.43V up to 1.62V and then down again (with a breakpoing at "jmp vcore2_lp" I see the VCORE rise to 1.95V).

    With respect to a TI-presentation (focus.ti.com/.../Understanding-the-New-'5xx-Integrated-Power-Management-Modul.pdf) the VCORE should at least rise to 1.8V as an SVM-level.


    vcore2_lp:
        mov #0,R12
        call #fSys_SetVCore
        mSys_WaitShort 500,R15 // Wait 3*500MCLK (187ms) for settling VCORE at lower level
        mov #1,R12
        call #fSys_SetVCore
        mov #2,R12
        call #fSys_SetVCore
        mov #3,R12
        call #fSys_SetVCore
        jmp vcore2_lp

  • Hello Jurgen,

    I grabbed a MSP430F5438A Exp. Board to test out the assembly code example provided in TI resource Explorer. The code works as is. I then added to more calls of the SetVcore chain to bump it up to Core Level 3 via stepping. This works as intended as well. The only other change made to the code from "stock" is the output pin from P1.0 to P1.1. This is due tot he fact that my LED1 (P1.0) is disconnected on my board and LED2 is located on P1.1. Code posted below to try out.

    I am unsure of your issue here, so I am providing a list for things to watch for.

    *Do not measure Vcore directly via the Vcore cap while changing Vcore level. This can cause instability to the part and potentially resets.

    *Please be sure when changing Vcore to only change one level at a time per the FLASH37 errata.

    *Since this is an assembly project, please be mindful of CPU errata that may effect you. These are usually taken care of in the compiler for C code.

    *Make sure to unlock PMM module before trying to write to its registers.w

    *Please be mindful of PMM errata that may effect you.

    *Please ensure DVCC voltage level is high enough to support higher VCore levels before changing levels.


    Regards,

    JH

    ;-------------------------------------------------------------------------------
    ; MSP430 Assembler Code Template for use with TI Code Composer Studio
    ;
    ;
    ;-------------------------------------------------------------------------------
                .cdecls C,LIST,"msp430.h"       ; Include device header file
                
    ;-------------------------------------------------------------------------------
                .def    RESET                   ; Export program entry-point to
                                                ; make it known to linker.
    ;-------------------------------------------------------------------------------
                .text                           ; Assemble into program memory.
                .retain                         ; Override ELF conditional linking
                                                ; and retain current section.
                .retainrefs                     ; And retain any sections that have
                                                ; references to current section.
    
    ;-------------------------------------------------------------------------------
    RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
    StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer
    
    
    ;-------------------------------------------------------------------------------
    ; Main loop here
    ;-------------------------------------------------------------------------------
    _main
    
    
                mov.w	#PMMCOREV_1, R12		; Set VCore to 1.6V to support 12MHz clock
                calla	#SetVCore
                mov.w	#PMMCOREV_2, R12		; Set VCore to 1.6V to support 12MHz clock
                calla	#SetVCore
                mov.w	#PMMCOREV_3, R12		; Set VCore to 1.6V to support 12MHz clock
                calla	#SetVCore
                bis.b   #BIT1,&P1DIR            ; P1.0 output
                bis.b   #0x07,&P11DIR           ; ACLK, MCLK, SMCLK set out to pins
                bis.b   #0x07,&P11SEL           ; P11.0, 1, 2 for debugging purposes
                ; Initialize clocks
                bis.w   #SELREF_2,&UCSCTL3      ; Set DCO FLL reference = REFO
                bis.w   #SELA_2,&UCSCTL4        ; Set ACLK = REFO
    
                bis.w   #SCG0,SR                ; Disable the FLL control loop
                clr.w   &UCSCTL0                ; Set lowest possible DCOx, MODx
                mov.w   #DCORSEL_5,&UCSCTL1     ; Select range for 24 MHz operation
                mov.w   #FLLD_1 + 366,&UCSCTL2  ; Set DCO multiplier for 12 MHz
                                                ; (N + 1) * FLLRef = Fdco
                                                ; (366 + 1) * 32768 = 12MHz
                                                ; Set FLL Div = fDCOCLK/2
                bic.w   #SCG0,SR                ; Enable the FLL control loop
    
      ; Worst-case settling time for the DCO when the DCO range bits have been
      ; changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG
      ; for optimization.
      ; 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
                mov.w   #0x6E34,R15
                nop
                mov.w   #0x1,R14
    delay_L1    add.w   #0xFFFF,R15
                addc.w  #0xFFFF,R14
                jc      delay_L1
    
                ; Loop until XT1,XT2 & DCO fault flag is cleared
    do_while    bic.w   #XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG,&UCSCTL7
                                                ; Clear XT2,XT1,DCO fault flags
                bic.w   #OFIFG,&SFRIFG1         ; Clear fault flags
                bit.w   #OFIFG,&SFRIFG1         ; Test oscillator fault flag
                jc      do_while
    
    while_loop  xor.b   #BIT1,&P1OUT            ; Flash the LED
                mov.w   #0xFFFF,R4              ; Initialize loop counter R4=65535
    delay_loop  dec.w   R4                      ; Decrement loop counter
                jne     delay_loop              ; Loop if loop counter > 0
                jmp     while_loop              ; Infinite while loop
    ;-------------------------------------------------------------------------------
    SetVCore   ; SetVCore function
               ; In order to support high speed MCLK , The voltage level of Vcore  must be sufficiently high
               ; The voltage level of Vcore must be increased by one step one time
    ;-------------------------------------------------------------------------------
                mov.b   #PMMPW_H, &PMMCTL0_H     ;Open PMM registers for write
       ;  Set SVS/SVM high side new level
                mov.w   R12,R15                 ; R12--->R15
    			and.w   #0xff,R15
                swpb    R15                     ;exchange the high and low byte of R15
                add.w   R12,R15                 ;add src to dst src+dst--->dst
                add.w   #0x4400,R15             ;SVM high-side enable ,SVS high-side enable
                mov.w   R15,&SVSMHCTL            ;
       ;  Set SVM low side to new level
    			mov.w   R12,R15
    			add.w   #0x4400,R15
    			mov.w   R15,&SVSMLCTL
       ; Wait till SVM is settled
    do_while1   bit.w   #SVSMLDLYIFG,&PMMIFG     ; Test SVSMLDLYIFG
    			jz     do_while1
       ; Clear already set flags
                bic.w   #SVMLIFG,&PMMIFG         ;clear SVM low-side interrupt flag
                bic.w   #SVMLVLRIFG,&PMMIFG      ;clear  SVM low-side voltage level reached interrupt flag
       ; Set VCore to new level
                mov.b  R12,&PMMCTL0_L
       ; Wait till new level reached
                bit.w   #SVMLIFG,&PMMIFG
                jz     low_set
    do_while2   bit.w   #SVMLVLRIFG,&PMMIFG      ; Test SVMLvLrIFG
    			jz     do_while2
        ;Set SVS/SVM low side to new level
    low_set     mov.w   R12,R15
                and.w   #0xff,R15
                swpb    R15
                add.w   R15,R12
                add.w   #0x4400,R12
                mov.w   R12,&SVSMLCTL
    	;Lock PMM registers for write access
    			clr.b   &PMMCTL0_H
                RETA
    
    ;-------------------------------------------------------------------------------
    ; Stack Pointer definition
    ;-------------------------------------------------------------------------------
                .global __STACK_END
                .sect   .stack
                
    ;-------------------------------------------------------------------------------
    ; Interrupt Vectors
    ;-------------------------------------------------------------------------------
                .sect   ".reset"                ; MSP430 RESET Vector
                .short  RESET
                
    

  • Even though it's late I got the problem: In the errata sheet the PMM10 problem is reported regarding wrong flag settings after PUC.

    Why the hell are that known issues not included in the User Guide? The C-code is fully shown but not this and ohter errata are not even mentioned.

  • Hi,

    I can understand your frustration on ERRATA. However a device specific ERRATA sheet is required to reflect device speicific malfunctions also with respect to the corresponding DIE revision. Doing this in a family user's guide would get easily confused and hard to read.

    Therefore the recommendation is to utalize following key documents for development:
    - latest datasheet revision from the web
    - latest ERRATA sheet from the
    - latest familiy user's guide

    Optionally dedicated Application Reports linked to certain topics are recommended as well.

    Best regards,
    Dietmar

**Attention** This is a public forum