Problem reading Flash memory (W7500p)

Hi all,

I am facing a problem regarding the flash memory. With the following code, I can write the data and read it. However, if I disable DO_IAP(IAP_ERAS_DAT0,0,0,0) and DO_IAP(IAP_PROG,DAT0_START_ADDR,save_buff,SECT_SIZE) and try to read the data that I wrote previously, I will get strange results (no consistent values). This code is based on the IAP_EXAMPLE, in the library. What am I doing wrong?


#include "W7500x.h"
#include "mbed.h"

#define IAP_ENTRY           0x1FFF1001            
#define IAP_ERAS            0x010
#define IAP_ERAS_DAT0       (IAP_ERAS + 0)
#define IAP_ERAS_SECT       (IAP_ERAS + 2)              
#define IAP_ERAS_BLCK       (IAP_ERAS + 3)  
#define IAP_ERAS_CHIP       (IAP_ERAS + 4)  
#define IAP_ERAS_MASS       (IAP_ERAS + 5)  
#define IAP_PROG            0x022
#define DAT0_START_ADDR     0x0003FE00
#define BLOCK_SIZE          4096
#define SECT_SIZE           256


struct data{
    char something1[5];
    int something2;
    } test;

void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size);

int main()
{ 
    strcpy(&test.something1[0] ,"abcd");
    test.something2 = 1000;
    uint8_t save_buff[BLOCK_SIZE];
    memcpy(save_buff, (const char*)&test, sizeof(data) );
    
    DO_IAP(IAP_ERAS_DAT0,0,0,0);
    DO_IAP(IAP_PROG,DAT0_START_ADDR,save_buff,SECT_SIZE);
    
    uint8_t data_save[BLOCK_SIZE];
    memcpy(data_save,(uint8_t *)(DAT0_START_ADDR),sizeof(data));
    data *p = (data*)data_save;
    printf("Something1: %s, Something2: %d \r\n",p->something1, p->something2);

    }


void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size)
{
    uint32_t temp_interrupt;

    // Backup Interrupt Set Pending Register
    temp_interrupt = (NVIC->ISPR[0]);
    (NVIC->ISPR[0]) = (uint32_t)0xFFFFFFFF;
    
    // Call IAP Function
    ((void(*)(uint32_t,uint32_t,uint8_t*,uint32_t))IAP_ENTRY)( id,dst_addr,src_addr,size);

    // Restore Interrupt Set Pending Register
    (NVIC->ISPR[0]) = temp_interrupt;
}

Thanks!

Hi, danielski.

To give you a detailed answer, I need some more information, such as the board name and version you are using.

Anyway, I tested your code.
Looking at mbed.h, I thought that it was written in the mbed environment, and I proceeded with the mbed compiler.
Is that right?

Here, I have an answer.
In your code, there is no initialization for Serial, how did you check the contents of printf?

Anyway, I attach the code I modified.
I did not include W7500.h and added Serial initialization.

#include "mbed.h"

#define IAP_ENTRY           0x1FFF1001            
#define IAP_ERAS            0x010
#define IAP_ERAS_DAT0       (IAP_ERAS + 0)
#define IAP_ERAS_SECT       (IAP_ERAS + 2)              
#define IAP_ERAS_BLCK       (IAP_ERAS + 3)  
#define IAP_ERAS_CHIP       (IAP_ERAS + 4)  
#define IAP_ERAS_MASS       (IAP_ERAS + 5)  
#define IAP_PROG            0x022
#define DAT0_START_ADDR     0x0003FE00
#define BLOCK_SIZE          4096
#define SECT_SIZE           256


struct data{
    char something1[5];
    int something2;
} test;

void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size);

int main()
{ 
    Serial pc(USBTX,USBRX);
    pc.baud(115200);

    pc.printf("Hello, This is test for IAP\r\n");

    strcpy(&test.something1[0] ,"abcd");
    test.something2 = 1000;
    uint8_t save_buff[BLOCK_SIZE];
    memcpy(save_buff, (const char*)&test, sizeof(data) );
    
    DO_IAP(IAP_ERAS_DAT0,0,0,0);
    DO_IAP(IAP_PROG,DAT0_START_ADDR,save_buff,SECT_SIZE);
    
    uint8_t data_save[BLOCK_SIZE];
    memcpy(data_save,(uint8_t *)(DAT0_START_ADDR),sizeof(data));
    data *p = (data*)data_save;
    pc.printf("Something1: %s, Something2: %d \r\n",p->something1, p->something2);

}


void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size)
{
    uint32_t temp_interrupt;

    // Backup Interrupt Set Pending Register
    temp_interrupt = (NVIC->ISPR[0]);
    (NVIC->ISPR[0]) = (uint32_t)0xFFFFFFFF;
    
    // Call IAP Function
    ((void(*)(uint32_t,uint32_t,uint8_t*,uint32_t))IAP_ENTRY)( id,dst_addr,src_addr,size);

    // Restore Interrupt Set Pending Register
    (NVIC->ISPR[0]) = temp_interrupt;
}

In my case, it worked just as you intended.
(disable DO_IAP(IAP_ERAS_DAT0,0,0,0) and DO_IAP(IAP_PROG,DAT0_START_ADDR,save_buff,SECT_SIZE) and try to read the data that I wrote previously)

Best regard,
Kei