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

Writing Structure to EEPROM reset_cpu() clears Data EEPROM

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



Joined: 14 Dec 2009
Posts: 33
Location: Wales

View user's profile Send private message

Writing Structure to EEPROM reset_cpu() clears Data EEPROM
PostPosted: Wed Jan 20, 2010 2:11 pm     Reply with quote

I wrote this program to test writing a data structure to the PIC
data EEPROM. It appears to work when reading / writing the
EEPROM with the user input menu but when the PIC is reset
via the menu the data is lost when its read from the menu.

Anyone got any ideas - I am completely baffled. It reads data from
EEPROM but reset_cpu() clears it again. Compiler version 4.09
Code:

//*********************************************************
// 18F4620-Setup-Write-V1.c
// Program to check writing setup structure to NVM
//*********************************************************
#include    <18F4620.h>
#device     PASS_STRINGS=IN_RAM
#device   *= 16;

#fuses      HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP, NODEBUG, MCLR
#use      DELAY(CLOCK=20MHz, RESTART_WDT)
#use      RS232(BAUD=115200, XMIT=PIN_C6, RCV=PIN_C7, STREAM=COM1, RESTART_WDT)

#include    <stdio.h>
#include    <string.h>
#include    <stdarg.h>
#include   <stdlibm.h>

void    init_structure_defaults_in_memory(void);
void   clear_structure(void);
void   read_eeprom_string( char *, int8, int8);
void   write_eeprom_string(char *, int8, int8);
void   load_setup_from_nvm(void);
void   save_setup_to_nvm(void);
void   erase_nvm(int16);

const   char     EMPTY[]={"**************************"};
const   char   CHANNEL[]={"Channel 1 Control Defaults"};

struct   PID      {   char   ident[sizeof(CHANNEL)]   ;
               float   Kp, Ki, Kd      ;   // PID Gains
               char   is_setup      ;   //
               }    trx,    *ptrx         ;   //

char   buffer[sizeof(trx)];

void   main()
{
char    ch=0;
int16   counter=0, s_size;

ptrx   =   &trx;
s_size   =   sizeof(trx);

// Clear structure to check it loads ok on startup
trx.Kp=0;   trx.Ki=0;   trx.Kd=0;
strncpy(trx.ident, EMPTY, sizeof(EMPTY));

fprintf(COM1, "\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
fprintf(COM1, "=================[ CPU Reset ]=================\r\n");
fprintf(COM1, "\r\n Structure trx (size : %Ld), Kp=%f, IDENT=%s", sizeof(trx), (*ptrx).Kp, trx.ident );

trx.Kp=0; trx.Ki=0; trx.Kd=0;             // Clear initialised structure

while(1)
   {   fprintf(COM1, "\r\nCount : %Ld, Struct Data : %f %f %f \n\r", counter++, trx.Kp, trx.Ki, trx.Kd);
      fprintf(COM1, "\r\n 1. Save Setup to NVM");
      fprintf(COM1, "\r\n 2. Load Setup from NVM");
      fprintf(COM1, "\r\n 3. Initialise Setup");
      fprintf(COM1, "\r\n 4. Erase NVM ");
      fprintf(COM1, "\r\n 5. Clear Structure");
      fprintf(COM1, "\r\n 6. Reset CPU ");
      fprintf(COM1, "\r\n\n  Enter a choice : ");
      ch=getch();
      switch (ch)
         {   case '1' :    save_setup_to_nvm();
                     continue;
            case '2' :   load_setup_from_nvm();
                     continue; 
            case '3' :  init_structure_defaults_in_memory();
                     continue;
            case '4' :   erase_nvm(sizeof(trx));
                     continue;
            case '5' :  clear_structure();
                     continue;
            case '6' :  reset_cpu();
                     continue;
            default  :  break;
      }
   }
}

void   erase_nvm(int16 size)
{
int16   i=0;
fprintf(COM1, "\r\n Erasing %Ld bytes ", size);
for (i=0; i<size; )   write_eeprom(i++, 0);
}

void   read_eeprom_string(char *array, int8 address, int8 max_size)
{
int8   i =   0;

*array = 0;

while(i<max_size)   {   *array=read_eeprom(address+i);
                  if (*array==0) { i=max_size; }
                  else   {   array++;
                           *array=0;   }   
                  i++;   }
}

//*******************************************************************
//   Function: write_eeprom_string
//*******************************************************************

void   write_eeprom_string(char *array, int8 address, int8 max_size)
{
int8   i=0;
while(i < max_size)   
   {   write_eeprom(address+i, *array);
      if (*array==0) { i=max_size; }
      array++; i++;   }
}   //    Start of main ..

void    init_structure_defaults_in_memory(void)
{
fprintf(COM1, "\r\n Initialising Setup Structure Defaults : ");
trx.Kp         =  10;   
trx.Ki         =  20;      
trx.Kd         =  35;
trx.is_setup   =  0x62;
strncpy(trx.ident, CHANNEL, sizeof(CHANNEL));
}

void   load_setup_from_nvm()
{
fprintf(COM1, "\r\nLoading setup from NVM : ");
read_eeprom_string(&buffer[0], 0, sizeof(trx));
memcpy(&trx, &buffer[0], sizeof(trx));
fprintf(COM1, "\r\nChecking - setup from NVM : %f %f %f", trx.Kp, trx.Ki, trx.Kd);
fprintf(COM1, "\r\nChecking setup value : %02x", trx.is_setup);
fprintf(COM1, "\r\nPress a key to continue");
getch();
}

void   save_setup_to_nvm()
{
fprintf(COM1, "\r\n Saving Setup to NVM : ");
memcpy(&buffer[0], &trx, sizeof(trx));      // Copy  initialised stucture
write_eeprom_string(&buffer[0], 0, sizeof(trx));
}

void   clear_structure(void)
{
trx.Kp=0;
trx.Ki=0;
trx.Kd=0;

trx.is_setup = 0;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 20, 2010 3:24 pm     Reply with quote

Write a small test program to prove that you can write a byte to eeprom
and then read it after a reset or power-up. Here's an example:
http://www.ccsinfo.com/forum/viewtopic.php?t=22109&start=17

Note: For 18F PICs, the #rom address for eeprom is 0xF00000 (5 zeros
after the 'F').
ac34856



Joined: 14 Dec 2009
Posts: 33
Location: Wales

View user's profile Send private message

PostPosted: Thu Jan 21, 2010 7:29 am     Reply with quote

Thanks PCM,
this seems to work but started giving me trouble when porting
to the main application - possibly running out of RAM ? ..
Will plod on with it see where I get..

Code:
//*********************************************************
//    18F4620-Setup-Write-V2.c
//    Program to check writing setup structure to NVM
//   Notes:  This program works and appears to be correct
//   Modifications: Requires Error Traps Adding.
//*********************************************************
#include    <18F4620.h>
#device     PASS_STRINGS=IN_RAM
#device   *= 16;

#fuses   HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use      DELAY(CLOCK=20MHz, RESTART_WDT)
#use      RS232(BAUD=115200, XMIT=PIN_C6, RCV=PIN_C7,   STREAM=COM1, RESTART_WDT)

#include    <stdio.h>
#include    <string.h>
#include    <stdarg.h>
#include   <stdlibm.h>

void    init_structure_defaults_in_memory(void);
void   clear_structure(void);
void   read_eeprom_string( char *, int8, int8);
void   write_eeprom_string(char *, int8, int8);
void   load_setup_from_nvm(void);
void   save_setup_to_nvm(void);
void   erase_nvm(int16);
void   dump_eeprom(int16);

const   char     EMPTY[]={"**************************"};
const   char   CHANNEL[]={"Channel 1 Control Defaults"};

struct   PID      {   char   ident[sizeof(CHANNEL)]   ;
            float   Kp, Ki, Kd      ;   // PID Gains
            char   is_setup      ;   //
               }    trx,    *ptrx         ;   //

char   buffer[sizeof(trx)];

void   main()
{
char    ch=0;
int16   counter=0;
int16   s_size;

ptrx   =   &trx;
s_size   =   sizeof(trx);

// Clear structure to check it loads ok on startup
trx.Kp=0;   trx.Ki=0;   trx.Kd=0;
strncpy(trx.ident, EMPTY, sizeof(EMPTY));

fprintf(COM1, "\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
fprintf(COM1, "====[ CPU Reset ]===\r\n");
load_setup_from_nvm();

fprintf(COM1, "\r\n Structure trx (size : %Ld), Kp=%f, IDENT=%s", sizeof(trx), (*ptrx).Kp, trx.ident );

while(1)
   {   fprintf(COM1, "\r\nCount : %Ld, Struct Data : %f %f %f \n\r", counter++, trx.Kp, trx.Ki, trx.Kd);
      fprintf(COM1, "\r\n 1. Save Setup to NVM");
      fprintf(COM1, "\r\n 2. Load Setup from NVM");
      fprintf(COM1, "\r\n 3. Initialise Default Setup");
      fprintf(COM1, "\r\n 4. Erase NVM ");
      fprintf(COM1, "\r\n 5. Clear Structure");
      fprintf(COM1, "\r\n 6. Dump EEPROM (0-100)");
      fprintf(COM1, "\r\n 7. Reset CPU ");
      fprintf(COM1, "\r\n\n  Enter a choice : ");
      ch=getch();
      switch (ch)
         {   case '1' :    save_setup_to_nvm();
                     continue;
            case '2' :   load_setup_from_nvm();
                     continue; 
            case '3' :  init_structure_defaults_in_memory();
                     save_setup_to_nvm();
                     continue;
            case '4' :   erase_nvm(sizeof(trx));
                     continue;
            case '5' :  clear_structure();
                     // erase_nvm(sizeof(trx));
                     continue;
            case '6' :  dump_eeprom(100);
                     continue;
            case '7' :  reset_cpu();
                     continue;
            default  :  break;
      }
   }
}

void   erase_nvm(int16 size)
{
int16   i=0;
fprintf(COM1, "\r\n Erasing %Ld bytes ", size);
for (i=0; i<size; )   write_eeprom(i++, 0xff);
}

void   read_eeprom_string(char *array, int8 address, int8 max_size)
{
int8   i =   0;

*array = 0;

while(i<max_size)   {   *array=read_eeprom(address+i);
                  if (*array==0) { i=max_size; }
                  else   {   array++;
                           *array=0;   }   
                  i++;   }
}

//**********************************************************
//   Function: write_eeprom_string
//**********************************************************

void   write_eeprom_string(char *array, int8 address, int8 max_size)
{
int8   i=0;
while(i < max_size)   
   {   write_eeprom(address+i, *array);
      if (*array==0) { i=max_size; }
      array++; i++;   }
}   //    Start of main ..

void    init_structure_defaults_in_memory(void)
{
fprintf(COM1, "\r\n Initialising Setup Structure Defaults : ");
trx.Kp      =  10;   
trx.Ki         =  20;      
trx.Kd      =  35;
trx.is_setup   =  0x62;
strncpy(trx.ident, CHANNEL, sizeof(CHANNEL));

}

void   load_setup_from_nvm()
{
int16   s_eeprom;
s_eeprom   =   getenv("DATA_EEPROM");
fprintf(COM1, "\r\nLoading setup from NVM : ");
read_eeprom_string(&buffer[0], 0, sizeof(trx));
memcpy(&trx, &buffer[0], sizeof(trx));
fprintf(COM1, "\r\n        Size of EEPROM : %Ld Bytes ", s_eeprom);
fprintf(COM1, "\r\n Setup values from NVM : %f %f %f", trx.Kp, trx.Ki, trx.Kd);
fprintf(COM1, "\r\n Setup value  from NVM : %02x", trx.is_setup);
//   fprintf(COM1, "\r\nPress a key to continue");
//   getch();
}

void   save_setup_to_nvm()
{
fprintf(COM1, "\r\n Saving Setup to NVM : ");
memcpy(&buffer[0], &trx, sizeof(trx));      // Copy  initialised stucture
write_eeprom_string(&buffer[0], 0, sizeof(trx));
}

void   clear_structure(void)
{
trx.Kp=0;
trx.Ki=0;
trx.Kd=0;
trx.is_setup = 0;
}

void   dump_eeprom(int16 size)
{
int16    i=0;
BYTE   val;
fprintf(COM1, "\r\n Dumping EEPROM\r\n");
for (i=0; i<size; )
   {
   val=read_eeprom(i);
   fprintf(COM1,"%02x ", val);
   if (i % 16 == 0) fprintf(COM1,"\r\n");
   ++i;
   }
}
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