Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

PIC18F27J13 using flash as EEPROM, in C
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

PIC18F27J13 using flash as EEPROM, in C

by zener on Sun Oct 24, 2010 12:35 am

So the PIC18Fx7Jx3 doesn't have any EEPROM. You have to use flash. I can't find any example code for this exact part but I found some code that includes:

//Write data into flash from the specified location
WriteBytesFlash((UINT32)0x6000,(UINT16)250,Write_Data);

So it looks like they are just writing to 0x6000 without reserving it or anything first.

I realize I need to set registers, etc, but my main issue is with what address to write to, and do I need to reserve it somehow or do anything special with the compiler.

Thanks

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Sun Nov 07, 2010 11:04 pm

FYI, I was able to figure this out eventually. The libraries did not support my chip technically, but I used a lot of the code from them. It has been suggested that I need to reserve the location with some #pragma code, but it did not seem to make any difference if I did or not.

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by oPossum on Mon Nov 08, 2010 2:04 am

I wonder if we are working on the same project. :)

Here is my code...

Code: Select all | TOGGLE FULL SIZE
#include <p18f27j53.h>
#include "inttypes.h"

void EraseFlashPage(uint8_t rom far *p)
{
   TBLPTRU = ((short long)p >> 16) & 0xFF;
   TBLPTRH = ((short long)p >> 8) & 0xFC;
   TBLPTRL = 0;
   EECON1bits.WREN = 1;
   EECON1bits.FREE = 1;
   INTCONbits.GIE = 0;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1bits.WR = 1;
   INTCONbits.GIE = 1;
}

void WriteFlashPage(uint8_t rom far *p, uint8_t *d)
{
   uint8_t i,j;

   i = 16;
   do {
      j = 64;
      do {
         *p++ = *d++;
      } while(--j);
      EECON1bits.WREN = 1;
      INTCONbits.GIE = 0;
      EECON2 = 0x55;
      EECON2 = 0xAA;
      EECON1bits.WR = 1;
      INTCONbits.GIE = 1;
      EECON1bits.WREN = 0;
   } while(--i);
}
I am the Possum, and I approve of this message. Sent from MacBook Wheel Sorry for my bad German.
oPossum
 
Posts: 636
Joined: Fri Oct 26, 2007 12:42 am
Location: Michigan, USA

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Mon Nov 08, 2010 4:01 pm

Interesting in your Write procedure you don't have anything like:

TABLAT = setting[9-num_bytes][0]; // load table
_asm TBLWTPOSTINC _endasm // Inc table position

Is it something to do with *p and *d?

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by oPossum on Mon Nov 08, 2010 6:29 pm

Yes, that line copies a byte from RAM to Flash.

The equivalent assembly code would be:
Code: Select all | TOGGLE FULL SIZE
movff  POSTINC0, TABLAT     ; Get a byte from RAM and increment RAM pointer
tblwtpostinc                ; Write to flash and increment flash pointer
I am the Possum, and I approve of this message. Sent from MacBook Wheel Sorry for my bad German.
oPossum
 
Posts: 636
Joined: Fri Oct 26, 2007 12:42 am
Location: Michigan, USA

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Mon Nov 08, 2010 6:46 pm

Hmmm... So you are writing 1K Bytes with that? I may need to do something like that with my bootloader. I may have to write a lot of it myself since I want to use a thumb drive in a Vdrive2 instead of a GUI and PC.

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by oPossum on Mon Nov 08, 2010 7:01 pm

Yes, that is the smallest chunk of flash that can be erased. It is possible to write 64 byte chunks, but that would have made the code more complicated. Erasing and writing 1K chunks keeps it simple.
I am the Possum, and I approve of this message. Sent from MacBook Wheel Sorry for my bad German.
oPossum
 
Posts: 636
Joined: Fri Oct 26, 2007 12:42 am
Location: Michigan, USA

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Tue Nov 09, 2010 8:04 pm

So I have seen "rom far" and "far rom". What is this all about?

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Wed Nov 10, 2010 5:28 pm

I have been studying your code some more, because there is a lot there I can learn I think. So please help me scale the wall of ignorance. Here are my questions:

1) What is type uint8_t ? I looked in GenericTypeDefs.h and didn't seem to see it there. I am guessing it is more than 8 bits since you are specifying memory locations higher than 256...

2) Does the " * " mean "relative", as in, "the data at this location"?

3) Does 'rom far' mean "program memory" (flash)? ( I have also seen it as 'far rom' which I guess is the same thing )

Thanks

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by oPossum on Thu Nov 11, 2010 12:09 am

uint8_t is in inttypes.h. The Microchip C compiler does not include this standard header file (nor does Microsoft Visual C/C++), so I use my own.
Code: Select all | TOGGLE FULL SIZE
// inttypes.h
typedef          char  int8_t;
typedef unsigned char uint8_t;
typedef          int   int16_t;
typedef unsigned int  uint16_t;


These types will always be the same size. uint8_t will always be 8 bits unsigned. This is different than the intrinsic C types. An int in C can be any size. It is usually 16 or 32 bits, but could be 8 bits (embedded systems) or 64 bits (for 64 bit mode of x86 for example). char, long, float and double can also be any size. The C standard does not require them to be any specific size.

* is used to dereference a pointer. So *p would be the data stored at the address stored in p.

*p = *d will copy what is at the address in d to the address in p.

*p++ = *d++ will do the copy and then increment both p and d.

rom designates that the pointer is for ROM/PROM/EPROM/Flash memory. The PIC is a Harvard architecture, so program and data memory are separate address spaces and require distinct pointer types.

far designates that the pointer can access addresses beyond 64K. The PIC I am using has 128K, so rom pointers must be far to access the upper 64K.

rom far and far rom are equivalent.
I am the Possum, and I approve of this message. Sent from MacBook Wheel Sorry for my bad German.
oPossum
 
Posts: 636
Joined: Fri Oct 26, 2007 12:42 am
Location: Michigan, USA

Re: PIC18F27J13 using flash as EEPROM, in C

by zener on Thu Nov 11, 2010 2:23 am

Hmmmm..

I am still getting hung up on this line:

Code: Select all | TOGGLE FULL SIZE
void WriteFlashPage(uint8_t rom far *p, uint8_t *d)


Is *p 8 bits but p is not?

p has to be more than 8 bits to increment to 1023 (at least), and I am guessing starts at an address more than 8 bits. What concept am I missing here?

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: PIC18F27J13 using flash as EEPROM, in C

by oPossum on Thu Nov 11, 2010 2:35 am

It is a rom far pointer to a uint8_t.

So p is 24 bits (far pointer to "rom") and *p is 8 bits unsigned (uint8_t at address in p).

uint8_t rom *p is a 16 bit pointer to an 8 bit unsigned value.
uint16_t rom *p is a 16 bit pointer to a 16 bit unsigned value
uint16_t rom far *p is a 24 bit pointer to a 16 bit unsigned value

d is 16 bits (pointer to register) and *d is 8 bits (uint8_t at address in d).
I am the Possum, and I approve of this message. Sent from MacBook Wheel Sorry for my bad German.
oPossum
 
Posts: 636
Joined: Fri Oct 26, 2007 12:42 am
Location: Michigan, USA

Please be positive and constructive with your questions and comments.