• AVR Freaks

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

Page: 1234 > Showing page 1 of 4
Author
Guest
Super Member
  • Total Posts : 80500
  • Reward points : 0
  • Joined: 2003/01/01 00:00:00
  • Location: 0
  • Status: online
2004/09/29 14:43:19 (permalink)
0

Program Memory / Internal EEPROM Reads and Writes

I was wondering if anyone had a C function for read/writting to program memory (aka flash).

Thanks
Trampas
< Message edited by KajitaJ2 -- Nov. 15, 2004 5:59:19 PM >
#1

72 Replies Related Threads

    lmwelder
    Junior Member
    • Total Posts : 98
    • Reward points : 0
    • Joined: 2003/11/07 12:41:33
    • Location: Ventura, CA
    • Status: offline
    RE: Program Memory Reads and Writes 2004/09/29 15:21:56 (permalink)
    0
    Have you checked out the functions in MPLAB C18 C Compiler Libraries Manual, section 4.4 "Memory and String Manipulation Functions"?

    memcpypgm2ram, etc.

    or

    save/load data memory to flash

    If you search the forum, there are probably many more examples.
    #2
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2004/09/29 15:31:26 (permalink)
    0
    Attached is what I received from microchip tech support. I used a cleaned up version of the flash functions. Also, I remember the test routine is a little buggy, but, the functions are correct. Finally, depending on which silicon you are using, the FLASH write will fail if any interrupt flags become active. Disabling interrupts does not help, you need to stop any process, which could cause an interrupt flag to beome active. Its quite a hassle.

    Good luck,
    Kevin
    www.checkeffect.net

    Below is tech support comments:
    ----------------------------
    Hi Kevin,

    Please see the attached C18_Flash.zip file. Please be sure to fully test
    this code in your application.
    < Message edited by KajitaJ2 -- Sep. 29, 2004 9:16:26 PM >
    #3
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2004/09/29 15:44:03 (permalink)
    0
    Kevin,

    Thanks for the information and the files. As far as the interrupt flags becoming active would this not be a big problem with RB and external interrupts? Do you have more information about this problem? I was thinking I could set all the Interrupt Flags to 1 before startting writting to flash, would this help?

    Thanks again
    Trampas
    #4
    ric
    Super Member
    • Total Posts : 24624
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    RE: Program Memory Reads and Writes 2004/09/29 16:09:05 (permalink)
    0
    The flags are level based, not edge based, so that would be a very bad idea.
    I would guess clearing all the IE flags should work.
    I was thinking I could set all the Interrupt Flags to 1 before startting writting to flash, would this help?

    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!
    #5
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2004/09/30 05:52:45 (permalink)
    0
    Ric,

    I guess I do not understand the problem, maybe some more information would help.

    What I was thinking is that if a PORT RB change happened after I cleared the flag, then the flag would get set. Yea I was assuming this would trigger some hardware to do something (aka edge triggered). However if I set the flag before hand, with interrupts disabled, then the flag would not change thus the hardware would not do anything.

    So I guess I am confused as to the details of the interrupt problem, do you have any information from Microchip?

    I guess if this interrupt flag is a problem for the external interrupts and the port B pins you would need to configure the ports as output and drive low, before starting firmware update.

    Trampas
    #6
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2004/11/18 05:10:06 (permalink)
    0
    OK I wrote some code here for read/write eeprom. Yes I often reinvent the wheel for better understanding...

    There is some interesting stuff in here for newbies like the datatypes.h. I always define my own datatypes as that as you start porting code to other processors you will find this will save you days of debugging. For example one compiler defines a int to be a unsigned byte, while others define it to be a signed byte....

    By the way you are all welcome to use this code, maybe one day if I make it to the Microchip training someone can buy me a beer if they found it useful.


    //Datatypes.h
    *
    * DESCRIPTION:
    *
    * AUTHOR : Trampas Stern
    *
    * DATE : 7/30/2004 2:34:24 PM
    *
    * FILENAME: datatypes.h
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    #ifndef __DATATYPES_H
    #define __DATATYPES_H

    typedef unsigned char UINT;
    typedef signed char INT;
    typedef char CHAR;
    typedef unsigned short UWORD;
    typedef signed char BYTE;
    typedef signed char UBYTE;
    typedef signed short WORD;
    typedef unsigned long UDWORD;
    typedef signed long DWORD;
    typedef float FLOAT;

    typedef union {
    UWORD data ;
    struct {
    BYTE low;
    BYTE high;
    };
    } UWORDbytes;


    typedef union {
    UDWORD data ;
    struct {
    BYTE byte0;
    BYTE byte1;
    BYTE byte2;
    BYTE byte3;
    };
    struct {
    UWORD word0;
    UWORD word1;
    };
    } UDWORDbytes;


    typedef union {
    UBYTE byte;
    struct {
    unsigned bit0:1;
    unsigned bit1:1;
    unsigned bit2:1;
    unsigned bit3:1;
    unsigned bit4:1;
    unsigned bit5:1;
    unsigned bit6:1;
    unsigned bit7:1;
    };
    } UBYTEbits;

    #define MAX_UDWORD 0xFFFFFFFF

    #endif //__DATATYPES_H



    //eeprom.h header
    #ifndef __EEPROM_H
    #define __EEPROM_H

    #include "datatypes.h"
    //#include "system.h" //This is where I define stuff such as Fosc

    BYTE EEpromGet(UWORD addr);
    void EEpromPut(UWORD addr, BYTE data);
    UBYTE EEpromRead(UWORD addr, UBYTE *data, UWORD len);
    UBYTE EEpromWrite(UWORD addr, UBYTE *data, UWORD len);

    #endif //__EEPROM_H



    #include "eeprom.h"

    /*******************************************************************
    * FUNCTION: EEpromGet
    * AUTHOR = TRAMPAS STERN
    * FILE = eeprom.c
    * DATE = 11/4/2004 8:24:41 AM
    *
    * PARAMETERS:
    *
    * DESCRIPTION: Gets a byte of data from EEPROM
    *
    * RETURNS:
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    BYTE EEpromGet(UWORD addr)
    {
    volatile BYTE eepTemp;
    UWORDbytes temp;
    temp.data=addr;
    EEADRH = temp.high;
    EEADR = temp.low;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.RD = 1;
    eepTemp = EEDATA;
    return eepTemp;
    }

    /*******************************************************************
    * FUNCTION: EEpromPut
    * AUTHOR = TRAMPAS STERN
    * FILE = eeprom.c
    * DATE = 11/4/2004 8:55:20 AM
    *
    * PARAMETERS:
    *
    * DESCRIPTION:
    *
    * RETURNS:
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    void EEpromPut(UWORD addr, BYTE data)
    {
    UWORDbytes temp;
    temp.data=addr; //could use cast instead
    EEADRH = temp.high;
    EEADR = temp.low;
    EEDATA = data;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.WREN = 1;

    DISABLE_INTERRUPTS();
    _asm
    MOVLW 0x55
    MOVWF EECON2,0
    MOVLW 0xAA
    MOVWF EECON2,0
    _endasm
    EECON1bits.WR=1;
    while (EECON1bits.WR == 1);
    ENABLE_INTERRUPTS();

    EECON1bits.WREN = 0;
    }

    /*******************************************************************
    * FUNCTION: EEpromWrite
    * AUTHOR = TRAMPAS STERN
    * FILE = eeprom.c
    * DATE = 11/5/2004 7:55:18 AM
    *
    * PARAMETERS:
    *
    * DESCRIPTION:
    *
    * RETURNS:
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    UBYTE EEpromWrite(UWORD addr, UBYTE *data, UWORD len)
    {
    UWORD i;

    for(i=0; i<len; i++)
    {
    EEpromPut(addr++,data[i]);
    }
    return i;
    }

    /*******************************************************************
    * FUNCTION: EEpromRead
    * AUTHOR = TRAMPAS STERN
    * FILE = eeprom.c
    * DATE = 11/5/2004 7:56:40 AM
    *
    * PARAMETERS:
    *
    * DESCRIPTION:
    *
    * RETURNS:
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    UBYTE EEpromRead(UWORD addr, UBYTE *data, UWORD len)
    {
    UWORD i;

    //printf("eeprom read %uhd\n\r",len);
    for(i=0; i<len; i++)
    {
    data[i]=EEpromGet(addr++);
    //printf("%x ", data[i]);
    }
    return i;
    }
    #7
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2004/11/18 05:16:41 (permalink)
    0
    I forgot that I used some macros from my system.h header file...


    /*******************************************************************
    *
    * DESCRIPTION:
    *
    * AUTHOR : Trampas Stern
    *
    * DATE : 7/30/2004 2:37:41 PM
    *
    * FILENAME: system.h
    *
    * Copyright 2004 (c) by Trampas Stern
    *******************************************************************/
    #ifndef __SYSTEM_H
    #define __SYSTEM_H

    #include <p18f8680.h>
    #include "datatypes.h"

    #define DATA_MEM_LIMIT 0x1000

    //frequency of oscilation...
    #define MHZ e6
    #define FOSC 40000000
    #define SYS_CLK (FOSC/4)
    #define GET8(x,n) ((x>>(n*8) & 0xFF))
    #define MAKE16(x,y) (((((WORD)x)<<8)) | ((WORD)y))
    #define BIT_SET(x,n) (x=x | (0x01<<n))
    #define BIT_TEST(x,n) ((x & (0x01<<n))!=0)
    #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n))
    #define MAKEWORD(x,y) ((((UWORD)x)<<8) | (UWORD)y)

    #include <float.h> //Include float.h for FLT_MAX in DIV macro
    #define ABS(x) ((x) > 0 ? (x) : -(x))
    #define DIV(x,y) ((y==0)?FLT_MAX:x/y) //avoid division by zero

    #define HALT() while(1){}

    #define DISABLE_INTERRUPTS() {while(INTCONbits.GIE) INTCONbits.GIE=0;}
    #define ENABLE_INTERRUPTS() {INTCONbits.GIE=1;}


    #endif __SYSTEM_H
    #8
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2005/01/13 08:31:08 (permalink)
    0
    I'm sure that I should know why this is but I don't. I have tried several of the EEPROM routines posted to see which I like best. The one the is in the "Attachement (1)" file I am using right now but I get a suspicous pointer conversion from this line in the *memcpyde2ram function. Do you know why?

    *(s1+n) = readDataEE(s2+n);
    #9
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2005/02/18 00:33:28 (permalink)
    0
    Hi,

    I would like to get some information on how to search a data in EEPROM in C program.

    Thanks
    Sangeetha
    < Message edited by kamatchi -- Feb. 18, 2005 12:34:29 AM >
    #10
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    Internal EEPROM Reads and Writes 2005/08/01 21:40:13 (permalink)
    0
    I am having a problem reading from the internall EEPROM memory. I am using the learning version of the C18 compiler, ICD2 programmer, and my target is the 18F452 on the PICDEM2+ board.

    My problem is that I am unable to read the internal eeprom until after I have unplugged the board from the programmer and removed power from the board. Until I do this, my read function just returns 0. It does not seem to matter whether the data is going into the eeprom from my program or if it is being programmed by the programmer.

    This is my code to write to the eeprom:

    void eeprom_write (char *buffer) // write string to eeprom
    {
    unsigned int eeaddress = 0;
    char letter;
    PIE1bits.TMR1IE = 0; // disable timer1 interrupt
    EECON1bits.EEPGD = 0; // address eeprom, not program
    EECON1bits.WREN = 1; // Write enable
    while(*buffer) //
    {
    EEADR = eeaddress;
    letter = (*buffer);
    EEDATA = letter;
    EECON2 = 0x55; // I'm told you must do this
    EECON2 = 0xAA; // and this too
    EECON1bits.WR = 1;
    while (EECON1bits.WR)
    Nop (); // wait for write to complete
    eeaddress++; // point to next storage location
    buffer++; // Increment buffer
    }
    EEADR = eeaddress;
    EEDATA = (*buffer);
    EECON1bits.WR = 1; // store null character at end of string
    PIE1bits.TMR1IE = 1; // enable timer1 interrupt
    while (EECON1bits.WR)
    Nop (); // wait for write to complete
    return;
    }

    This is the code to read from the eeprom:

    void eeprom_read (void) // read string from eeprom
    {
    unsigned char j = 0;
    char read;


    do {

    EEADR = j;
    EECON1bits.EEPGD = 0; // address eeprom, not program
    EECON1bits.RD = 1;
    read = EEDATA;
    incoming[j] = read;
    j++; // point to next storage location
    }
    while(read); // read data from eeprom up through null

    return;
    }


    Has anyone else encountered this? The source file is attached (I think).

    Thanks,
    -Maarten
    #11
    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 2005/08/05 03:08:27 (permalink)
    0
    I 've some questions before I plan a small database with my PIC 18F242:

    Is it necessary to erase the program data before write it ?
    Is there a diffrence between write 0xFF and erase ?
    So it would be possible to erase less thean 64kbytes ?

    What will happen after 100.000 cyles of write-program-memory operation ?

    Thanks for help!
    #12
    jspaarg
    Super Member
    • Total Posts : 2926
    • Reward points : 0
    • Joined: 2005/05/25 16:47:08
    • Location: PA, now MN via NJ,AZ,OR,CA
    • Status: offline
    RE: Program Memory / Internal EEPROM Reads and Writes 2005/08/05 05:36:50 (permalink)
    0
    You have to perform an erase operation prior to performing a write; writing 0xff is not the same thing.

    You don't erase 64K at a time from internal code. The block size changes based on the PIC, but 64 bytes is typical. Read the datasheet.

    After 100,000 write cycles, the ability of the memory to be erased and hold new data is not guaranteed. There is nothing magical about the 100,001st write. The chip may work to 150,000; but there is no guarantee.

    Read the datasheet for the 242, it will provide sample code on erasing and writing FLASH.
    #13
    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 2005/08/05 08:00:54 (permalink)
    0
    I read the datasheet for th ePIC 18F2424 100 times, but I couldn`t find any note, that I have to erase before I write.
    But in AN910 on page 12 I found:
    "For all devices except the PIC18 family, erase is generally
    handled as part of the programming command. All
    devices use an “Erase Program” command, which
    automatically blanks the target location before writing
    new data to it."
    So I guess only the PIC 18.. have to be erased before write.

    Can I use "memcpyram2pgm" to handle this very easy, or do I have to use the inline assembly ?
    #14
    jspaarg
    Super Member
    • Total Posts : 2926
    • Reward points : 0
    • Joined: 2005/05/25 16:47:08
    • Location: PA, now MN via NJ,AZ,OR,CA
    • Status: offline
    RE: Program Memory / Internal EEPROM Reads and Writes 2005/08/05 08:54:38 (permalink)
    0
    Try reading sections 5.4 and 5.5 (especially 5.5.1) for the 101st time.
    #15
    chsekhar
    New Member
    • Total Posts : 30
    • Reward points : 0
    • Joined: 2005/01/10 21:59:38
    • Status: offline
    RE: Program Memory / Internal EEPROM Reads and Writes 2005/09/13 22:00:02 (permalink)
    0
    Hi,

    I wrote C functions for writing data to flash memory and used in my project successfully.

    /**************************************************
    FUNCTION TO WRITE WHOLE BLOCK OF 64 BYTES
    **************************************************/

    rom unsigned char* startblock = 0x5000; // any number divisible by 64
    rom unsigned char* buf; // temporary rom pointer
    unsigned char mem[64]; // 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;
    }
    }
    }


    /**************************************************
    FUNCTION TO WRITE A BYTE TO SPECIFIC LOCATION
    **************************************************/

    void WriteByteToMemory(rom unsigned char* addr,unsigned char b)
    {
    unsigned char i;

    // identify block(64 bytes)
    unsigned char off = (unsigned int)addr % 64; // offset
    TBLPTR = (unsigned int)(addr - off); // base

    // backup 64 bytes
    buf = (rom unsigned char*)TBLPTR;
    for(i = 0;i < 64;i++){
    mem = buf;
    }
    mem[off] = b; // modify byte at base + off

    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++){ // write back 64 bytes after modification
    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;
    }
    }
    }

    HOWEVER FOR READING FLASH MEMORY IT IS STRAIT FORWARD

    data = buf[0]; // read byte from the address location (buf + 0)


    -Sekhar
    #16
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Internal EEPROM Reads and Writes--Solved the problem 2005/10/02 20:10:49 (permalink)
    0
    I reported earlier about having to do a cold reboot on my project before I could write to the EEPROM data memory.

    I am using an 18F452 and programming with an ICD2. I dilligently copied the assembly code in section 6 "DATA EEPROM MEMORY" into C. But until I disconnected the programmer and removed power from the board, I was unable to read anything but garbage back from the EEPROM memory. After removing power for a while (5 seconds) the board would start behaving as expected.

    I finally guessed that some register bit somewhere was being set during programming, and needed to be cleared, which the cold reboot accomplished. The most likely was bit 6 of the EECON1 register. By adding the line

    EECON1bits.CFGS = 0; // access data registers

    I got the board to function as expected even while connected to the ICD2.

    -Maarten
    #17
    ric
    Super Member
    • Total Posts : 24624
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    RE: Internal EEPROM Reads and Writes--Solved the problem 2005/10/02 20:23:30 (permalink)
    0
    ORIGINAL: mkorringa

    ...I finally guessed that some register bit somewhere was being set during programming, and needed to be cleared, which the cold reboot accomplished. The most likely was bit 6 of the EECON1 register. By adding the line

    EECON1bits.CFGS = 0; // access data registers

    I got the board to function as expected even while connected to the ICD2.

    Do not assume the power-on state of any SFR that you depend upon, and you'll never get bitten by this sort of problem.
    That said, your post will be useful to other people striking a similar problem :)

    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!
    #18
    lukez
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2005/11/02 23:07:20
    • Status: offline
    RE: Program Memory Reads and Writes 2005/11/02 23:09:21 (permalink)
    0
    Trampas, thanks for the sample code you posted here, as well as elsewhere in the forums. Your posts are always useful.

    I have a question though in your Datatypes.h file. You have these two typedefs:
    typedef signed char BYTE;
    typedef signed char UBYTE;

    Don't you mean the second one to be:
    typedef UNsigned char UBYTE;

    ??


    Luke
    #19
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: Program Memory Reads and Writes 2005/12/05 14:27:22 (permalink)
    0
    ORIGINAL: dcs1212

    I'm sure that I should know why this is but I don't. I have tried several of the EEPROM routines posted to see which I like best. The one the is in the "Attachement (1)" file I am using right now but I get a suspicous pointer conversion from this line in the *memcpyde2ram function. Do you know why?

    *(s1+n) = readDataEE(s2+n);


    This solves your warning
    *(s1+n) = readDataEE(s2[n]);

    Pointer math :P
    #20
    Page: 1234 > Showing page 1 of 4
    Jump to:
    © 2019 APG vNext Commercial Version 4.5