|
|
View previous topic :: View next topic |
Author |
Message |
Ramey
Joined: 11 Sep 2007 Posts: 18
|
problem with write_program_memory on the PIC18F2450 |
Posted: Fri Feb 27, 2009 1:45 am |
|
|
I've got a boot loader program which uses write_program_memory to update program code.
This program was originally developed and tested on the PIC18F4550 and and PIC18F2550 has worked flawlessly for some time on those platforms. However when I compile it for the PIC18F2450 and invoke it, it SEEMS to work correctly until I read back the code. At this point I see blocks of 16 bytes blank (NOP) alternating with 16 bytes of valid code. That is, every second block is empty! - the others are valid.
Here is the code which does the write
Code: | #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
#if defined(__PCM__)
if(0 == (addr % (getenv("FLASH_ERASE_SIZE") / 2)))
#else
if(0 == (addr % getenv("FLASH_ERASE_SIZE")))
#endif
erase_program_eeprom(addr);
#endif
write_program_memory(addr, hexdata, count);
|
and here is the pre-amble from the list file
CCS PCH C Compiler, Version 4.055, 40531 26-Feb-09 23:17
Filename: usb_loader.lst
ROM used: 5596 bytes (34%)
Largest free fragment is 10772
RAM used: 464 (61%) at main() level
546 (72%) worst case
Stack: 13 worst case (6 in main + 7 for interrupts)
I'm wondering "FLASH_ERASE_SIZE" might be a problem here. Is it possile that number returned here is too small by half? That would be consistent with the symtom of the problem.
Robert Ramey |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 27, 2009 2:21 am |
|
|
Quote: | I'm wondering "FLASH_ERASE_SIZE" might be a problem here.
Is it possible that number returned here is too small by half? |
Look at the table on page 19 of the 18F2450 Programming spec:
http://ww1.microchip.com/downloads/en/DeviceDoc/39622k.pdf
It says the erase buffer size is 64 bytes. Run the test program
shown below. This will give you the answer.
Code: | #include <18F2450.h>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//====================================
void main()
{
printf("%U", getenv("FLASH_ERASE_SIZE"));
while(1);
} |
|
|
|
Guest
|
|
Posted: Fri Feb 27, 2009 11:27 am |
|
|
Thanks very much for the link to the data sheet on programming flash memory on these processors. I added a little bit to my example, compiled it and displayed the disassembled output.
It looks to me that getenv("FLASH_ERASE_SIZE") is returning 64
while getenv("FLASH_WRITE_SIZE") is returning 32 for this chip. This latter number is not in accordance with the data sheet cited above.
Code: | 269: else{
150C D02B BRA 0x1564
270: unsigned int16 e = getenv("FLASH_ERASE_SIZE");
150E 0E40 MOVLW 0x40
1510 6FF9 MOVWF 0xf9, BANKED
1512 6BFA CLRF 0xfa, BANKED
271: unsigned int16 w = getenv("FLASH_WRITE_SIZE");
1514 0E20 MOVLW 0x20
1516 6FFB MOVWF 0xfb, BANKED
1518 6BFC CLRF 0xfc, BANKED
|
I double checked the my mplab selection was for the PIC18f2450 and my program included the following:
Code: | //#include <18F2550.h>
#include <18F2450.h>
//#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#device ICD=TRUE
#fuses HSPLL
#fuses NOWDT
#fuses NOPROTECT
#fuses NOLVP
#fuses NODEBUG // if this isn't there - things don't work !!!
#fuses USBDIV
#fuses PLL5 // 20 MHz crystal
#fuses CPUDIV3 // to support slow speed 6 mhz
#fuses VREGEN
#fuses NOPBADEN
#use delay(clock=24mHz)
|
So it looks like that the the implemenation of getenv needs to be looked at for these values.
Note also that the documentation on how to use this function doesn't seem to correct:
Quote: | Writes count bytes to program memory from dataptr to address. This function is most effective when count is a multiple of FLASH_WRITE_SIZE. Whenever this function is about to write to a location that is a multiple of FLASH_ERASE_SIZE then an erase is performed on the whole block. |
From the help file that came with my compiler. This strongly suggests to me that I don't have to break up my writes into any specific size and that as long as I start on a erase_block boundry, everything should "just work".
very confusing.
Robert Ramey |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|