![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Apr 01, 2019 6:20 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
rodrigo_cirilo
Joined: 31 Mar 2019 Posts: 43 Location: Sao paulo/Brazil
|
|
Posted: Mon Apr 01, 2019 7:17 am |
|
|
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")
|
|
|
![](templates/subSilver/images/spacer.gif) |
rodrigo_cirilo
Joined: 31 Mar 2019 Posts: 43 Location: Sao paulo/Brazil
|
|
Posted: Mon Apr 01, 2019 11:42 am |
|
|
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...
*/
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Apr 01, 2019 11:54 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|