// EEPROM_11.c, CCS, PIC16F1827
//
// copyright, Peter H. Anderson, Baltimore, MD, April, '23, '10

#ifdef DESCRIPTION

Reads preprogrammed data at EEPROM location 0x00 and displays.

Writes values to 250 bytes of high endurance data EEPROM.

Reads it back and displays on serial LCD.  Serial LCD is on RB2.

Note that the high endurance EEPROM is located at 0xF000 - 0xF0FF.

#endif

#case

#device PIC16F1827 ICD=TRUE

#include <defs_1827.h>
#include <string.h>

#rom 0x8007 = {0x09e4, 0x0003}  // Manual Section 4.0

#define TRUE 1
#define FALSE 0

byte read_eeprom(byte adr);
void write_eeprom(byte adr, byte dat);

void asynch_setup(void);
void ser_char(char ch);

void delay_10us(byte t);
void delay_ms(long t);
void delay_s(long t);


int main()
{

   byte x, adr;

   OSCCON = 0x6b; // 4.0 MHz internal

   asynch_setup();
   delay_ms(10);

   printf(ser_char, "?f");
   delay_ms(25);

   x = read_eeprom(0x00);
   printf(ser_char, "Val in EEPROM is %2x" x);
   delay_s(3);  // pause to admire

   printf(ser_char, "?f");
   delay_ms(25);

   printf(ser_char, "Writing ...");

   for (adr = 0; adr < 250; adr++)
   {
      write_eeprom(adr, 250 - adr);
   }

   delay_s(1);


   printf(ser_char, "?f");
   delay_ms(25);

   printf(ser_char, "Reading ...");

   for (adr = 0; adr < 250; adr++)
   {
      x = read_eeprom(adr);
      printf(ser_char, "?x00?y2?l"); // locate on the beginning of row 2
      printf(ser_char, "?t%2x?t%2x", adr, x);  // display each adr and data
      delay_ms(200);
   }

   printf(ser_char, "?f");
   delay_ms(25);

   while(1)
   {
      printf(ser_char, ".");
      delay_s(1);
   }

}

void write_eeprom(byte adr, byte d)
{
   byte gie_save;

   cfgs = 0;  // not configuration memory
   eepgd = 0; // high endurance EEPROM

   EEADRL  = adr;
   EEDATL = d;

   gie_save = gie; // save the gie bit

   while(gie)
   {
      gie = 0;
   }

   wren = 1;
   EECON2 = 0x55;
   EECON2 = 0xaa;
   wr = 1;      // begin programming sequence
   wren = 0;
   while(wr)
   {
   }
   eeie = 0;
   eeif = 0;

   gie = gie_save;
}

byte read_eeprom(byte adr)
{
   byte x;
   cfgs = 0;
   eepgd = 0;
   EEADRL = adr;
   rd = 1;
#asm
   NOP
   NOP
   NOP
   NOP
   NOP
#endasm
    x = EEDATL;
   return(x);
}

void ser_char(char ch)
{
    TXREG = ch;
    while(trmt == 0) // wait for trmt to return to logic one
    {
    }
}

void asynch_setup(void)
{
    txcksel = 0;    // assign TX to RB2
    trisb2 = 1;    // TX

    spen = 1;     // enable serial port
    sync = 0;     // asynchronous
    txen = 1;     // enable transmitter

    brgh = 1;
    brg16 = 1;
    SPBRGH = 0x00;
    SPBRGL = 103; // 9600 at 4.0 MHz clock
}

void delay_s(long t)
{
   while(t--)
   {
      delay_ms(1000);
   }
}

void delay_ms(long t)   // delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}

void delay_10us(byte t)
{
#asm
//      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}

#rom 0xf000 = {0x15} // initialize location 0x00