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

10F322 and HEF (virtual eeprom)

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



Joined: 31 Mar 2019
Posts: 43
Location: Sao paulo/Brazil

View user's profile Send private message Send e-mail

10F322 and HEF (virtual eeprom)
PostPosted: Sun Mar 31, 2019 7:02 pm     Reply with quote

Hello dear friends.

I humbly ask you for help on an issue.

I have to write 6 bytes (int8 values) and I do not know how to proceed with this question. I found some examples here in this forum, I tried but I did not understand.

This is a value that will be read every time the system is turned on, and sometimes new value will be written to the addresses.

I ask for help with an example code to record and read 1 byte.

Thank you very much in advance!!
Jerson



Joined: 31 Jul 2009
Posts: 122
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Sun Mar 31, 2019 10:20 pm     Reply with quote

Since the device does not have a dedicated EEPROM area, I think you will need to look at functions that can read / write flash area.
_________________
Regards
Jerson Fernandes
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Mon Apr 01, 2019 12:29 am     Reply with quote

Forget about using it like virtual EEPROM.

Your chip has an erase block size of 16words. So you need to think
of organising everything you want to save, into a block of RAM that
fits this size. Remember only 14bits in each word, so if you need 16bit
values, you need to use two words to hold each value etc..
If you only need to save a couple of values, read these using
read_program_memory. You then have to write the entire block you
want to save as one operation using write_program_memory, to
a boundary multiple of the erase size.
So write (for instance) to address 0x1E0, and this will erase and write
automatically.
Your chip _does not have HEF_. So there is no 'better' place to put this.
Seriously, given the size of RAM buffer needed, the lack of HEF, and
the amount of code that will be needed, it is honestly better to think in
terms of using another chip if you need EEPROM. The 'virtual EEPROM'
driver, would use a huge amount of your code space, so you really need
to be using the DIY approach, but this is going to be quite laborious...
rodrigo_cirilo



Joined: 31 Mar 2019
Posts: 43
Location: Sao paulo/Brazil

View user's profile Send private message Send e-mail

PostPosted: Mon Apr 01, 2019 4:59 am     Reply with quote

Ttelmah wrote:
Forget about using it like virtual EEPROM.

Your chip has an erase block size of 16words. So you need to think
of organising everything you want to save, into a block of RAM that
fits this size. Remember only 14bits in each word, so if you need 16bit
values, you need to use two words to hold each value etc..
If you only need to save a couple of values, read these using
read_program_memory. You then have to write the entire block you
want to save as one operation using write_program_memory, to
a boundary multiple of the erase size.
So write (for instance) to address 0x1E0, and this will erase and write
automatically.
Your chip _does not have HEF_. So there is no 'better' place to put this.
Seriously, given the size of RAM buffer needed, the lack of HEF, and
the amount of code that will be needed, it is honestly better to think in
terms of using another chip if you need EEPROM. The 'virtual EEPROM'
driver, would use a huge amount of your code space, so you really need
to be using the DIY approach, but this is going to be quite laborious...


Yes, I want to write 8-bit values, for example, 100, 101 and 102, and then write 200, 201, and 202 having only 6 8-bit values to be written. I do not quite understand this issue of organizing pages or blocks of memory, so I count on your precious help.

For the little that I understood, if I write the first 3 values, when I write the other 3 I should read before or 3 first and then write it all over again, is that it?

Below is your code that compiles correctly here, but I can not understand, the many settings that I do not know.


Code:
#include <10F322.h>
#FUSES NOWDT                   
#FUSES NOBROWNOUT         
#FUSES NOLVP                   
#use delay(internal=4000000)
#define ADDRESS_TO_USE_FOR_STORAGE 0x1F8 //This is the high endurance flash - 0xF8 for 10F320
#define BYTES_TO_USE 8 //Key is that the high endurance flash is 8 * bytes only low bytes in word only

#ROM int16 ADDRESS_TO_USE_FOR_STORAGE = {1,2,3,4,5,6,7} //Preload the HEF
//studying the assembler suggest the supplied memory write/erase functions still won't work.
//rewrite trimmed versions of these....
int8 buffer[BYTES_TO_USE]; //buffer for HEF

#byte PMADRH=getenv("SFR:PMADRH")
#byte PMADRL=getenv("SFR:PMADRL")
#bit CFGS=getenv("BIT:CFGS")
#bit WREN=getenv("BIT:WREN")
#bit LWLO=getenv("BIT:LWLO")
#bit FREE=getenv("BIT:FREE")
#byte PMDATL=getenv("SFR:PMDATL")
#byte PMDATH=getenv("SFR:PMDATH")
#byte PMCON2=getenv("SFR:PMCON2")
#bit WR=getenv("BIT:WR")
#bit RD=getenv("BIT:WR")
//#byte FSR0=getenv("SFR:INDF0")
#define delay_2() delay_cycles(1);delay_cycles(1) //two nops
#bit GIE=getenv("BIT:GIE")

#define UNLOCK()    PMCON2=0x55; PMCON2=0xAA; WR=TRUE; delay_2() //chip unlock sequence

#define select_address(add) CFGS=FALSE;PMADRL=make8(add,0);PMADRH=make8(add,1) //load address

void erase_row(int16 address) //erases the row containing 'address'.
{
   disable_interrupts(GLOBAL); //ensure interrupts are off
   select_address(address & 0x1F0); //select page
   FREE=TRUE;
   WREN=TRUE;
   UNLOCK(); //Perfrom the actual erase
   WREN=FALSE;
   enable_interrupts(GLOBAL);
}

void write_block(int8 *ram, int8 ctr, int16 address)
{
   //function to replace non working write
   //Warnings....
   //Writes 'ctr' bytes to the _low_ byte only of the memory block starting at 'address'
   //Must fit inside a row. No testing done to ensure this (keep space small...)
   disable_interrupts(GLOBAL); //ensure interrupts are off
   
   select_address(address);
   LWLO=TRUE;
   WREN=TRUE;
   FREE=FALSE;
   //Now need to load the latches
   do
   {
      PMDATH=0;
      PMDATL=*ram;
      ram++; //next byte
      if (--ctr==0) break;
      UNLOCK();
      PMADRL++; //Next word
   }
   while (TRUE);
   //Now all but last latch loaded
   LWLO=FALSE; //switch to physical write
   UNLOCK(); //and write the data
   WREN=FALSE;
   enable_interrupts(GLOBAL); 
}

void save_HEF(void) //copies the 8 HEF bytes to RAM buffer
{
   int16 address;
   //now read the max 8 HEF bytes
   for (address=0;address<BYTES_TO_USE;address++)
   {
      buffer[address]=read_program_eeprom(address+ADDRESS_TO_USE_FOR_STORAGE);
   }
}

void write_HEF(void)
{
   //Uses my replacement functions to write the 8 HEF bytes to ROM
   erase_row(ADDRESS_TO_USE_FOR_STORAGE); //erase entire row
   write_block(buffer,8,ADDRESS_TO_USE_FOR_STORAGE); //write the 8 HEF bytes
}

void main()
{
   while(TRUE)
   {
      save_HEF();
      //Now buffer contains the bytes from the HEF
      //Now modify, and try writing.
      buffer[2]=34;
      buffer[4]=56;
      buffer[7]=78;
      write_HEF();
      do {
      }
      while (TRUE); //stop here, don't want to write more than once...
   }
}


Please help me.
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Apr 01, 2019 5:16 am     Reply with quote

I looked at the datasheet and it does say it has HEF,though not how to access it. I did find a ref to HEF being the last 128 bytes of memory. Perhaps there's a separate 'application note' or other document on how to use it ?
I do have PIC10F322 samples on order as it seems it might be a GREAT 'glue' PIC.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Mon Apr 01, 2019 6:20 am     Reply with quote

That's interesting. I looked at my data sheet and no mention of HEF.
Suggests they have updated the chip and added this. In which case
you need to be sure your chip is recent.

On the current sheet, the HEF, is address 0x180 to 0x1FF.

So you need to choose a 32byte boundary in this area. So
0x180 0x1A0, 0x1C0, or 0x1E0.

A write to the page boundary erases the whole page.

Now you can change any bit from a 1, to a 0, without erasing.
So you can write to a single word and change it provided this is what
you want to do. However as soon as you need to change a bit from
0 to 1, this can only be done be erasing the whole page, which then implies
writing the whole page back. You need a buffer that is twice the size
of the number of bytes you want to store. So if you need 6 bytes, then
use a twelve byte buffer. Read the twelve bytes from the ROM, change the
ones you want, and write the whole block back to the page boundary.
You need to use even bytes in the buffer to have 8bits available (the
odd bytes will only store 6 bits each).

Code:
byte buffer[12];
read_program_memory(0x1E0, buffer, 12);
Would read a 12byte buffer from the flash.

Code:
write_program_memory(0x1E0, buffer, 12);
Would write the same buffer back.

buffer[0], buffer[2], buffer[4] etc., would contain the bytes you could use.

Add
Code:
#ORG 0x1E0, 0x1FF {}

Before your code, to stop the compiler putting anything into this area.
rodrigo_cirilo



Joined: 31 Mar 2019
Posts: 43
Location: Sao paulo/Brazil

View user's profile Send private message Send e-mail

PostPosted: Mon Apr 01, 2019 7:17 am     Reply with quote

Ttelmah wrote:
That's interesting. I looked at my data sheet and no mention of HEF.
Suggests they have updated the chip and added this. In which case
you need to be sure your chip is recent.

On the current sheet, the HEF, is address 0x180 to 0x1FF.

So you need to choose a 32byte boundary in this area. So
0x180 0x1A0, 0x1C0, or 0x1E0.

A write to the page boundary erases the whole page.

Now you can change any bit from a 1, to a 0, without erasing.
So you can write to a single word and change it provided this is what
you want to do. However as soon as you need to change a bit from
0 to 1, this can only be done be erasing the whole page, which then implies
writing the whole page back. You need a buffer that is twice the size
of the number of bytes you want to store. So if you need 6 bytes, then
use a twelve byte buffer. Read the twelve bytes from the ROM, change the
ones you want, and write the whole block back to the page boundary.
You need to use even bytes in the buffer to have 8bits available (the
odd bytes will only store 6 bits each).

byte buffer[12];
read_program_memory(0x1E0, buffer, 12);

Would read a 12byte buffer from the flash.

write_program_memory(0x1E0, buffer, 12);

Would write the same buffer back.

buffer[0], buffer[2], buffer[4] etc., would contain the bytes you could use.

Add

#ORG 0x1E0, 0x1FF {}

Before your code, to stop the compiler putting anything into this area.


Thank you very much for the guidance.

I analyzed your first code and I understood a small part.

I saw that you have to write directly in memory with the command:

Code:
 #ROM int16 ADDRESS_TO_USE_FOR_STORAGE = {1,2,3,4,5,6,7}


So soon after you read all the data and change only those below
Code:

buffer [2] = 15;
buffer [4] = 56;
buffer [7] = 78;
write_HEF ();

Could you help me to simplify your example code?

Is really necessary all this part:
Code:

#byte PMADRH = getenv ("SFR: PMADRH")
#byte PMADRL = getenv ("SFR: PMADRL")
#bit CFGS = getenv ("BIT: CFGS")
#bit WREN = getenv ("BIT: WREN")
#bit LWLO = getenv ("BIT: LWLO")
#bit FREE = getenv ("BIT: FREE")
#byte PMDATL = getenv ("SFR: PMDATL")
#byte PMDATH = getenv ("SFR: PMDATH")
#byte PMCON2 = getenv ("SFR: PMCON2")
#bit WR = getenv ("BIT: WR")
#bit RD = getenv ("BIT: WR")
rodrigo_cirilo



Joined: 31 Mar 2019
Posts: 43
Location: Sao paulo/Brazil

View user's profile Send private message Send e-mail

PostPosted: Mon Apr 01, 2019 11:42 am     Reply with quote

I think I can handle this.
I'm simulating proteus and it's working.

Look what I did.

Code:

#include <10F322.h>
#FUSES NOWDT                   
#FUSES NOBROWNOUT         
#FUSES NOLVP                   
#use delay(internal=4000000)
#define ADDRESS_TO_USE_FOR_STORAGE 0x1F8 //This is the high endurance flash - 0xF8 for 10F320
#define BYTES_TO_USE 8 //Key is that the high endurance flash is 8 * bytes only low bytes in word only

//#ROM int16 ADDRESS_TO_USE_FOR_STORAGE = {1,2,3,4,5,6,7} //Preload the HEF
//studying the assembler suggest the supplied memory write/erase functions still won't work.
//rewrite trimmed versions of these....
int8 buffer[BYTES_TO_USE]; //buffer for HEF

#byte PMADRH=getenv("SFR:PMADRH")
#byte PMADRL=getenv("SFR:PMADRL")
#bit CFGS=getenv("BIT:CFGS")
#bit WREN=getenv("BIT:WREN")
#bit LWLO=getenv("BIT:LWLO")
#bit FREE=getenv("BIT:FREE")
#byte PMDATL=getenv("SFR:PMDATL")
#byte PMDATH=getenv("SFR:PMDATH")
#byte PMCON2=getenv("SFR:PMCON2")
#bit WR=getenv("BIT:WR")
#bit RD=getenv("BIT:WR")
//#byte FSR0=getenv("SFR:INDF0")
#define delay_2() delay_cycles(1);delay_cycles(1) //two nops
#bit GIE=getenv("BIT:GIE")

#define UNLOCK()    PMCON2=0x55; PMCON2=0xAA; WR=TRUE; delay_2() //chip unlock sequence

#define select_address(add) CFGS=FALSE;PMADRL=make8(add,0);PMADRH=make8(add,1) //load address

void erase_row(int16 address) //erases the row containing 'address'.
{
   disable_interrupts(GLOBAL); //ensure interrupts are off
   select_address(address & 0x1F0); //select page
   FREE=TRUE;
   WREN=TRUE;
   UNLOCK(); //Perfrom the actual erase
   WREN=FALSE;
   enable_interrupts(GLOBAL);
}

void write_block(int8 *ram, int8 ctr, int16 address)
{
   //function to replace non working write
   //Warnings....
   //Writes 'ctr' bytes to the _low_ byte only of the memory block starting at 'address'
   //Must fit inside a row. No testing done to ensure this (keep space small...)
   disable_interrupts(GLOBAL); //ensure interrupts are off
   
   select_address(address);
   LWLO=TRUE;
   WREN=TRUE;
   FREE=FALSE;
   //Now need to load the latches
   do
   {
      PMDATH=0;
      PMDATL=*ram;
      ram++; //next byte
      if (--ctr==0) break;
      UNLOCK();
      PMADRL++; //Next word
   }
   while (TRUE);
   //Now all but last latch loaded
   LWLO=FALSE; //switch to physical write
   UNLOCK(); //and write the data
   WREN=FALSE;
   enable_interrupts(GLOBAL); 
}

void save_HEF(void) //copies the 8 HEF bytes to RAM buffer
{
   int16 address;
   //now read the max 8 HEF bytes
   for (address=0;address<BYTES_TO_USE;address++)
   {
      buffer[address]=read_program_eeprom(address+ADDRESS_TO_USE_FOR_STORAGE);
   }
}

void write_HEF(void)
{
   //Uses my replacement functions to write the 8 HEF bytes to ROM
   erase_row(ADDRESS_TO_USE_FOR_STORAGE); //erase entire row
   write_block(buffer,8,ADDRESS_TO_USE_FOR_STORAGE); //write the 8 HEF bytes
}

void main()
{
   while(TRUE)
   {
     
      if(input(pin_a0))
      {   
         buffer[1]=1;
         buffer[2]=2;
         buffer[3]=3;     
         buffer[7]=255;     
         write_HEF();   
      }
     
     if(input(pin_a1))
      {   
        buffer[4]=4;
        buffer[5]=5;
        buffer[6]=6;
        buffer[7]=255;     
        write_HEF();
      }
     
     
   /*   do {
      }
      while (TRUE); //stop here, don't want to write more than once...
      */
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Mon Apr 01, 2019 11:54 am     Reply with quote

The code you have written is all already there. That is what the
program_memory functions in the compiler do. You have a read,
write and erase function. The write will automatically erase if you talk
to the first byte of an erase page.
You don't need to go DIY.
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