CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

problem with write_program_memory on the PIC18F2450

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ramey



Joined: 11 Sep 2007
Posts: 18

View user's profile Send private message

problem with write_program_memory on the PIC18F2450
PostPosted: Fri Feb 27, 2009 1:45 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 27, 2009 2:21 am     Reply with quote

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








PostPosted: Fri Feb 27, 2009 11:27 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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