This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2000 IAP, programed data in flash are not consistent with data in RAM buffer.

Hi, Folks,

Hopefully, someone can shed some light to this. Thanks.

I am using the LPC2000 IAP functions to put user data in to flash, but I got a weird problem. My target MCU is a LPC2214 and debugger is the Keil uvision 3.05 + ULink2. I have a MSB2100 evaluation board but it's broken, so I cannot test this on it.

The following is the test program. For each user, I read the 512 bytes block the user should be in to a RAM buffer, update the user data and then program the buffer back in.

The problem is the programed data are often not consistent with the data in the RAM buffer. I programmed 8000 users, usually this will happen more then 1000 times. The following example is one of them. The user number 7 was wrong, and this happened when user 8 was programmed. I had erased this section before I ran this function and checked all data in the section were 0xFF. In the whole process, the IAP functions return 0 (CMD_SUCCESS)

d 0x10000
0x00010000 01 00 00 00 10 FF FF FF
0x00010008 02 00 00 00 10 FF FF FF
0x00010010 03 00 00 00 10 FF FF FF
0x00010018 04 00 00 00 10 FF FF FF
0x00010020 05 00 00 00 10 FF FF FF
0x00010028 06 00 00 00 10 FF FF FF
0x00010030 07 00 02 00 10 FF FF FF
0x00010038 08 00 00 00 10 FF FF FF
0x00010040 FF FF FF FF FF FF FF FF
0x00010048 FF FF FF FF FF FF FF FF
.......ALL oxFF

d flash_buffer
0x4000021C 01 00 00 00 10 FF FF FF
0x40000224 02 00 00 00 10 FF FF FF
0x4000022C 03 00 00 00 10 FF FF FF
0x40000234 04 00 00 00 10 FF FF FF
0x4000023C 05 00 00 00 10 FF FF FF
0x40000244 06 00 00 00 10 FF FF FF
0x4000024C 07 00 00 00 10 FF FF FF
0x40000254 08 00 00 00 10 FF FF FF
0x4000025C FF FF FF FF FF FF FF FF
0x00000264 FF FF FF FF FF FF FF FF
.......ALL oxFF

//////////////my test program//////////////
typedef struct
{
        unsigned long   id;
        BYTE    zone;
} USER_DATA;

unsigned char flash_buffer[512];

//the start address of users in flash (64k block)
USER_DATA *user = (USER_DATA *)0x10000;
unsigned long blockerrors = 0;
unsigned long singleerrors = 0;

void test_user()
{
  unsigned long i;
  unsigned char *program_addr;
  USER_DATA temp_user;

  for(i = 1; i <= 8000, i++)
  {
    //get the 512 bytes block base address the current user is in.
        program_addr =(BYTE*)((unsigned int)(&user[i]) & 0xFFFFFE00);

        //update the user in the buffer.
        memcpy((void*)flash_buffer, (void*)program_addr, 512);
        temp_user = (USER_DATA*)(flash_buffer + (((BYTE*)(user + i)) - program_addr));
        temp_user->id = i;
        temp_user->zone = 16;

    //program the flsh
        FlashProgram((uint)program_addr, flash_buffer, 512);

        if(memcmp(flash_buffer, program_addr, 512)) //check block programming errors
                  ++blockerrors;

          if(i != user[i].id) //
                  ++singleerrors;

                DELAY(100); //delay 100 millisends
  }
}

#define XTAL_HZ    10000000                   // Oscillator Frequency in HZ
#define PLL_MUL 6
#define VPB_DIVIDER 4              // VPB Clock divider
#define CPU_CLK_HZ (XTAL_HZ*PLL_MUL)                    // CPU Clock (cclk) in HZ

#define CPU_CLK_KHZ   (CPU_CLK_HZ / 1000)          // CPU Clock (cclk) in kHz

#define VPB_CLK_HZ   (CPU_CLK_HZ / VPB_DIVIDER)              // VPB Clock (pclk) in Hz


struct iap_in {
  uint cmd;
  uint par[4];
};

typedef void (*IAP)(struct iap_in *in, uint *result);
#define IapEntry ((IAP) 0x7FFFFFF1)       // IAP Entry Point

uint FlashProgram (uint addr, uchar *data, uint size)
{
        struct iap_in iap;                       // IAP Input Parameters
        uint  result[16];                // IAP Results

        assert(FlashGetSecNum (addr) >= 8);

        di();                                    // disable all interrupts


        iap.cmd = 50;                            // IAP Command: Prepare Sectors for Write
        iap.par[0] = FlashGetSecNum (addr);         // Start Sector
        iap.par[1] = iap.par[0];                 // End Sector
        IapEntry (&iap, result);                // Call IAP Function
        if (result[0])
                goto exit;                // Error occured?

        iap.cmd = 51;                            // IAP Command: Copy RAM to Flash
        iap.par[0] = addr;                       // Destination Address
        iap.par[1] = (uint) data;        // Source Address
        iap.par[2] = size;                       // Number of Bytes
        iap.par[3] = CPU_CLK_KHZ;                       // CPU Clock
        IapEntry (&iap, result);                // Call IAP Function

exit:
        ei();                                    // enable all interrupts
        return (result[0]);
}

0