• AVR Freaks

Locked[FAQ]Program Memory / Internal EEPROM Reads and Writes

Page: < 1234 > Showing page 2 of 4
Author
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/02 14:20:22 (permalink)
0
I am trying to write to flash/program memory.
 
I have been looking at Trampas Sterns code as posted in this forum. His code is
for the p18f8680 but I am working with a p18f452. His code uses a register
called EEADRH (which is defined in p18f8680.h) but the p18f452 does not define
this register. In the p18F452.asm file there is the following definition:
EEADR               RES 1     ; 0xFA9
                       RES 1
It appears to me that the second byte (0xFAA?) is the byte corresponding to the
p18f8680 EEADRH register, but for some reason it is not named. I am new to
microcontroller programming and I'm not used to all this low-level stuff so I'm
not sure how best to modify Trampas's code to make it work for the p18f452.
My initial thought is to simply change the start of his EEpromPut function from:
 
void EEpromPut(UWORD addr, BYTE data)
{
  UWORDbytes temp;
  temp.data=addr;    //could use cast instead
  EEADRH = temp.high;
  EEADR = temp.low;
  ...
to:
 
void EEpromPut(UWORD addr, BYTE data)
{
  EEADR = addr;
  ...
 
Is this correct?
 
#21
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/02 14:41:22 (permalink)
0
Further to my last post, and thanks to Kalpak for pointing out that Trampas's code is
for writing to EEPROM, not flash memory. Can I modify his code to write to
flash by simply changing the EEPGD bit as follows?
 
His code:
void EEpromPut(UWORD addr, BYTE data)
{
  ....
  EECON1bits.EEPGD = 0;
  ....
 
Change to:
void EEpromPut(UWORD addr, BYTE data)
{
  ....
  EECON1bits.EEPGD = 1;
  ....
 
Thanks, David.

#22
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/02 17:55:04 (permalink)
0
It appears that the answer to my most recent question is NO.
So please don't bother to point this out.
 
#23
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/02 21:08:28 (permalink)
0
I'm still trying to find out how to write C code to write to program memory.
I'm not getting very far with this.
I wrote the following program based on code posted by Sekhar:
 
#include <p18F452.h>
rom unsigned char* startblock = 0x5000; // any number divisible by 64
rom unsigned char* buf; // temporary rom pointer
unsigned char mem[64] = "test"; // data holding buffer
void WriteDataToMemory(int block_no) {
  unsigned char i;
  TBLPTR = (unsigned int)(startblock + block_no * 64);
  buf = (rom unsigned char*)TBLPTR;
  EECON1bits.EEPGD = 1; // erase sequence
  EECON1bits.WREN = 1;
  EECON1bits.FREE = 1;
  INTCONbits.GIE = 0;
  EECON2 = 0x55;
  EECON2 = 0xaa;
  EECON1bits.WR = 1;
  Nop();
  INTCONbits.GIE = 1;
  EECON1bits.WREN = 0;
  for(i = 0;i < 64;i++){
    buf = mem;
    if(((i + 1) % 8) == 0){
      EECON1bits.EEPGD = 1; // write sequence for every 8 bytes
      EECON1bits.WREN = 1;
      INTCONbits.GIE = 0;
      EECON2 = 0x55;
      EECON2 = 0xaa;
      EECON1bits.WR = 1;
      Nop();
      INTCONbits.GIE = 1;
      EECON1bits.WREN = 0;
    }
  }
}
void main(void) {
  WriteDataToMemory(0);
  while(1);
}
I expected the string "test" to show up at 0x5000 in program memory after
running the program, but it didn't. I was not completely surprised by this
because this code does not seem to correspond to the guidelines given in the
datasheet (where are the holding registers getting filled?). The only other C
code that I found in this thread is an excerpt from a bootloader and it does not
make any sense to me at all.
Does anyone have any easily understandable and well-documented code that I could
use/modify to write a string to flash memory (please)?
Regards, David.

#24
kalpak
Super Member
  • Total Posts : 3265
  • Reward points : 0
  • Joined: 2004/03/12 23:01:40
  • Location: India
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/02 21:20:00 (permalink)
0
Add this to the beginning of your code and check

EECON1bits.EEPGS = 1

This is for selecting the flash
#25
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/03 12:29:17 (permalink)
0
ORIGINAL: kalpak

Add this to the beginning of your code and check

EECON1bits.EEPGS = 1

This is for selecting the flash

 
There is no EECON1bits.EEPGS. I presume you mean EEPGD, which I have set to 1 already.
#26
kalpak
Super Member
  • Total Posts : 3265
  • Reward points : 0
  • Joined: 2004/03/12 23:01:40
  • Location: India
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/03 12:42:54 (permalink)
0
A typo, try:

EECON1bits.CFGS=0;


Still a typo, it should be:

EECON1bits.CFGS=1;
post edited by kalpak - 2006/02/03 13:36:11
#27
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/03 13:21:13 (permalink)
0
ORIGINAL: kalpak

A typo, try:

EECON1bits.CFGS=0;


 
Thanks, I have added that line, which I had overlooked previously. But it still doesn't write to flash memory. I can't see where the program is telling the processor which data to put into flash. The datasheet says that one must load the 8 holding registers with the data to be written for each 8-byte write, but this code does not seem to do that. The only line in the writing sequence code that might be indicating what to write is:
    buf = mem;
which I have altered to:
    buf = (rom unsigned char*) mem;
to suppress a compiler warning. But what on earth is "buf = mem" supposed to be doing? It seems to me that this line should be replaced with code to load the holding registers.
In the datasheet there is some assembly code that does this:
PROGRAM_LOOP
  MOVLW 8           ; number of bytes in holding register
  MOVWF COUNTER
WRITE_WORD_TO_HREGS
  MOVF POSTINC0, W  ; get low byte of buffer data
  MOVWF TABLAT      ; present data to table latch
  TBLWT+*           ; write data, perform a short write
                    ; to internal TBLWT holding register.
  DECFSZ COUNTER    ; loop until buffers are full
  BRA WRITE_WORD_TO_HREGS
but I'm not clear how to do this in C.
#28
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 15:51:08 (permalink)
0
This is my latest attempt at writing a block of ram to flash:
 
#include <p18F452.h>
void memcpyram2flash(unsigned addr, char * mem) {
 unsigned char i;
 TBLPTR = addr;
 //TBLPTR <<= 6;  // erasure uses TBLPTR bits [21:6] to point to program memory address
 // erase row of 64 bytes starting at TBLTPTR address
 EECON1bits.EEPGD = 1;
 EECON1bits.WREN = 1;
 EECON1bits.FREE = 1;
 EECON1bits.CFGS = 0;
 INTCONbits.GIE = 0;
 EECON2 = 0x55;
 EECON2 = 0xaa;
 EECON1bits.WR = 1;
 Nop();
 INTCONbits.GIE = 1;
 EECON1bits.WREN = 0;
 //TBLPTR >>= 3; // TBLWT uses [21:3] to point to memory address, [2:0] identifies
        // each of the eight holding registers
 for(i = 0;i < 64;i++){
  TABLAT = mem;    // put a char into the table latch register
  _asm
   TBLWTPOSTINC     // write to holding register and post-increment TBLPTR
  _endasm
  if(((i + 1) % 8) == 0){ // after each 8-byte write to holding registers...
   EECON1bits.EEPGD = 1; // ...write the holding registers to flash
   EECON1bits.WREN = 1;
   EECON1bits.CFGS = 0;
   EECON1bits.FREE = 0;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xaa;
   EECON1bits.WR = 1;
   Nop();
   INTCONbits.GIE = 1;
   EECON1bits.WREN = 0;
  }
 }
}
 
void main(void) {
 // write test string to address 0x5000 in program memory
 char mem[64] = "test"; // string to be copied to flash
 memcpyram2flash(0x5000, mem);
 while(1);
}
 
It still doesn't seem to work. I'm not sure how to interpret the information in the datasheet about the various bits of the TBLPTR that are used for reading, erasing and writing so I experimented with shifting the bits around, but that did not help so I have commented those lines out.
 
Any suggestions please?
#29
kalpak
Super Member
  • Total Posts : 3265
  • Reward points : 0
  • Joined: 2004/03/12 23:01:40
  • Location: India
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 19:35:13 (permalink)
0
Please see my typo above, the CFGS bit selects EERPOM or flash. It should be:

EECON1bits.CFGS=1;

 
#30
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 19:43:15 (permalink)
0
ORIGINAL: kalpak

Please see my typo above, the CFGS bit selects EERPOM or flash. It should be:

EECON1bits.CFGS=1;



 
I'll try it, but it doesn't seem right.
This is what it says in the PIC18FXX2 datasheet:
 
bit 6 CFGS: FLASH Program/Data EE or Configuration Select bit
1 = Access Configuration registers
0 = Access FLASH Program or Data EEPROM memory
#31
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 19:49:59 (permalink)
0
I have also tried decrementing the TBLPTR prior to setting the WR bit to ensure that TBLPTR is pointing to the start of the correct 8-byte block (there is a note about this in the datasheet). But that didn't help either:
 
 for(i = 0;i < 64;i++){
  TABLAT = mem;    // put a char into the table latch register
  _asm
   TBLWTPOSTINC     // write to holding register and post-increment TBLPTR
  _endasm
  if(((i + 1) % 8) == 0){ // after each 8-byte write to holding registers...
   TBLPTR -= 8;
   EECON1bits.EEPGD = 1; // ...write the holding registers to flash
   EECON1bits.WREN = 1;
   EECON1bits.CFGS = 0;
   EECON1bits.FREE = 0;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xaa;
   EECON1bits.WR = 1;
   Nop();
   INTCONbits.GIE = 1;
   EECON1bits.WREN = 0;
   TBLPTR += 8;
  }
 }
#32
kalpak
Super Member
  • Total Posts : 3265
  • Reward points : 0
  • Joined: 2004/03/12 23:01:40
  • Location: India
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 20:06:12 (permalink)
0
You are right, the CFGS bit is not for that purpose, that is the EEPGD.
#33
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 22:01:14 (permalink)
0
I have discovered that this program was actually writing to memory. I did not realise that I had to read the flash memory into MPLAB in order to view it in the program memory viewing window. When I did this I found the test string at 0x5000 as expected. The final code is as follows:
 
#include <p18F452.h>

void memcpyram2flash(unsigned addr, char * mem) {
 unsigned char i;
 TBLPTR = addr;
 EECON1bits.EEPGD = 1;
 EECON1bits.CFGS = 0;
 EECON1bits.WREN = 1;
 EECON1bits.FREE = 1;
 INTCONbits.GIE = 0;
 EECON2 = 0x55;
 EECON2 = 0xAA;
 EECON1bits.WR = 1;
 Nop();
 INTCONbits.GIE = 1;
 EECON1bits.WREN = 0;
 
 for(i = 0;i < 64;i++){
  TABLAT = mem;    // put a char into the table latch register
  _asm
   TBLWTPOSTINC     // write to holding register and post-increment TBLPTR
  _endasm
  if(((i + 1) % 8) == 0){ // after each 8-byte write to holding registers...
   TBLPTR -= 8;// temporarily put TBLPTR back into the range to be written to
   EECON1bits.EEPGD = 1; // ...write the holding registers to flash
   EECON1bits.CFGS = 0;
   EECON1bits.WREN = 1;
   EECON1bits.FREE = 0;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1bits.WR = 1;
   Nop();
   INTCONbits.GIE = 1;
   EECON1bits.WREN = 0;
   TBLPTR += 8;// put the TBLPTR back where it should be
  }
 }
}
void main(void) {
 // write test string to address 0x5000 in program memory
 char mem[64] = "test"; // string to be copied to flash
 memcpyram2flash(0x5000, mem);
 Nop();
 while(1);
}
 
I hope this is of some help to others in the future. It was very difficult for me to locate C code to do this.
Thanks to Kalpak for your suggestions.
#34
ric
Super Member
  • Total Posts : 24605
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/04 23:08:26 (permalink)
0
If you select your code, and click on the "<%" button, you won't get those formatting errors in this forum...

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#35
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/05 01:03:03 (permalink)
0
ORIGINAL: ric

If you select your code, and click on the "<%" button, you won't get those formatting errors in this forum...

 
OK, I noticed something was wrong, it did not include the index of the array mem. This confused me about the original code I downloaded from this forum by Sekhar: he had a line "buf = mem" which didnt make any sense to me. I think it was probably meant to be

buf = mem[i].

Here is my working code again:
 

#include <p18F452.h>

void memcpyram2flash(unsigned addr, char * mem) {
 unsigned char i;
 TBLPTR = addr;
 EECON1bits.EEPGD = 1;
 EECON1bits.CFGS = 0;
 EECON1bits.WREN = 1;
 EECON1bits.FREE = 1;
 INTCONbits.GIE = 0;
 EECON2 = 0x55;
 EECON2 = 0xAA;
 EECON1bits.WR = 1;
 Nop();
 INTCONbits.GIE = 1;
 EECON1bits.WREN = 0;
 
 for(i = 0;i < 64;i++){
  TABLAT = mem[i];    // put a char into the table latch register
  _asm
   TBLWTPOSTINC     // write to holding register and post-increment TBLPTR
  _endasm
  if(((i + 1) % 8) == 0){ // after each 8-byte write to holding registers...
   TBLPTR -= 8;
   EECON1bits.EEPGD = 1; // ...write the holding registers to flash
   EECON1bits.CFGS = 0;
   EECON1bits.WREN = 1;
   EECON1bits.FREE = 0;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1bits.WR = 1;
   Nop();
   INTCONbits.GIE = 1;
   EECON1bits.WREN = 0;
   TBLPTR += 8;
  }
 }
}
void main(void) {
 // write test string to address 0x5000 in program memory
 char mem[64] = "test"; // string to be copied to flash
 memcpyram2flash(0x5000, mem);
 Nop();
 while(1);
}


#36
Guest
Super Member
  • Total Posts : 80500
  • Reward points : 0
  • Joined: 2003/01/01 00:00:00
  • Location: 0
  • Status: online
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/23 01:13:05 (permalink)
0
i have a question, your program runs on debugger or programmer. where should i view the data that was saved? in program memory or EEPROM?
#37
kalpak
Super Member
  • Total Posts : 3265
  • Reward points : 0
  • Joined: 2004/03/12 23:01:40
  • Location: India
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/23 02:20:32 (permalink)
0
ORIGINAL: boi^boi

i have a question, your program runs on debugger or programmer. where should i view the data that was saved? in program memory or EEPROM?

 
The program never runs in the debugger or the programmer. It runs on the chip. If you use the debugger, you can see the data in the memory you have programmed, if destination was EEPROM then EEPROM window is where you see.
#38
DavidP5
Super Member
  • Total Posts : 472
  • Reward points : 0
  • Joined: 2006/02/01 23:23:40
  • Location: New Zealand
  • Status: offline
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/23 18:20:42 (permalink)
0
I use the ICD2. The code I posted works in debug mode or in "normal" mode (you just have to change the linker script etc). This is code for writing to flash program memory so you will look for the results in program memory (at 0x5000 in the program I posted, but you can write anywhere you like). To view the program memory I click on the "read target device" button in MPLAB, then I choose View>Program Memory from the menus, then scroll down to 0x5000.
#39
Guest
Super Member
  • Total Posts : 80500
  • Reward points : 0
  • Joined: 2003/01/01 00:00:00
  • Location: 0
  • Status: online
RE: Program Memory / Internal EEPROM Reads and Writes 2006/02/23 22:10:44 (permalink)
0
if i were to use programmer, wad are the areas i need to change? anywa i tried ya program. the word "test" don appear in program memory, it appear in file register. i tried to used other libraries like memcpypgm2ram and the same ting appear in file register.
post edited by boi^boi - 2006/02/25 01:44:51
#40
Page: < 1234 > Showing page 2 of 4
Jump to:
© 2019 APG vNext Commercial Version 4.5