ARM Technical Support Knowledge Articles


Applies to: C51 C Compiler


Information in this article applies to:


From my application program, I'm trying to update data stored in Flash. The device (Silicon Labs C8051F320) uses the first MOVX instruction (after unlocking Flash) to store 1 byte to flash memory.

I don't have room in DATA memory for the pointer to the flash address. So, the pointer is stored in XDATA. When I reference this pointer to write to flash, the compiler unlocks the Flash, then uses a MOVX instruction to get the value of the XDATA pointer. And, the Flash write fails. For example, in the following code:

code unsigned char flashmem[9];
code unsigned char fdata[9] = "Test data";

unsigned char xdata * pdestination;
unsigned char code * psource;
  pdestination = (unsigned char xdata *) flashmem;
  psource = (unsigned char code *) fdata[0];
  FLKEY = 0xA5;               // FLASH lock and key seq. 1
  FLKEY = 0xF1;               // FLASH lock and key seq. 2
  PSCTL = 0x01;               // PSWE = 1; PSEE = 0
  *pdestination = *psource;   // Move 1 byte to flash

The *pdestination = *psource; code line generates the following assembly code:

  MOV      DPTR,#psource(0x0000)
  MOVX     A,@DPTR            <-- Reset flash write enable
  MOV      R4,A
  INC      DPTR
  MOVX     A,@DPTR
  MOV      DPL(0x82),A
  MOV      DPH(0x83),R4
  CLR      A
  MOVC     A,@A+DPTR
  MOV      R5,A
  MOV      DPTR,#pdestination(0x0002)
  MOVX     A,@DPTR
  MOV      R2,A
  INC      DPTR
  MOVX     A,@DPTR
  MOV      DPL(0x82),A
  MOV      DPH(0x83),R2
  MOV      A,R5
  MOVX     @DPTR,A             <-- Write to XDATA not flash

The first MOVX instruction is required to get the pointer value from XDATA. But after this the byte is not written to flash. How can I make this work?


There are several ways to accomplish this.

Option 1

Perhaps the best way is to make room in DATA memory for the pointer. Of course, you may not have available memory for this.

Option 2

Another way is to create an assembly routine that performs all the operations in the correct order. You can prototype the function in C and generate the assembly source code using the compiler's SRC directive. Then, fill-in the required assembly routine.

Option 3

Another way to do this is to create a function that unlocks and moves the data into flash using your XDATA pointers as parameters. As long as your function doesn't have more than three parameters, the pointer values are passed in registers. For example, create the following function:

#include <C8051F320.h>
#include <write_flash_byte.h>
void write_flash_byte (
unsigned char code * source,
unsigned char xdata * destination) { bit EA_save; // saves the current interrupt state EA_save = EA; EA = 0; // disable interrupts FLKEY = 0xA5; // FLASH lock and key sequence 1 FLKEY = 0xF1; // FLASH lock and key sequence 2 PSCTL = 0x01; // Sets PSWE bit, Clears PSEE bit *destination = *source; // Move the data to C8051F320 flash PSCTL &= ~0x03; // Clear PSWE so MOVX writes target XRAM EA = EA_save; // re-enable interrupts }

Because the pointers are passed in registers, the *destination = *source; line generates the following assembly code without having to read from XDATA:

C:0x0093    8F82     MOV      DPL(0x82),R7
C:0x0095    8E83     MOV      DPH(0x83),R6
C:0x0097    E4       CLR      A
C:0x0098    93       MOVC     A,@A+DPTR
C:0x0099    8D82     MOV      DPL(0x82),R5
C:0x009B    8C83     MOV      DPH(0x83),R4
C:0x009D    F0       MOVX     @DPTR,A    <-- Write to flash

For instruction-sensitive operations such as this, you should consider Option 2 and create a separate assembly language function and module you can call from your C code. You may use the SRC directive with the above C function to get started.



Article last edited on: 2005-07-22 15:22:23

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential