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(){ }