LPC2148H and IAP Flash Writing

Has anybody had much success writing Flash from within a program? Is there any way to do it besides calling the IAP subroutine?

I managed to get OpenOCD talking to my header board over JTAG via an Olimex Wiggler clone, and GDB can download code to RAM and execute it, but I haven’t had much luck writing Flash.

I have a simple LED blinker program and I’ve added calls to Prepare Flash and Copy RAM to Flash. It worked once, but I haven’t been able to change and/or erase the data I wrote. (Actually, I was able to overwrite some of it, but it’s not consistent.)

How do you figure out what to pass for CCLK (system clock frequency in kHz)? I haven’t fiddled with the PLL yet, so I don’t know what the clock frequency is – it’s whatever the bootloader and/or demo USB code sets it to, I guess. When I toggle the LED bit as fast as possible, I get a 1/3 duty cycle waveform at about 0.3uS (3 instructions – set, clear, jmp, so about 10MHz?) Does the CCLK parameter have to be correct, or can you fudge it on one side or the other and have it work?

I have had some success in programming the FLASH on a 2138 using the IAP subroutines. There is no officially supported method other than IAP and ISP on the LPC to program the FLASH as far as I know. There is someone on the LPC group over at Yahoo which talks about having written their own routines by reverse engineering the IAP code but I wouldn’t want to go that route myself.

If you haven’t setup the PLL then the clock rate will match the rate of the clock that you have connected to the oscillator pins of the chip. From what I have seen from past discussions, the clock rate passed in should be as close as possible but many people have reported success even when they weren’t that close but I wouldn’t recommend this for a production system.

Can you give me any more details on exactly which IAP routines you are calling, in what order, are you getting errors back from the IAP routines, and what are the nature of the failures that you are getting? One problem that I have encountered in the past is that if the device is running the bootloader, then it will have its interrupt vectors mapped into the lowest 64 bytes of memory. This will cause some of the IAP routines (especially those used for verifying the sectors such as the blank check or compare flash to ram) to fail. To get around this, you first need to write the appropriate value to the MEMMAP register (write the value 1 to address 0xe01fc040) before starting the programming sequence. Also, if you don’t set the 4-byte word at address 0x14 to the correct checksum value, then your code won’t boot and it will just keep running the bootloader. These issues have caused me to have success the first time I tried to program the FLASH but fail on subsequent attempts because:

-on the first attempt the device was running some code from FLASH which had been programmed via the ISP routines over the serial connection.

-The lowest portions of memory were mapped to the FLASH so my programming attempts were successful. By success I mean that the prepare, erase, and write routines didn’t return any errors and the blank check and compare flash to ram functions passed in the appropriate places as well.

-However, I forgot to the set the interrupt vector checksum at address 0x14 correctly and the newly programmed FLASH program would never run. The bootloader just kept getting loaded up instead.

-Since the bootloader was running, sector 0 of the FLASH was no longer mapped into the lower 64 bytes of memory. This caused some of my IAP routine calls to fail on subsequent attempts. In particular, I would prepare and erase sector 0 but the blank check would always fail since it would see the bootloader code in the interrupt vector.

atom:
Can you give me any more details on exactly which IAP routines you are calling, in what order, are you getting errors back from the IAP routines, and what are the nature of the failures that you are getting?

Not just yet...after reading your message, I have a bunch of things to check and try. (Particularly the interrupt vectors.) I've gone through that section of the manual more carefully, and I have a better idea of how it's supposed to work, so I'll have to spend some time fiddling with initialization code before I get to the IAP routines. I did manage to get some sectors erased and written yesterday, but I think it was just luck -- a fortuitous combination of resets, poking around in interrupt vector tables, and guessing clock speeds.