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
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