| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| rodrigo_cirilo 
 
 
 Joined: 31 Mar 2019
 Posts: 43
 Location: Sao paulo/Brazil
 
 
			      
 
 | 
			
				| 10F322 and HEF (virtual eeprom) |  
				|  Posted: Sun Mar 31, 2019 7:02 pm |   |  
				| 
 |  
				| 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: 132
 Location: Bombay, India
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Sun Mar 31, 2019 10:20 pm |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Apr 01, 2019 12:29 am |   |  
				| 
 |  
				| 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
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Mon Apr 01, 2019 4:59 am |   |  
				| 
 |  
				|  	  | 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: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Apr 01, 2019 5:16 am |   |  
				| 
 |  
				| 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: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  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).
 
 
 Would read a 12byte buffer from the flash. 	  | Code: |  	  | byte buffer[12]; read_program_memory(0x1E0, buffer, 12);
 
 | 
 
 
 Would write the same buffer back. 	  | Code: |  	  | write_program_memory(0x1E0, buffer, 12); | 
 
 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
 
 
			      
 
 | 
			
				|  |  
				|  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")
 
 | 
 |  |  
		|  |  
		| 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...
 */
 }
 }
 | 
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |