2004/09/29 14:43:19
Guest
I was wondering if anyone had a C function for read/writting to program memory (aka flash).

Thanks
Trampas
2004/09/29 15:21:56
lmwelder
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.
2004/09/29 15:31:26
Guest
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.
2004/09/29 15:44:03
Guest
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
2004/09/29 16:09:05
ric
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?
2004/09/30 05:52:45
Guest
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
2004/11/18 05:10:06
Guest
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;
}
2004/11/18 05:16:41
Guest
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
2005/01/13 08:31:08
Guest
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);
2005/02/18 00:33:28
Guest
Hi,

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

Thanks
Sangeetha
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account