Hi
I am trying to make a routine for updating my firmware without using ISP. So fare I am downloading my firmware to a free location in FLASH and I am now trying to copy this firmware to the first part of the FLASH memory. I am aware that to do this, the function copying the firmware cannot also be in the FLASH section being written to, so I am trying to place this function in RAM using __RAMFUNC. I have attached the code for my function below. However, I am experiencing that the execution is halted after executing the "Erase sectors" IAP command. So it seems to me that the code is not executed from RAM. Anyone have any idea of what I am doing wrong? (I am using LPC1549)
__RAMFUNC(RAM2) void flashing(uint8_t sectors)
{
unsigned int command[5]; // Command
unsigned int result[4]; // Result
typedef void (*IAP)(unsigned int[], unsigned int[]); // IAP Pointer
IAP iap_Entry = (IAP) IAP_LOCATION;
uint8_t ret_code,i;
uint16_t ii;
uint8_t data[1024];
/* Disable interrupt mode */
__disable_irq();
/* Prepare to write/erase the sector */
command[0] = IAP_PREWRRITE_CMD;
command[1] = 0; // strSector
command[2] = sectors; // endSector
iap_entry(command, result);
/* Erase Sectors */
command[0] = IAP_ERSSECTOR_CMD;
command[1] = 0; //strSector;
command[2] = sectors; //endSector;
command[3] = SystemCoreClock / 1000;
iap_entry(command, result);
/* Copy 1024 bytes at a time. Sectors = number of sectors to copy */
for(i=0;i<sectors*4;i++)
{
for(ii=0; ii<1024;ii++)
{
/* First read date to RAM before writing to FLASH */
data[ii] = *(uint8_t*)(START_ADDR_SECTOR+i*1024+ii);
}
/* Prepare sector for write */
command[0] = IAP_PREWRRITE_CMD;
command[1] = 0; // strSector
command[2] = sectors; // endSector
iap_entry(command, result);
/* Write to FLASH */
command[0] = IAP_WRISECTOR_CMD;
command[1] = i*1024;
command[2] = (uint32_t) &data;
command[3] = 1024;
command[4] = SystemCoreClock / 1000;
iap_entry(command, result);
}
NVIC_SystemReset(); //#TODO
}
Solved! Go to Solution.
Finally, I managed to get it working. Thank you all for guiding me to the solution.
I found that you don't have to move the vector table, but doing so helped me to find out what was wrong. I moved the vector table by copying the first sector to the last sector and then changed VTOR. I then found that my program ended up in the Hard Fault handler. Before moving the vector table the pointer to the Hard Fault handle would have been erased, but now I could investigate what had happened by looking at the vectpc register. I found that my program counter had tried to execute a line in sector 0 that I had erased. The guilty function was iap_entry. I found that the program was calling iap_entry in romapi_15xx.h and not iap_Entry that I had declared. I was not aware that there existed a function with almost the same name as I had used. This function was of course erased when I erased the sector and hence the error. Changing the name of my declaration in RAM and updating the function calls to the new name solved my problem.
Hey Terje,
Just so you know, I just tried my suggestion and it did not work for me. I got to my office a few hours ago.. I am having the exact same problem it seems, if i figure it our I will reply with my fix.
As for the problem with the erase. I found that sending the REINVOKE ISP command before PREPARE SECTOR and ERASE SECTOR and then performing a reset is necessary for me to be able to write to flash. Might be worth a try.
Best of luck,
Peter
Thanks for your update Peter. Too bad the solution did not work. I will look into this when I get back to the office on Thursday. Please let me know if you find a solution.
Terje
How about checking the return code from each IAP call to find out what the error reported?
I have done that. There are no errors from the IAP calls. I have also tried to run this function and copy the data to free sections of the FLASH memory and that works fine. I therefore do not expect the problem to be the IAP calls, but that my code is not executed from RAM even though I am using __RAMFUNC. But I don't know so any ideas would be highly appreciated.