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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users