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 CCS Technical Support

reading/writing to program memory problems

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



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

reading/writing to program memory problems
PostPosted: Mon May 14, 2012 12:45 am     Reply with quote

Compiler: PCWH/PCD 4.130
Processor: 24HJ128GP202

I'm writing and reading from program memory. When I read back the data every 4th byte is 0x00. Am I doing something wrong or is this a bug in the compiler?

I've attached the minimum amount of code to demonstrate this:

Code:
#CASE

#include <24HJ128GP202.h>
#fuses NOWRTB     //Boot block not write protected
#fuses NOBSS      //No boot segment
#fuses NORBS      //No Boot RAM defined
#fuses NOWDT      //No Watch Dog Timer
#fuses PUT128     //Power On Reset Timer value 128ms
#fuses NOALTI2C   //I2C mapped to SDA1/SCL1 pins
#fuses ICSP1      //ICD uses PGC1/PGD1 pins
#fuses NOJTAG     //JTAG disabled
#fuses NODEBUG    //No Debug mode for ICD
#fuses NOWRTSS    //Secure segment not write protected
#fuses NOSSS      //No secure segment
#fuses NORSS      //No secure segment RAM
#fuses NOPROTECT  //Code not protected from reading
#fuses PR_PLL     //Primary Oscillator with PLL
#fuses IESO       //Internal External Switch Over mode enabled
#fuses XT         // Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#fuses NOOSCIO    //OSC2 is clock output
#fuses NOIOL1WAY  //Allows multiple reconfigurations of peripheral pins
#fuses CKSNOFSM   //Clock Switching is enabled, fail Safe clock monitor is disabled

#use delay( clock=80M, xtal=10M )

// Setup Port IOs as all digital
#define AD1PCFGL_Def 0xffff;

//-----------------------------------------------------------------------------
//------ Hardware pin assignments ---------------------------------------------
//-----------------------------------------------------------------------------

#pin_select    U1TX = PIN_B0     // Console
#pin_select    U1RX = PIN_B1

#use rs232( baud=38400, UART1, ERRORS, stream=CONSOLE  )

//-----------------------------------------------------------------------------
//    pseudo-EEPROM stuff for write/read_program_eeprom()
//    Used to save config info     
//-----------------------------------------------------------------------------

#define  EE_BUFFER_SIZE       64    // bytes
#define  PROGRAM_MEMORY_SIZE  getenv("PROGRAM_MEMORY")
#define  EE_BUFFER_END        (PROGRAM_MEMORY_SIZE - 1)
#define  EE_BUFFER_START      (PROGRAM_MEMORY_SIZE - EE_BUFFER_SIZE)
int32    eepromAddress;       // pointer to address location to write

struct {
   int8  exitDelay;     // number of seconds to wait
   int8  numSnaps;      // default number of pictures to take
   BYTE  oldDir[14];    // oldest directory name
   } camConfig;


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void main ()
{
   delay_ms( 100 );
   
   fprintf(CONSOLE,"%s %s %s \r\n",__FILENAME__, __DATE__,__TIME__);
   fprintf(CONSOLE, "MEMORY Locations: %ld %ld %ld \r\n",PROGRAM_MEMORY_SIZE, EE_BUFFER_START, EE_BUFFER_END);

   // initialize structure
   camConfig.exitDelay = 30;
   camConfig.numSnaps = 10;
   sprintf(camConfig.oldDir,"12345678.abc");
   
   // write structure to program memory
   eepromAddress = (int32)EE_BUFFER_START;
   write_program_memory( eepromAddress, &camConfig, sizeof(camConfig) );

   // fill structure with other data to be sure we are overwriting when we read program memory
   camConfig.exitDelay = 8;
   camConfig.numSnaps = 9;
   sprintf(camConfig.oldDir,"abcdefgh.123");
   fprintf(CONSOLE," %d %d >%s<\r\n",camConfig.exitDelay, camConfig.numSnaps, camConfig.oldDir);

   // read program memory
   eepromAddress = (int32)EE_BUFFER_START;
   read_program_memory( eepromAddress, &camConfig, sizeof(camConfig) );

   fprintf(CONSOLE," %d %d >%s<\r\n",camConfig.exitDelay, camConfig.numSnaps, camConfig.oldDir);

   fprintf(CONSOLE,"Starting with 3rd byte in struct: %x %x %x %x %x %x %x %x %x %x %x %x %x\r\n", camConfig.oldDir[0], camConfig.oldDir[1], camConfig.oldDir[2],
      camConfig.oldDir[3], camConfig.oldDir[4], camConfig.oldDir[5], camConfig.oldDir[6], camConfig.oldDir[7], camConfig.oldDir[8],
      camConfig.oldDir[9], camConfig.oldDir[10], camConfig.oldDir[11], camConfig.oldDir[12]);

   delay_ms( 100 );
}   


Which produces the following output:

    pgm_mem.c 14-May-12 01:40:44
    MEMORY Locations: 88064 88000 88063
    8 9 >abcdefgh.123<
    30 10 >1<
    Starting with 3rd byte in struct: 31 0 33 34 35 0 37 38 2e 0 62 63 0


Thanks.
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Mon May 14, 2012 1:44 am     Reply with quote

You say:
"When I read back the data every 4th byte is 0x00. Am I doing something wrong or is this a bug in the compiler?".
Neither.....

You need to understand that the program memory is _24bits wide_.
It is organised as (quote from data sheet):
"it is more appropriate to think of each address of the program memory as a lower and upper word, with the upper byte of the upper word being unimplemented."

Note the 'unimplemented'.

So you have a 32bit memory value, with the top 8 bits being 'unimplemented'.

So if you want to store values into the program memory, you need to handle breaking the values into 3byte pieces, and re-assembling these.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Mon May 14, 2012 6:13 am     Reply with quote

Something else you want to pay attention to is how and where you write to Program Memory. In order to write to program memory, you need to do a page erase first, even if you don't plan on writing the whole page. Most pic24's if not all, have a page size of 0x400 words (0x800 bytes). you can get the value with:

#define PM_PAGE_SIZE (getenv("PAGE_ERASE_SIZE)/2) //words

Also note that write_program_memory() will do the erase for you if you write to the page address itself, which is a multiple of the PM_PAGE_SIZE


Additionally, since you are working with the last area of memory, you don't want to erase the last page of memory because that is where the program FUSES reside. You can manage this a couple ways. You can either manually specify the page or calculate it, and then do a page erase on it.


Code:

#define PM_PAGE_SIZE (getenv("PAGE_ERASE_SIZE)/2)  //words
#define PM_FUSE_ADDR getenv("PROGRAM_MEMORY")
#define PM_FUSE_PAGE_ADDR ((PM_FUSE_ADDR/PM_PAGE_SIZE)*PM_PAGE_SIZE)

//pick the PM page before the one using the fuses.
#define PM_EE_BUFFER_START (PM_FUSE_PAGE_ADDR-PM_PAGE_SIZE)
#define PM_EE_BUFFER_END   (PM_FUSE_PAGE_ADDR-1)
#define PM_EE_BUFFER_SIZE  PM_PAGE_SIZE

//make sure your code can't go into this space:
#org PM_EE_BUFFER_START,PM_EE_BUFFER_END {}
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon May 14, 2012 8:11 am     Reply with quote

I get it. Thanks for the great explanations.
_________________
Jürgen
www.jgscraft.com
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