EmbeddedRelated.com
Forums
Memfault Beyond the Launch

LPC2148 Flash Write Problem

Started by malzki7480 October 10, 2009
Hi!
I have a problem writing to the on chip Flash ROM of LPC2148 in my project. I find it hard to determine the cause of the problem because my Flash write routines are working in the boot loader code as well as in the application code when i send the flash write command from PC program via USB. Let me explain the 3 situations where I have successful (1 and 2) and unsuccessful (3) writing to flash memory.
1) In boot loader code - I reserved at location 0x00000000 to 0x00007FFF including some data like version numbers, etc which I save from address 0x00007000 to 0x00007FFF). During startup, i read the version of my boot loader (located at address 0x00007042) and if it is blank or is not the latest, it will update by writing the latest version number to this address. I have no problem using my flash routines in this way.

2) In application code - which starts from 0x00008000 to 0x00034000 (i define the length of the application code to be 0x0002C000. My application code is updateable via USB and I use an application program (done in VB) to do this. Everytime I want to update my LPC2148's application code, I send a command from USB to write some data in the flash memory (from 0x00007FFC to 0x00007FFF). I also have no problem writing the flash memory in this way. I understand that the flash write happens during an USB interrupt routine like this:

BOOL HID_SetReport (void) {

/* ReportID = SetupPacket.wValue.WB.L; */
switch (SetupPacket.wValue.WB.H) {
case HID_REPORT_INPUT:
return (FALSE); /* Not Supported */
case HID_REPORT_OUTPUT:
{ unsigned char i;
for(i=0; i OutReport_PCToScale();
}
break;
case HID_REPORT_FEATURE:
return (FALSE); /* Not Supported */
}
return (TRUE);
}

where the call to flash writing of data is inside the function OutReport_PCToScale();

3) In application code - There are some data and settings that I want to store in the flash ROM like serial number, date of application code update, etc and I have the correct functions to do this as well as the call to write the data to flash memory. But everytime my function executes the call to flash write (which is same as the flash write code I used in #2), my system restarts (do startup routines and load again). I have keys or buttons to execute the functions as well as LCD to view the results. The thing is I even copied the same function and data that I have in #2 but the result is same (system restart).

I hope somebody can help me with my problem.
Thank you.
Regards,
Marilou

An Engineer's Guide to the LPC2100 Series

> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of malzki7480
> Sent: Friday, October 09, 2009 9:36 PM
> To: l...
> Subject: [lpc2000] LPC2148 Flash Write Problem
> Hi!
> I have a problem writing to the on chip Flash ROM of LPC2148
> in my project. I find it hard to determine the cause of the
> problem because my Flash write routines are working in the
> boot loader code as well as in the application code when i
> send the flash write command from PC program via USB. Let me
> explain the 3 situations where I have successful (1 and 2)
> and unsuccessful (3) writing to flash memory.
> 1) In boot loader code - I reserved at location 0x00000000 to
> 0x00007FFF including some data like version numbers, etc
> which I save from address 0x00007000 to 0x00007FFF). During
> startup, i read the version of my boot loader (located at
> address 0x00007042) and if it is blank or is not the latest,
> it will update by writing the latest version number to this
> address. I have no problem using my flash routines in this way.
>
> 2) In application code - which starts from 0x00008000 to
> 0x00034000 (i define the length of the application code to be
> 0x0002C000. My application code is updateable via USB and I
> use an application program (done in VB) to do this. Everytime
> I want to update my LPC2148's application code, I send a
> command from USB to write some data in the flash memory (from
> 0x00007FFC to 0x00007FFF). I also have no problem writing the
> flash memory in this way. I understand that the flash write
> happens during an USB interrupt routine like this:
>
> BOOL HID_SetReport (void) {
>
> /* ReportID = SetupPacket.wValue.WB.L; */
> switch (SetupPacket.wValue.WB.H) {
> case HID_REPORT_INPUT:
> return (FALSE); /* Not Supported */
> case HID_REPORT_OUTPUT:
> { unsigned char i;
> for(i=0; i > OutReport_PCToScale();
> }
> break;
> case HID_REPORT_FEATURE:
> return (FALSE); /* Not Supported */
> }
> return (TRUE);
> }
>
> where the call to flash writing of data is inside the
> function OutReport_PCToScale();
>
> 3) In application code - There are some data and settings
> that I want to store in the flash ROM like serial number,
> date of application code update, etc and I have the correct
> functions to do this as well as the call to write the data to
> flash memory. But everytime my function executes the call to
> flash write (which is same as the flash write code I used in
> #2), my system restarts (do startup routines and load again).
> I have keys or buttons to execute the functions as well as
> LCD to view the results. The thing is I even copied the same
> function and data that I have in #2 but the result is same
> (system restart).
>
> I hope somebody can help me with my problem.
> Thank you.
> Regards,
> Marilou
>
Do you disable interrupts while writing to flash in the main
application?

Mike

Hi,

it's bit difficult to see where the problem is, but I just wonder that
case #1 and #2 does work.

General rules to write the internal flash are as follows:

1) *all* the routines handling flash writing must be located in RAM -
take care when calling implicit library routines (even a multiply can
call lib-funcs) located in flash
2) when allowing interrupts, interrupt routines have to located in RAM
as well, the vector table must be fetched from RAM then
3) I *never* would call a flash writing routine out of an interrupt
(!!!), do this from the main program only
4) watchdog must be disabled (or set to a appropriate long period) when
writing flash

Herbert

malzki7480 schrieb:
> Hi!
> I have a problem writing to the on chip Flash ROM of LPC2148 in my project. I find it hard to determine the cause of the problem because my Flash write routines are working in the boot loader code as well as in the application code when i send the flash write command from PC program via USB. Let me explain the 3 situations where I have successful (1 and 2) and unsuccessful (3) writing to flash memory.
> 1) In boot loader code - I reserved at location 0x00000000 to 0x00007FFF including some data like version numbers, etc which I save from address 0x00007000 to 0x00007FFF). During startup, i read the version of my boot loader (located at address 0x00007042) and if it is blank or is not the latest, it will update by writing the latest version number to this address. I have no problem using my flash routines in this way.
>
> 2) In application code - which starts from 0x00008000 to 0x00034000 (i define the length of the application code to be 0x0002C000. My application code is updateable via USB and I use an application program (done in VB) to do this. Everytime I want to update my LPC2148's application code, I send a command from USB to write some data in the flash memory (from 0x00007FFC to 0x00007FFF). I also have no problem writing the flash memory in this way. I understand that the flash write happens during an USB interrupt routine like this:
>
> BOOL HID_SetReport (void) {
>
> /* ReportID = SetupPacket.wValue.WB.L; */
> switch (SetupPacket.wValue.WB.H) {
> case HID_REPORT_INPUT:
> return (FALSE); /* Not Supported */
> case HID_REPORT_OUTPUT:
> { unsigned char i;
> for(i=0; i > OutReport_PCToScale();
> }
> break;
> case HID_REPORT_FEATURE:
> return (FALSE); /* Not Supported */
> }
> return (TRUE);
> }
>
> where the call to flash writing of data is inside the function OutReport_PCToScale();
>
> 3) In application code - There are some data and settings that I want to store in the flash ROM like serial number, date of application code update, etc and I have the correct functions to do this as well as the call to write the data to flash memory. But everytime my function executes the call to flash write (which is same as the flash write code I used in #2), my system restarts (do startup routines and load again). I have keys or buttons to execute the functions as well as LCD to view the results. The thing is I even copied the same function and data that I have in #2 but the result is same (system restart).
>
> I hope somebody can help me with my problem.
> Thank you.
> Regards,
> Marilou
>
>

As mike says... you should switch off interrupts. Because during IAP flash
writesthe flash (ALL of it, not where you're writting) becomes unavailable
to the processor,
so... if an IRQ happens... the result is undefined instructions...

Miguel Angel Ajo Pelayo
http://www.nbee.es
+34 91 120 1798
+34 636 52 25 69
skype: ajoajoajo
2009/10/10 Michael Anton

> > -----Original Message-----
> > From: l...
> > [mailto:l... ]On Behalf
> > Of malzki7480
> > Sent: Friday, October 09, 2009 9:36 PM
> > To: l...
> > Subject: [lpc2000] LPC2148 Flash Write Problem
> >
> >
> > Hi!
> > I have a problem writing to the on chip Flash ROM of LPC2148
> > in my project. I find it hard to determine the cause of the
> > problem because my Flash write routines are working in the
> > boot loader code as well as in the application code when i
> > send the flash write command from PC program via USB. Let me
> > explain the 3 situations where I have successful (1 and 2)
> > and unsuccessful (3) writing to flash memory.
> > 1) In boot loader code - I reserved at location 0x00000000 to
> > 0x00007FFF including some data like version numbers, etc
> > which I save from address 0x00007000 to 0x00007FFF). During
> > startup, i read the version of my boot loader (located at
> > address 0x00007042) and if it is blank or is not the latest,
> > it will update by writing the latest version number to this
> > address. I have no problem using my flash routines in this way.
> >
> > 2) In application code - which starts from 0x00008000 to
> > 0x00034000 (i define the length of the application code to be
> > 0x0002C000. My application code is updateable via USB and I
> > use an application program (done in VB) to do this. Everytime
> > I want to update my LPC2148's application code, I send a
> > command from USB to write some data in the flash memory (from
> > 0x00007FFC to 0x00007FFF). I also have no problem writing the
> > flash memory in this way. I understand that the flash write
> > happens during an USB interrupt routine like this:
> >
> > BOOL HID_SetReport (void) {
> >
> > /* ReportID = SetupPacket.wValue.WB.L; */
> > switch (SetupPacket.wValue.WB.H) {
> > case HID_REPORT_INPUT:
> > return (FALSE); /* Not Supported */
> > case HID_REPORT_OUTPUT:
> > { unsigned char i;
> > for(i=0; i > > OutReport_PCToScale();
> > }
> > break;
> > case HID_REPORT_FEATURE:
> > return (FALSE); /* Not Supported */
> > }
> > return (TRUE);
> > }
> >
> > where the call to flash writing of data is inside the
> > function OutReport_PCToScale();
> >
> > 3) In application code - There are some data and settings
> > that I want to store in the flash ROM like serial number,
> > date of application code update, etc and I have the correct
> > functions to do this as well as the call to write the data to
> > flash memory. But everytime my function executes the call to
> > flash write (which is same as the flash write code I used in
> > #2), my system restarts (do startup routines and load again).
> > I have keys or buttons to execute the functions as well as
> > LCD to view the results. The thing is I even copied the same
> > function and data that I have in #2 but the result is same
> > (system restart).
> >
> > I hope somebody can help me with my problem.
> > Thank you.
> >
> >
> > Regards,
> > Marilou
> >
> Do you disable interrupts while writing to flash in the main
> application?
>
> Mike
>
>
>


Miguel Angel schrieb:
> As mike says... you should switch off interrupts.
... if the interrupt routine (and any routine called by it) is located
in RAM and the IRQ table is in RAM as well, then you *can* use
interrupts during IAP (this is what I successfully do)

Herbert
> Because during IAP flash
> writesthe flash (ALL of it, not where you're writting) becomes unavailable
> to the processor,
> so... if an IRQ happens... the result is undefined instructions...
>
> -----Original Message-----
>
>>> From: l...
>>> [mailto:l... ]On Behalf
>>> Of malzki7480
>>> Sent: Friday, October 09, 2009 9:36 PM
>>> To: l...
>>> Subject: [lpc2000] LPC2148 Flash Write Problem
>>>
>>>
>>> Hi!
>>> I have a problem writing to the on chip Flash ROM of LPC2148
>>> in my project. I find it hard to determine the cause of the
>>> problem because my Flash write routines are working in the
>>> boot loader code as well as in the application code when i
>>> send the flash write command from PC program via USB. Let me
>>> explain the 3 situations where I have successful (1 and 2)
>>> and unsuccessful (3) writing to flash memory.
>>> 1) In boot loader code - I reserved at location 0x00000000 to
>>> 0x00007FFF including some data like version numbers, etc
>>> which I save from address 0x00007000 to 0x00007FFF). During
>>> startup, i read the version of my boot loader (located at
>>> address 0x00007042) and if it is blank or is not the latest,
>>> it will update by writing the latest version number to this
>>> address. I have no problem using my flash routines in this way.
>>>
>>> 2) In application code - which starts from 0x00008000 to
>>> 0x00034000 (i define the length of the application code to be
>>> 0x0002C000. My application code is updateable via USB and I
>>> use an application program (done in VB) to do this. Everytime
>>> I want to update my LPC2148's application code, I send a
>>> command from USB to write some data in the flash memory (from
>>> 0x00007FFC to 0x00007FFF). I also have no problem writing the
>>> flash memory in this way. I understand that the flash write
>>> happens during an USB interrupt routine like this:
>>>
>>> BOOL HID_SetReport (void) {
>>>
>>> /* ReportID = SetupPacket.wValue.WB.L; */
>>> switch (SetupPacket.wValue.WB.H) {
>>> case HID_REPORT_INPUT:
>>> return (FALSE); /* Not Supported */
>>> case HID_REPORT_OUTPUT:
>>> { unsigned char i;
>>> for(i=0; i >>> OutReport_PCToScale();
>>> }
>>> break;
>>> case HID_REPORT_FEATURE:
>>> return (FALSE); /* Not Supported */
>>> }
>>> return (TRUE);
>>> }
>>>
>>> where the call to flash writing of data is inside the
>>> function OutReport_PCToScale();
>>>
>>> 3) In application code - There are some data and settings
>>> that I want to store in the flash ROM like serial number,
>>> date of application code update, etc and I have the correct
>>> functions to do this as well as the call to write the data to
>>> flash memory. But everytime my function executes the call to
>>> flash write (which is same as the flash write code I used in
>>> #2), my system restarts (do startup routines and load again).
>>> I have keys or buttons to execute the functions as well as
>>> LCD to view the results. The thing is I even copied the same
>>> function and data that I have in #2 but the result is same
>>> (system restart).
>>>
>>> I hope somebody can help me with my problem.
>>> Thank you.
>>>
>>>
>>> Regards,
>>> Marilou
>>>
>>>
>> Do you disable interrupts while writing to flash in the main
>> application?
>>
>> Mike
>>
Hello!
Thank you for all of your replies.
Yes, interrupts are disabled during flash write.
My codes for flash write are as follows:

unsigned int FlashWrite(void *dst, void *src, unsigned byteCount){
struct IAP_Input iap;
unsigned int result[2];
unsigned int saveVICInt;
unsigned int count;
unsigned int Buffer[4096/sizeof(int)]; //4kb

saveVICInt = VICIntEnable;
VICIntEnClr = 0xFFFFFFFF; //Disable all interrupt

//First copy the whole thing of that sector in buffer assuming the buffer is 4k big
memcpy(Buffer, (void *)((unsigned int)dst & ~0xFFF), 4096);

//Prepare all the APROM sector for programming
iap.cmd = IAP_SELSECTOR;
iap.par[0] = getSectorNo(dst);
iap.par[1] = getSectorNo(dst);
IAP_Entry(&iap, result);
if(result[0]) goto exit;

//Now after erasing copy the source to the buffer
count = min(byteCount, (4096 - ((unsigned int)dst & 0xFFF)));
memcpy((char *)Buffer + ((unsigned int)dst & 0xFFF), src, count);

iap.cmd = IAP_RAMTOFLASH;
iap.par[0] = (unsigned int)dst & ~0xFFF;
iap.par[1] = (unsigned int)Buffer; //(unsigned long)src;
iap.par[2] = 4096;
iap.par[3] = CCLK/1000;
IAP_Entry(&iap, result);

exit:
VICIntEnable = saveVICInt; //Enable interrupt
return (result[0]);
}

It's weird because it works in #1 and #2 scenarios. :(
--- In l..., Miguel Angel wrote:
>
> As mike says... you should switch off interrupts. Because during IAP flash
> writesthe flash (ALL of it, not where you're writting) becomes unavailable
> to the processor,
> so... if an IRQ happens... the result is undefined instructions...
> Miguel Angel Ajo Pelayo
> http://www.nbee.es
> +34 91 120 1798
> +34 636 52 25 69
> skype: ajoajoajo
> 2009/10/10 Michael Anton >
> >
> > > -----Original Message-----
> > > From: l...
> > > [mailto:l... ]On Behalf
> > > Of malzki7480
> > > Sent: Friday, October 09, 2009 9:36 PM
> > > To: l...
> > > Subject: [lpc2000] LPC2148 Flash Write Problem
> > >
> > >
> > > Hi!
> > > I have a problem writing to the on chip Flash ROM of LPC2148
> > > in my project. I find it hard to determine the cause of the
> > > problem because my Flash write routines are working in the
> > > boot loader code as well as in the application code when i
> > > send the flash write command from PC program via USB. Let me
> > > explain the 3 situations where I have successful (1 and 2)
> > > and unsuccessful (3) writing to flash memory.
> > > 1) In boot loader code - I reserved at location 0x00000000 to
> > > 0x00007FFF including some data like version numbers, etc
> > > which I save from address 0x00007000 to 0x00007FFF). During
> > > startup, i read the version of my boot loader (located at
> > > address 0x00007042) and if it is blank or is not the latest,
> > > it will update by writing the latest version number to this
> > > address. I have no problem using my flash routines in this way.
> > >
> > > 2) In application code - which starts from 0x00008000 to
> > > 0x00034000 (i define the length of the application code to be
> > > 0x0002C000. My application code is updateable via USB and I
> > > use an application program (done in VB) to do this. Everytime
> > > I want to update my LPC2148's application code, I send a
> > > command from USB to write some data in the flash memory (from
> > > 0x00007FFC to 0x00007FFF). I also have no problem writing the
> > > flash memory in this way. I understand that the flash write
> > > happens during an USB interrupt routine like this:
> > >
> > > BOOL HID_SetReport (void) {
> > >
> > > /* ReportID = SetupPacket.wValue.WB.L; */
> > > switch (SetupPacket.wValue.WB.H) {
> > > case HID_REPORT_INPUT:
> > > return (FALSE); /* Not Supported */
> > > case HID_REPORT_OUTPUT:
> > > { unsigned char i;
> > > for(i=0; i > > > OutReport_PCToScale();
> > > }
> > > break;
> > > case HID_REPORT_FEATURE:
> > > return (FALSE); /* Not Supported */
> > > }
> > > return (TRUE);
> > > }
> > >
> > > where the call to flash writing of data is inside the
> > > function OutReport_PCToScale();
> > >
> > > 3) In application code - There are some data and settings
> > > that I want to store in the flash ROM like serial number,
> > > date of application code update, etc and I have the correct
> > > functions to do this as well as the call to write the data to
> > > flash memory. But everytime my function executes the call to
> > > flash write (which is same as the flash write code I used in
> > > #2), my system restarts (do startup routines and load again).
> > > I have keys or buttons to execute the functions as well as
> > > LCD to view the results. The thing is I even copied the same
> > > function and data that I have in #2 but the result is same
> > > (system restart).
> > >
> > > I hope somebody can help me with my problem.
> > > Thank you.
> > >
> > >
> > > Regards,
> > > Marilou
> > >
> > Do you disable interrupts while writing to flash in the main
> > application?
> >
> > Mike
> >
> >
> >
>
>

malzki7480 wrote:
> Yes, interrupts are disabled during flash write.

But you have not confirmed that you have disabled or are not using the watchdog (Herbert's note).

--

Timo

Check that your RAM irq routines doesn't use any constant from ROM.
(Use objdump listing [or equivalent] to check for compiler-generated
constant)
Miguel Angel Ajo Pelayo
http://www.nbee.es
+34 91 120 1798
+34 636 52 25 69
skype: ajoajoajo
2009/10/10

> Miguel Angel schrieb:
>
> > As mike says... you should switch off interrupts.
> ... if the interrupt routine (and any routine called by it) is located
> in RAM and the IRQ table is in RAM as well, then you *can* use
> interrupts during IAP (this is what I successfully do)
>
> Herbert
> > Because during IAP flash
> > writesthe flash (ALL of it, not where you're writting) becomes
> unavailable
> > to the processor,
> > so... if an IRQ happens... the result is undefined instructions...
> >
> > -----Original Message-----
> >
> >>> From: l... > 40yahoogroups.com>
> >>> [mailto:l... > 40yahoogroups.com>]On Behalf
> >>> Of malzki7480
> >>> Sent: Friday, October 09, 2009 9:36 PM
> >>> To: l... > 40yahoogroups.com>
> >>> Subject: [lpc2000] LPC2148 Flash Write Problem
> >>>
> >>>
> >>> Hi!
> >>> I have a problem writing to the on chip Flash ROM of LPC2148
> >>> in my project. I find it hard to determine the cause of the
> >>> problem because my Flash write routines are working in the
> >>> boot loader code as well as in the application code when i
> >>> send the flash write command from PC program via USB. Let me
> >>> explain the 3 situations where I have successful (1 and 2)
> >>> and unsuccessful (3) writing to flash memory.
> >>> 1) In boot loader code - I reserved at location 0x00000000 to
> >>> 0x00007FFF including some data like version numbers, etc
> >>> which I save from address 0x00007000 to 0x00007FFF). During
> >>> startup, i read the version of my boot loader (located at
> >>> address 0x00007042) and if it is blank or is not the latest,
> >>> it will update by writing the latest version number to this
> >>> address. I have no problem using my flash routines in this way.
> >>>
> >>> 2) In application code - which starts from 0x00008000 to
> >>> 0x00034000 (i define the length of the application code to be
> >>> 0x0002C000. My application code is updateable via USB and I
> >>> use an application program (done in VB) to do this. Everytime
> >>> I want to update my LPC2148's application code, I send a
> >>> command from USB to write some data in the flash memory (from
> >>> 0x00007FFC to 0x00007FFF). I also have no problem writing the
> >>> flash memory in this way. I understand that the flash write
> >>> happens during an USB interrupt routine like this:
> >>>
> >>> BOOL HID_SetReport (void) {
> >>>
> >>> /* ReportID = SetupPacket.wValue.WB.L; */
> >>> switch (SetupPacket.wValue.WB.H) {
> >>> case HID_REPORT_INPUT:
> >>> return (FALSE); /* Not Supported */
> >>> case HID_REPORT_OUTPUT:
> >>> { unsigned char i;
> >>> for(i=0; i > >>> OutReport_PCToScale();
> >>> }
> >>> break;
> >>> case HID_REPORT_FEATURE:
> >>> return (FALSE); /* Not Supported */
> >>> }
> >>> return (TRUE);
> >>> }
> >>>
> >>> where the call to flash writing of data is inside the
> >>> function OutReport_PCToScale();
> >>>
> >>> 3) In application code - There are some data and settings
> >>> that I want to store in the flash ROM like serial number,
> >>> date of application code update, etc and I have the correct
> >>> functions to do this as well as the call to write the data to
> >>> flash memory. But everytime my function executes the call to
> >>> flash write (which is same as the flash write code I used in
> >>> #2), my system restarts (do startup routines and load again).
> >>> I have keys or buttons to execute the functions as well as
> >>> LCD to view the results. The thing is I even copied the same
> >>> function and data that I have in #2 but the result is same
> >>> (system restart).
> >>>
> >>> I hope somebody can help me with my problem.
> >>> Thank you.
> >>>
> >>>
> >>> Regards,
> >>> Marilou
> >>>
> >>>
> >> Do you disable interrupts while writing to flash in the main
> >> application?
> >>
> >> Mike
> >>
>
>


@Timo - Do you mean my code below does not assure that interrupts have been disabled?

saveVICInt = VICIntEnable;
VICIntEnClr = 0xFFFFFFFF; //Disable all interrupt

Anyway, thank you for all your replies.
In the meantime, I am using an external 512-byte EEPROM to save some settings while I am still solving the Flash ROM write problem.
I appreciate if there are other suggestions to fix it because I still plan to use the Flash ROM to save some data.
Thanks to everybody.
Regards,
Marilou

--- In l..., tike64@... wrote:
>
> malzki7480 wrote:
> > Yes, interrupts are disabled during flash write.
>
> But you have not confirmed that you have disabled or are not using the watchdog (Herbert's note).
>
> --
>
> Timo
>

malzki7480 wrote:
> @Timo - Do you mean my code below does not assure that interrupts have
> been disabled?
>
> saveVICInt = VICIntEnable;
> VICIntEnClr = 0xFFFFFFFF; //Disable all interrupt

It is a completely different thing. If you have watchdog enabled and fail to
bump it in time, you get a system reset regardless of interrupts being disabled.

--

Timo


Memfault Beyond the Launch