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.

MSP430G2433: BSL warm start reacts differently than cold start

Part Number: MSP430G2433


Hi,

Following the discussion https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/704222 , I wanted to implement the BSL warm start to be able to update the msp firmware from our host controller without risking erasing the ADC calibration upon wrong password. 

When entering the BSL with the test/reset sequence (cold start), I can successfully do the whole flashing sequence.

But when entering the BSL with the warm start, the BSL replies to the Sync command with an ACK and then does not reply to any other command (I checked with a logic analyzer to be sure)

In both cases the whole communication process is exactly the same thing, the only difference being the warm VS cold start.

The command I use to enter the BSL warm start.

__disable_interrupt();

((void (*)(void))0x0C02)();

Do you have any idea what could be causing my issue? Or what I could check to understand the problem further?

  • Hello Cedric,

    Taking a look at the MSP430 Flash Device Bootloader guide, it appears for this device there is a required "preparation for software call" that is required.

    Try this and see if that resolves your issue.

  • Also see note 2 at the bottom of that page.  Even if you don't want to clear LOCKA, you still need to clear LOCK before jumping to the warm start.  So  it would be

    mov.w   #FWKEY,   &FCTL3

    LOCKA is not cleared by that because it is a toggle bit.  Writing a zero has no effect.  You have to write a 1 to toggle it to the opposite state.  But LOCK is just a regular bit, so writing a zero clears it.  On boot, LOCK is set, but needs to be cleared for BSL.

    If you read out the BSL code at 0x0C00 and disassemble it, this is what you see.  Of course you can use the default warm start vector, or make your own.  My preference is 0x0C0C, which skips only the LOCK/LOCKA stuff.  Note that 0x0C06 clears both LOCK and LOCKA.  If you skip over that, you still have to clear LOCK beforehand.

    0c00: 0c06 .dw 0x0c06                     ;Cold start vector
    0c02: 0c1e .dw 0x0c1e                     ;Warm start vector
    0c04: 3fff jmp 0x0c04                     ;Endless loop
    0c06: 40b2 mov.w #0xa540, &FCTL3          ;Cold start: toggle LOCKA, reset LOCK
    0c08: a540
    0c0a: 012c
    0c0c: 90b2 cmp.w #0xaa55, &0xffde         ;check key word - is BSL disabled?
    0c0e: aa55
    0c10: ffde
    0c12: 27ff jeq 0x0c12                     ;yes - infinite loop
    0c14: 4031 mov.w #0x0220, SP              ;no - set stack pointer, etc.
    0c16: 0220
    0c18: 430b mov.w #0, r11
    0c1a: 43c0 mov.b #0, 0x0216
    0c1c: f5fa
    0c1e: c232 dint -- bic.w #8, SR           ;Warm start - clear interrupts, etc.
    0c20: c0f2 bic.b #0x32, &IE1
    0c22: 0032
    0c24: 0000
    -etc-

  • Hello Cedric,

    To add on here from Dennis's previous suggestion, there is also another step that needs to be done before invoking the BSL via SW entry (or Warm start as you call it). You need to ensure to reset peripherals/resources the BSL uses to its default HW Reset state before invoking the BSL via SW. From the snippet Dennis showed, you can see that this BSL changes uses the clock and TimerA. I would set the clock system to default and the Timer A peripheral (all registers) to default HW Reset state before invoking the BSL via SW entry. Also remember to disabled interrupts before SW entry as well.
  • Thank you all for your replies!

    So I finally had time to test it but am still not able to put the msp properly in BSL. 

    Here are a few of my trials

    __disable_interrupt();
    BCSCTL2 = 0; // asm ("mov.b #00h, &BCSCTL2");
    FCTL3 = FWKEY; //asm ("mov.w #FWKEY, &FCTL3");
    __bic_SR_register(0xFF);
    ((void (*)(void))0x0C0C)();

    I also tried to put it in its own asm function and call it from the c file.

    	    mov.b 	#00h, &BCSCTL2
    	    mov 	#00h, SR
    	    mov.w   #FWKEY, &FCTL3
    	    br 		&0C0Ch

    I also tried to reset the value of all registers indicated in Dennis screenshot (by looking at their default value in the MSP430x2xx Family User's Guide)  

    __disable_interrupt();
    TA0CTL = 0;
    TA0CCTL0 = 0;
    TA0R = 0;
    TA0CCR0 = 0;
    DCOCTL = 0x60;
    BCSCTL1 = 0x87;
    BCSCTL2 = 0; // asm ("mov.b #00h, &BCSCTL2");
    BCSCTL3 = 0x05;
    FCTL3 = FWKEY; //asm ("mov.w #FWKEY, &FCTL3");
    __bic_SR_register(0xFF);
    ((void (*)(void))0x0C0C)();

    With all those, the BSL did not respond correctly.

    Is there something obviously wrong with my snippets (I am quite new with msp and assembly ; ))

    Is there a way with the debugger to see if i've entered the BSL correctly ( and set the peripherals correctly)?

    Cédric

  • Cedric Gerber said:

    I also tried to put it in its own asm function and call it from the c file.

    	    mov.b 	#00h, &BCSCTL2
    	    mov 	#00h, SR
    	    mov.w   #FWKEY, &FCTL3
    	    br 		&0C0Ch

    My experience with this stuff is all in assembler, so I don't know  what comes along with using C that might complicate things.

    But in the snippet above, it should be

    br   #0C0Ch 

    Also, while I don't understand it, the C format of your jump instruction to 0C0Ch appears to be the same as you used originally for 0C02h.  But they can't be the same format.  What's at 0C02h is a word vector which points to TI's cold start location.  But at 0C0Ch you have executable code.  So in assembler terms, you could branch &0C02, but you must  branch #0C0C.  Someone who knows C will have to say what the right C format is for those instructions.

  • Hello Cedric,

    The LOCK and LOCKA bits need to be cleared before entering the BSL as well. You are not doing that in the above code.  Also, why are you moving 0xFF into the SR register before jumping? the documentation says to clear SR with 0x00. Some of the things you are missing are below. Alos, for a Warm start (aka SW invoke) you need to jump to 0x0C02.

    /// Clear LOCKA
    FCTL3 = FWKEY + LOCKA:
    
    //Jump to BSL
    ((void ( * )())0x0C02)(); // jump to BSL

**Attention** This is a public forum