Hi Robert,
> I understand that it is not possible (supported) to use the full flash
> memory for a program.
> But is it possible to store date in the higher flash memory of the
> MSP430F5438?
I had a similar problem.
My approach was to write some functions for byte-wise read access to the memory
above 64k. The functions consist of hand-crafted assembler code (refer to the
msp430 user's guide for details of the opcode).
Writing can be done by combining page-wise erase and byte-wise write actions.
Attached you find the assembler code, that I used to accomplish this.
For write access, you will need to set the specific msp430 registers before
calling "set_memory_byte".
I am quite sure, that my approach is not the best way to solve this problem.
Thus I would appreciate any comments!
greetings,
Lars
inline char get_memory_byte(const long destination) {
/* access to the upper memory (>64k) must be done via "raw" opcodes.
* msp430-gas does not know about the 20bit opcodes.
* We do the following steps:
* (1) copy the address (20bit) of "destination" (@SP) to r15
* (2) copy the content of the memory, that r15 refers to (above 64k) to result
* (3) return "result"
* See msp430 user's guide for the description of the opcodes:
* - chapter 3.4
* - chapter 4.5
* This procedure uses "result" for storing the return value. This allows
* us to use a plain C directive ("return result;") for returning
* the result. Otherwise gcc would emit noisy warnings about
* "not returning a value" in a non-void function.
*/
volatile char result;
// mova r4,r15
asm(".word 0x040F");
// mov.b @r15,@r4
asm(".word 0x4FE4"); asm(".word 0x0004");
return result;
}
inline unsigned int get_memory_word(const long destination) {
// see "get_memory_byte" for a detailed explaination of the following code
// we don't use "mov.w" (word-move), as this would require special handling for non-
even addresses
volatile unsigned int result;
// mova r4,r15
asm(".word 0x040F");
// mov.b @r15+,@r4 (indirect autoincrement mode for src register)
asm(".word 0x4FF4"); asm(".word 0x0004");
// mov.b @r15,@r4
asm(".word 0x4FE4"); asm(".word 0x0005");
return result;
}
// read a 32 bit value from high memory
inline unsigned long get_memory_dword(const long destination) {
// see "get_memory_byte" for a detailed explaination of the following code
volatile unsigned long result;
// mova r4,r15
asm(".word 0x040F");
// mov.b @r15+,@r4 (indirect autoincrement mode for src register)
asm(".word 0x4FF4"); asm(".word 0x0004");
asm(".word 0x4FF4"); asm(".word 0x0005");
asm(".word 0x4FF4"); asm(".word 0x0006");
// mov.b @r15,@r4
asm(".word 0x4FE4"); asm(".word 0x0007");
return result;
}
void set_memory_byte(const long destination, const char input) {
/* msp430-gcc does not support 20bit address access. Thus we have to do it
* on our own.
* (1) copy the (20bit) address from "destination" to r15
* (2) copy the content of "input" as a byte to the destination of r15
*
* BEWARE: in case something fails, this is quite likely caused by the
* hard-coded memory locations below.
*/
// mova 0(r4),r15 "0(r4)" is the address of "destination"
asm(".word 0x043F"); asm(".word 0x0000");
// mov.b 4(r4),@r15 "4(r4)" is the address of "input"
asm("mov.b 4(r4),@r15");
}