I am using the NVMwrite function that is in the firmware of a your demoboard to write data in flash memory on a custom board. I see that sometimes when I add new instructions or variables to the firmware, the data are not written in the flash memory anymore. Then I add new instructions or variable and the writing restart to work. The problem is that I don't know what is the condition that makes the writing instruction work or not.
The instructions or variables that I add are not related to the functioning of the writing function. Maybe is a matter of size, but I can't understand exactly the size of what and its value.
Hi kerryzhou,
I'm working on LPC1114F/302 Flash Read and Write. when I give an input to the switch The following function works giving result SUCCESSFULL.
if(coil_address_data[20]==1) //Switch input
{
u32IAP_PrepareSectors(0x6,0x6);
u32IAP_CopyRAMToFlash(0x6000,(uint32_t)RAM_Data,1024);
coil_address_data[20]=0;}
But while debugging value is not loaded to Flash address.
Thanks and Regards
Athmesh Nandakumar
Hi Valerio Caputo,
What the chip you are using?
When the problem happens, you can debug it, what the flash address the firmware want to write, and check that flash address, whether that flash address is erased before. As you know, when the customer want to write the flash, the according flash address must have been erased, and don't have any other data, otherwise , the flash write will be failed.
Wish it helps you!
If you still have question, please contact me!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello
I did the debug and I found that the data are always written in the
memory. So the problem is that data are not read when there is the
problem. But I don't know why it stops reading the data sometimes that I
add instructions or variables (for example, one time that the program
stopped to read data, I added 9 variables with size of one byte, and the
program restarted to work in the right way). Is there some size of the
code that must be respected (for example, it must be multiple of some
value)?
Il 03/01/2017 06:04, kerryzhou ha scritto:
>
NXP Community
<https://community.freescale.com/resources/statics/1000/35400-NXP-Community-Email-banner-600x75.jpg>
>
Re: IAP flash writing problem
reply from Kerry Zhou
<https://community.nxp.com/people/kerryzhou?et=watches.email.thread>
in /LPC/ - View the full discussion
<https://community.nxp.com/message/864708?commentID=864708&et=watches.email.thread#comment-864708>
>
Hi Valerio Caputo,
You still didn't tell us what the chip you are using.
Your code stop to read the flash address, I think you still need to check your code, when the problem happens, why it can't read. You refer to what item to read it? Length? If yes, please check the length is correct or not.
Please debug the code, and do more testing, and check your code, I think this is the code logic bug.
Wish it helps you!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
The chip is LPC1114FBD48-302.
I have made debug of the code, and the only difference between the code
that read the data and the one that doesn't read, is in the value of
&nvm_storage (there is a difference of 4 between the two cases). But
this is a parameter of the program_flash_sector function inside NVMwrite
function (that works), so it should not be the cause of the problem. All
the other variable of the NVMread function have the same values in both
cases.
In the code, the only difference between the two codes is a call to a
function (in a code it is called, in the other one not). That function
surely has nothing to do with flash memory. It seems that when I add new
instructions or variables, the program stops to read data. Then, I add
again new instructions or variables and it begins to read data again. So
far, it happens in a casual way for me (it already happened more than
one time during the writing of the code), I can't understand the reason
it happens. I thought for example, the number of data bytes stored must
be multiple of some value? I need to reserve some bytes for IAP commands?
I can't really find a solution.
Thank you again
Best regards
Il 03/01/2017 09:20, kerryzhou ha scritto:
>
NXP Community
<https://community.freescale.com/resources/statics/1000/35400-NXP-Community-Email-banner-600x75.jpg>
>
Re: IAP flash writing problem
reply from Kerry Zhou
<https://community.nxp.com/people/kerryzhou?et=watches.email.thread>
in /LPC/ - View the full discussion
<https://community.nxp.com/message/864834?commentID=864834&et=watches.email.thread#comment-864834>
>
Hi Valerio caputo,
Could you post some codes about your problem, it may help me to understand your question.
About the IAP program, please refer to the LPC1114 user manual, check the IAP commands, especial about the command description.
When you do the IAP erase/write operations, please disable the interrupts or ensure that the user interrupt vectors are active in RAM and that the interrupt handlers reside in RAM.
Because the on-chip flash memory is not accessible during erase/write operations.
About the question: the number of data bytes stored must be multiple of some value?
When you do the data store, please check the IAP function input param0, whether it is meet the user manual demand.Some input address and lenght have limit.
Besides, when you build the code, please modify your project optionmization level to lowest, it it better to none, just to make sure your problem is not caused by the high optimization.
Wish it helps you!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
This is the content of the file in which there are the funtions of
reading and writing:
#define CUR_BLOCK_SIZE 256
#define FLASH_SECTOR_FOR_DATA 7 // Highest Flash sector
number in LPC1114
#define START_OF_FLASH_SECTOR 0x00007000 // Start address of
FLASH_SECTOR_FOR_DATA
#define END_OF_FLASH_SECTOR 0x00008000 // End address of
FLASH_SECTOR_FOR_DATA
#define IAP_FLASH_CMD_PREPARE_SECTOR 50
#define IAP_FLASH_CMD_COPY_RAM2FLASH 51
#define IAP_FLASH_CMD_ERASE_SECTOR 52
#define IAP_LOCATION 0x1FFF1FF1
typedef void (*IAP)(unsigned int *pcommand, unsigned int *presult);
typedef struct versiont_
{
uint16_t major;
uint16_t minor;
} version_t;
typedef struct nvmlayout_t_
{
version_t version;
uint8_t data[CUR_BLOCK_SIZE - sizeof(version_t)];
} nvm_layout_t;
/*******************************************************************************
Local data
******************************************************************************/
nvm_layout_t nvm_storage; //static
/*******************************************************************************
Local functions
******************************************************************************/
static void erase_flash_sector(void)
{
uint32_t command[5];
uint32_t result[4];
IAP iap_entry = (IAP)IAP_LOCATION;
__disable_irq();
command[0] = IAP_FLASH_CMD_PREPARE_SECTOR;
command[1] = FLASH_SECTOR_FOR_DATA;
command[2] = FLASH_SECTOR_FOR_DATA; // Only 1 sector, so end
sector # is start sector #
iap_entry(command, result);
if (result[0] == 0)
{
command[0] = IAP_FLASH_CMD_ERASE_SECTOR;
command[1] = FLASH_SECTOR_FOR_DATA;
command[2] = FLASH_SECTOR_FOR_DATA; // Only 1 sector, so end
sector # is start sector #
command[3] = SystemCoreClock / 1000;
iap_entry(command, result);
}
__enable_irq();
}
static void program_flash_sector(uint32_t * pDest, uint32_t * pSrc,
uint32_t size)
{
uint32_t command[5];
uint32_t result[4];
IAP iap_entry = (IAP)IAP_LOCATION;
__disable_irq();
command[0] = IAP_FLASH_CMD_PREPARE_SECTOR;
command[1] = FLASH_SECTOR_FOR_DATA;
command[2] = FLASH_SECTOR_FOR_DATA; // Only 1 sector, so end
sector # is start sector #
iap_entry(command, result);
if (result[0] == 0)
{
command[0] = IAP_FLASH_CMD_COPY_RAM2FLASH;
command[1] = (uint32_t)pDest;
command[2] = (uint32_t)pSrc;
command[3] = size;
command[4] = SystemCoreClock / 1000;
iap_entry(command, result);
}
__enable_irq();
}
/*******************************************************************************
Exported functions
******************************************************************************/
bool NVM_read(void * pData, uint32_t data_size)
{
bool erase = false;
bool found = false;
uint32_t * fl_ptr;
nvm_layout_t * flash_nvm_ptr;
if (data_size > sizeof(nvm_storage.data))
{
return false;
}
// check if last block in Flash is empty
fl_ptr = (uint32_t *)(END_OF_FLASH_SECTOR - CUR_BLOCK_SIZE);
if (*fl_ptr != 0xFFFFFFFF)
{
// last block in Flash is not empty.
// so the Data storage in Flash is full.
erase = true;
}
// Try to find the most recent data in the NVM Flash sector.
// We search backward (highest address) to the first non empty
block that we
// find, since the NVM Flash sector is filled from the lowest
address upwards.
while (!found && (fl_ptr >= (uint32_t *)START_OF_FLASH_SECTOR))
{
flash_nvm_ptr = (nvm_layout_t *)fl_ptr;
if ((flash_nvm_ptr->version.major ==
MAJOR_FIRMWARE_VERSION_NUMBER) &&
(flash_nvm_ptr->version.minor ==
MINOR_FIRMWARE_VERSION_NUMBER))
{
found = true;
memcpy(pData, &flash_nvm_ptr->data[0], data_size);
}
else
{
fl_ptr -= (CUR_BLOCK_SIZE / sizeof(uint32_t)); // skip to
previous block
}
}
if (erase)
{
// Data storage will be cleaned up now,
// so that there is room in Flash when the next power down
takes place.
erase_flash_sector();
if (found)
{
// write back to Flash the most recent data
NVM_write(pData, data_size);
}
}
return found;
}
void NVM_write(void * pData, uint32_t data_size)
{
bool found = false;
uint32_t * pDest = (uint32_t *)START_OF_FLASH_SECTOR;
if (data_size > sizeof(nvm_storage.data))
{
return;
}
while (!found && (pDest < (uint32_t *)END_OF_FLASH_SECTOR))
{
// check if pDest points to an empty block
if (*pDest == 0xFFFFFFFF)
{
found = true;
}
else
{
pDest += (CUR_BLOCK_SIZE / sizeof(uint32_t)); // skip to
next block
}
}
if (!found)
{
erase_flash_sector();
pDest = (uint32_t *)START_OF_FLASH_SECTOR;
}
nvm_storage.version.major = MAJOR_FIRMWARE_VERSION_NUMBER;
nvm_storage.version.minor = MINOR_FIRMWARE_VERSION_NUMBER;
memcpy(&nvm_storage.data[0], pData, data_size);
program_flash_sector(pDest, (uint32_t *)&nvm_storage, CUR_BLOCK_SIZE);
}
/* End Of File */
Il 05/01/2017 09:38, kerryzhou ha scritto:
>
NXP Community
<https://community.freescale.com/resources/statics/1000/35400-NXP-Community-Email-banner-600x75.jpg>
>
Re: IAP flash writing problem
reply from Kerry Zhou
<https://community.nxp.com/people/kerryzhou?et=watches.email.thread>
in /LPC/ - View the full discussion
<https://community.nxp.com/message/865663?commentID=865663&et=watches.email.thread#comment-865663>
>