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.

MSP430FR58471: Self update mechanism using I2C running out of RAM

Part Number: MSP430FR58471

Hi,

I couldn't find another thread on the forum regarding this topic so I figured I'd make one. I'm currently working on developing a self update mechanism using I2C running out of RAM. I need to run this code from RAM in order to receive and flash a complete TI-TXT firmware image on a running target. For reference I'm using the MSP430-GCC compiler.

So far I have been able to get this code onto the device, load itself into RAM, and begin executing from RAM. My problems arise however when I attempt to send I2C to the device. For some reason my I2C isr is not being called correctly. I've gone through numerous sections of the user guide and one thing I found interesting was using the RAM based interrupt vectors via SYSRIVECT.  Maybe that is required to run ISR's out of RAM? Any help in finding out why my isr isn't being called properly would be great, overall suggestions are welcome too.

I've included my code that I jump to. Before this executes I program this "updater" code to a section of main flash then set my SP and PC to jump.

#include <msp430fr58471.h>

#define str(s) #s
#define ENQUOTE(s) str(s)
#define DO_PRAGMA(x) _Pragma (#x)
#define location(var_name,address) DO_PRAGMA(LOCATION(var_name, address))
#define attribute_section(x) __attribute((section(x)))

#define RAM_BASE              0x1c00
#define RAM_END               0x1ffe
#define BEGIN_RAM_EXECUTION() \
  asm("mov #"ENQUOTE(RAM_END)", r1"); \
  asm("br #"ENQUOTE(RAM_BASE))
#define CODE_BASE             0x8000
#define MAIN_CODE_OFFSET      0x0400
#define BEGIN_ROM_EXECUTION() asm("br #0x8400")
#define I2C_INT_VECTOR        0xffee

#define SCL     (1 << 7)
#define SDA     (1 << 6)
#define MCU_IRQ (1 << 4)

#define XT1_LF_MODE (LFXTDRIVE_0 + 0x0100)

#endif //defined(__MSP430FR58471__)

register unsigned int i2c_byte asm ("R4");
register unsigned int i2c_temp asm ("R5");
register unsigned int address asm ("R10"); // Needs to match jmp main_entrance check in main

/* Standard #defines */
#define GSC_STAGE2_PUC      0x1
#define GSC_STAGE2_ADDR     0x2
#define GSC_STAGE2_ERASE    0x3
#define GSC_STAGE2_WORD     0x4
#define GSC_STAGE2_PROG     0x5

void attribute_section(".text") __attribute__((optimize("Os"))) main( void ) {

  /* Copying ourself from main ROM to RAM */
  asm("mov #2, r5");                   // Store number 2
  asm("mov #main_entrance, r7");       // Store main_entrance location
  asm("mov #the_end, r8");             // Store the_end location
  asm("mov #"ENQUOTE(RAM_BASE)", r9"); // Store RAM_BASE location
  asm("memcpy:");                      // memcpy label (copying loop begins here)
  asm("mov @r7, 0(r9)");               // Move content of flash to RAM
  asm("add r5, r7");                   // Increment flash pointer by 2
  asm("add r5, r9");                   // Increment RAM pointer by 2

  asm("cmp r7, r8");                   // Check if we have reached the_end location
  asm("jne memcpy");                   // If not, repeat loop

  /* Write out the I2C interrupt vector address to vector table (0xffee) */
  asm("mov #main_entrance, r7");             // Store main_entrance location
  asm("mov #i2c_isr, r8");                   // Store i2c_isr location
  asm("sub r7, r8");                         // subtract main_entrance addr from i2c_isr addr, r8 has offset
  asm("add #"ENQUOTE(RAM_BASE)", r8");       // Add value of RAM_BASE to get new location of i2c_isr
  asm("mov #"ENQUOTE(I2C_INT_VECTOR)", r9"); // Store location of i2c interrupt vector
  asm("mov r8, 0(r9)");                      // Write out the I2C isr address to vector table

  /* Jump to RAM and execute */
  BEGIN_RAM_EXECUTION();

  asm("main_entrance:");
  while(1); // Loop here so the I2C ISR has somewhere harmless to return to
}

void attribute_section(".text") __attribute__((optimize("O0"))) i2c_isr(void) {
  switch(__even_in_range(UCB0IV,0x1e)) {
    case 0x06:        // Vector 6: STTIFG   (Start Condition)
    ... // The rest of the UCB0IFG cases here
    default:
    break;
  }
}

void attribute_section(".text") the_end(){
}

**Attention** This is a public forum