Looks like my code, except that in its current incarnation, I have declared the
function "extern inline __attribute__((always_inline))".
Makes it significantly faster than a real function call. And often allows for
better optimization.
And I used plain int and not uintxx_t types.
For a word read, simply make result uint16_t and replace the movx.b by a movx.w.
A dword read may be more complex. I didn't check whether a mov @rx, 0(ry) does
a real 32 bit transfer or only 20 bit.
My current implementation does 2*16 bit transfers and might be overly complex,
so I won't post it.
However, writing is more compicated:
// may not be called from within ISR, as it takes ~48ms per segment
// segment 0 starts @ 0x10000. This function does NOT write below 64k.
int FlashWriteSegmentHigh (unsigned int segment, const unsigned int * source,
unsigned int size){
unsigned long i,j;
unsigned int * flash;
unsigned int register sr;
i=segment +128;
i<<=9;
j=i+((unsigned long)size<<9);
FCTL3=FWKEY;
// clear lock bit
while(i<j){
// erase segment
__asm__ __volatile__ ("mov r2 , %0 \n":"=r"(sr));
// save old interrup tstate
_DINT();
// block IRQs
FCTL1=FWKEY|SEGERASE;
// segment erase mode
__asm__ __volatile__ ("movx.a %1,%0":"=r"(flash):"m"(i));
// 'm' type to ensure 20 bit load
__asm__ __volatile__ ("movx #llo(0), @%0 "::"r"(flash));
while(FCTL3&BUSY);
// wait for erase complete
FCTL1=FWKEY;
// segment erase mode off
__asm__ __volatile__ ("mov %0 , r2 \n"::"r"(sr));
// allow IRQs, if enabled before, so an ISR has a chance. (32ms have passed)
_NOP();
// give time for some interrupts
_NOP();
// give time for some interrupts
do{
_DINT();
_NOP();
// ensure INTs are disabled
FCTL1=FWKEY|LWWRITE;
__asm__ __volatile__ ("movx.a %1, %0":"=r"(flash):"m"(i));
__asm__ __volatile__ ("movx %0, @%1"::"m"(*source),"r"(flash));
__asm__ __volatile__ ("incd %0":"=r"(source):"0"(source));
__asm__ __volatile__ ("incda %0":"=r"(flash):"0"(flash));
__asm__ __volatile__ ("movx %0, @%1"::"m"(*source),"r"(flash));
__asm__ __volatile__ ("incd %0":"=r"(source):"0"(source));
__asm__ __volatile__ ("addx.a #llo(4), %0":"=m"(i):"m"(i));
while(FCTL3&BUSY);
// wait for write complete
FCTL1=FWKEY;
__asm__ __volatile__ ("mov %0 , r2 \n"::"r"(sr));
// allow IRQs, if enabled before, so an ISR has a chance.
} while (i&0x1ff);
}
FCTL3=FWKEY|LOCK;
// set lock bit again
return size;
}
My unified FlashWriteData function which writes any size on any place is not
finished (I stopped working on this some time
ago when I was assigned to software development, and MSP work was reduced to
bugfixing).
Doing such a function 'right' includes taking a backup of partially written,
non-empty segments, different sized segments, handling of area overlap etc.
For a full sector read, you can use the following function. It has not been
fully tested but should work:
void __attribute__ ((naked)) FlashReadData (unsigned long address, unsigned int
* dest, unsigned int size){
// R14/R15 = address, R12 = size, R13 = dest
__asm__ __volatile__ ("add #1, r12 \n"
" bic #1, r12 \n"
// ensure an even number of bytes (round up)
" tst r12 \n"
" jnz LP1 \n"
// at least one word to read
" ret \n"
" LP1: \n"
" push r2 \n"
" dint \n"
// disable interrupts (IRQs will clobber address bits 16..19)
" and #15, r15 \n"
" swpb r15 \n"
" rlam #4, r15 \n"
" rlam.a #4, r15 \n"
// shift bit 16..19 of address into R15 bit 16..19
" add #1, r14 \n"
// make it an even address
" bic #1, r14 \n"
" addx.a r14, r15 \n"
// move bit 0..15 of address into bit 0..15 of R15
"LP2: \n"
" movx @r15, @r13 \n"
" incd r13 \n"
" incda r15 \n"
" decd r12 \n"
" jnz LP2 \n"
" pop r2 \n"
// restore old interrupt state
" ret "
::);
}
----- Ursprüngliche Nachricht -----
Von: Matthias Ringwald
An: [email protected]
Gesendet am: 06 Aug 2011 10:30:24
Betreff: Re: [Mspgcc-users] How to access 20 bit peripheral registers...
Hi Alex
The MSP430s I've seen only have 16kB of RAM in the first 64kB, and of course
you cannot just write to flash with a
simple "mov".
However, the TI sample code for the MSP430x5438 Experimenter board has an
example of recoding audio to flash.
You may have a look there although their code uses IAR which supports 20 bit
addresses in general.
Here's a working FlashReadByte(), which somebody on this list showed me a some
time before.
Best
Matthias
uint8_t FlashReadByte (uint32_t addr){
uint8_t result;
uint32_t register sr, flash;
__asm__ __volatile__ (
"mov r2 , %1 \n"
"bic %3 , r2 \n"
"nop \n"
"movx.a %4 , %2 \n"
"movx.b @%2, %0 \n"
"mov %1 , r2 \n"
:"=X"(result),"=r"(sr),"=r"(flash)
:"i"(GIE),"m"(addr));
return result;
}
On 05.08.2011, at 23:39, Alex Stefan wrote:
> Does anybody have some example routines for reading/writing to high addresses
> in
> the flash?
>
> This is what I've written so far, but it's far from a working version:
>
> static inline __attribute__((always_inline)) void
> flash_write_byte(uint32_t addr, uint8_t val)
> {
>
> __asm__ __volatile__ (
> "dint \n"
> "nop \n"
> "mova %[addr], r15 \n"
> "movx %[val], @r15 \n"
> "eint \n"
> :
> :[addr] "r"(addr), [val] "m"(val)
> );
> }
> static inline __attribute__((always_inline)) uint8_t
> flash_read_byte(uint32_t addr)
> {
>
> uint8_t result;
> __asm__ __volatile__ (
> "dint \n"
> "nop \n"
> "mova %[addr], r15 \n"
> "movx @r15, %[result] \n"
> "eint \n"
> :[result] "=m"(result)
> :[addr] "r"(addr)
> );
> return result;
> }
>
> The problem, from what I could tell, comes from the inlining of the functions
> and the way the compiler generates their prologue. It would help me very much
> if
> I had fully working example to start from.
>
> Alex
>
>
> ------------------------------------------------------------------------------
> BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
> The must-attend event for mobile developers. Connect with experts.
> Get tools for creating Super Apps. See the latest technologies.
> Sessions, hands-on labs, demos & much more. Register early & save!
> http://p.sf.net/sfu/rim-blackberry-1
> _______________________________________________
> Mspgcc-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
Mspgcc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
------------------------------------------------------------------------------
BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts.
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
Mspgcc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users