Hi Tomek, Try the code snippet below. I am using 20-bit access for some time, targetting MSP430F2417/F2618 The code is part of my bootloader code. While bootloader is executed all IRQs are disabled. I did not have much time to look closer at your code. Hope it helps.
/* * 20-bit write access to flash func */ static inline void FlashWriteByte (uint32 Address, uint8 Byte) { unsigned int sr, flash; __asm__ __volatile__ ("mov r2,%0":"=r"(sr):); _DINT(); __asm__ __volatile__ ("movx.a %1,%0":"=r"(flash):"m"(Address)); __asm__ __volatile__ ("movx.b %1, @%0":"=r"(flash):"m"(Byte)); __asm__ __volatile__ ("mov %0,r2"::"r"(sr)); } ... /* * Clear LOCK Bit * Set LOCKA bit */ FCTL3 = FWKEY + LOCKA; FCTL1 = FWKEY + ERASE; /* * Dummy write to erase Flash segment */ FlashWriteByte (Address + Start, 0); /* * Set WRT bit for byte write operation */ FCTL1 = FWKEY + WRT; /* * Write value(s) to flash */ uint8 *SrcPtr = (uint8*)Buffer; uint16 i; for (i = Start; i < Count; i++) { FlashWriteByte (Address + i, SrcPtr[i]); } ... Regards Dan On 04/05/2014 00:00, Tomek Lorek wrote: > Hi, > I'm trying to figure out how to properly erase (and then to write, but > this is the fist step to have anything working) flash region from high > memory (over 64kB), thus using 20-bit mode. > > The erase procedure is quite straightforward: > > --start-- > unsigned long flash_addr = 0x1c400; > unsigned long flash; > unsigned int sr; > > FCTL3 = FWKEY; // Clear Lock bit > while (FCTL3 & BUSY) ; > FCTL1 = FWKEY + MERAS; // Set MERAS bit > > __asm__ __volatile__ ("mov r2,%0":"=r"(sr):); // save SR before disabling IRQ > __dint(); > __asm__ __volatile__ ("movx.a %1,%0":"=r"(flash):"m"(flash_addr)); // > move 20 bit flash address from variable to a register > __asm__ __volatile__ ("clrx @%0"::"r"(flash)); // dummy write 0 (or > clrx) to the address contained in the register > __asm__ __volatile__ ("mov %0,r2"::"r"(sr)); // restore previous SR > and IRQ state > __eint(); > > while (FCTL3 & BUSY) ; // test busy > FCTL1 = FWKEY; // Clear MERAS bit > FCTL3 = FWKEY + LOCK; // Set LOCK bit > --stop-- > > This code does not work, I've been struggling with it for a couple of > hours and still miss what is wrong. > Disassembly looks like this: > > --start-- > unsigned long flash_addr = 0x1c400; > 4458: b4 40 00 c4 mov #-15360,-10(r4) ;#0xc400, 0xfff6(r4) > 445c: f6 ff > 445e: 94 43 f8 ff mov #1, -8(r4) ;r3 As==01, 0xfff8(r4) > unsigned long flash; > unsigned int sr; > > FCTL3 = FWKEY; // Clear Lock bit > 4462: b2 40 00 a5 mov #-23296,&0x0144 ;#0xa500 > 4466: 44 01 > while (FCTL3 & BUSY) ; > 4468: 03 43 nop > 446a: 1f 42 44 01 mov &0x0144,r15 > 446e: 1f f3 and #1, r15 ;r3 As==01 > 4470: 4f 4f mov.b r15, r15 > 4472: 4f 93 tst.b r15 > 4474: fa 23 jnz $-10 ;abs 0x446a > FCTL1 = FWKEY + MERAS; // Set MERAS bit > 4476: b2 40 04 a5 mov #-23292,&0x0140 ;#0xa504 > 447a: 40 01 > > __asm__ __volatile__ ("mov r2,%0":"=r"(sr):); // save SR before disabling IRQ > 447c: 0b 42 mov r2, r11 > 447e: 84 4b f0 ff mov r11, -16(r4) ;0xfff0(r4) > __dint(); > 4482: 32 c2 dint > 4484: 03 43 nop > __asm__ __volatile__ ("movx.a %1,%0":"=r"(flash):"m"(flash_addr)); // > mov 20-bit flash address from variable to a reg > 4486: 80 1f 5a 44 movx.a -10(r4),r10 ;0xffff6(r4) > 448a: f6 ff > 448c: 84 4a f2 ff mov r10, -14(r4) ;0xfff2(r4) > 4490: 84 4b f4 ff mov r11, -12(r4) ;0xfff4(r4) > __asm__ __volatile__ ("clrx @%0"::"r"(flash)); // dummy write 0 (or > clrx) to the address contained in the reg > 4494: 1e 44 f2 ff mov -14(r4),r14 ;0xfff2(r4) > 4498: 1f 44 f4 ff mov -12(r4),r15 ;0xfff4(r4) > 449c: 40 18 8e 43 clrx 0(r14) ;0x00000(r14) > --stop-- > > The address 0x1c400 is properly stored on the stack in -10(r4) (4458 > and 445e). Then at 4486 it is mov'ed to r10, which is ok. > What happens in 448c and 4490? What is expected at -14(r4) and why is > the SR used in 4490 (mov'ed to r11 in 447c)? There is no C code > accompanying it. > > I guess this is the problem as I can see in 448c and 4490 some strange > data to be written to the stack and when the clrx is called at 449c it > uses an indexed r14 with an offset of 0. I made a big mess :-) > Where is the issue in my code? > > Using > __asm__ __volatile__ ("movx #0,&0x1c400"); > works correctly, my goal was to make this address stored in a variable. > > Thanks in advance for a hint! > > Best Regards, > Tomek > > ------------------------------------------------------------------------------ > "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE > Instantly run your Selenium tests across 300+ browser/OS combos. Get > unparalleled scalability from the best Selenium testing platform available. > Simple to use. Nothing to install. Get started now for free." > http://p.sf.net/sfu/SauceLabs > _______________________________________________ > Mspgcc-users mailing list > Mspgcc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mspgcc-users ------------------------------------------------------------------------------ "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available. Simple to use. Nothing to install. Get started now for free." http://p.sf.net/sfu/SauceLabs _______________________________________________ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users