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

Reply via email to