/******************************************************************************
*  LPC1xxx PCA9500 I2C-EEPROM demoprogram for MicroCore48 board (by Paul Seerden)
*
*  1. Use Systick timer to generate a 10 msec timer tick (interrupt driven).
*  2. Use LPC1000 UART for communication with i.e HyperTerminal (115200 baud).
*  3. Use LPC1000 I2C driver for interface with PCA9500-EEPROM
*******************************************************************************/

#include <LPC13Uxx.h>                          // LPC13Uxx definitions
#include "uart.h"
#include "command.h"
#include "eeprom.h"

const char cmdTable[]  = "HE""DE""FE""RB""WB";
const char helpTable[] = "Command set:\n\n"
                         "HE <cr>             - Help on commands and syntax\n"
                         "DE <cr>             - Display EEPROM contents\n"
                         "FE <dat> <cr>       - Fill all EEPROM with dat\n"
                         "RB <add> <cr>       - Read Byte\n"
                         "WB <add> <dat> <cr> - Write Byte\n\n";

volatile LONG SysTickCnt;                      // System Tick Counter

void SysTick_Handler (void)
{                                              // SysTick Interrupt Handler (1ms)
    SysTickCnt++;
}

void Delay (LONG tick)
{
  LONG tickcnt;

    tickcnt = SysTickCnt;
    while ((SysTickCnt - tickcnt) < tick) __wfi();
}

static void CMD_DE(void)
{
  WORD addr;

    for (addr=0; addr<256; addr++)	
    {
        if ((addr & 0x1f) == 0)
        { 
            PrintString("\n");
            PrintWord(addr);
        }
        if ((addr & 0x7) == 0)
        {
            PrintString("  ");
        }
        PrintByte(EEPROM_Read(addr));
    }
    PrintString("\n");
}

static void CMD_FE(void)
{
  LONG val;
  WORD addr;

    val = GetArgument();
    if (val > 255)
    {
        PrintString("err: data beyond BYTE size\n");
        return;
    }
    for (addr=0; addr<256; addr++)	
    {
        EEPROM_Write(addr,val);
        Delay(1);                              // delay 10ms, this is needed between
    }                                          // successive writes to the EEPROM
    PrintString("\n");
}

static void CMD_RB(void)
{
  LONG addr;

    addr = GetArgument();
    if (addr < 256)
    {
        PrintWord(addr);
        PrintString (": ");
        PrintByte(EEPROM_Read(addr));
        PrintString ("\n");
    }
    else
        PrintString("Address beyond EEPROM size\n");
}

static void CMD_WB(void)
{
  BYTE cha;
  LONG addr,val;

    addr = GetArgument();
    do
    {
        if (addr > 255)
        {
            PrintString("err: address beyond EEPROM size\n");
            return;
        }
        val = GetArgument();
        if (val > 255)
        {
            PrintString("err: data beyond BYTE size\n");
            return;
        }
        EEPROM_Write(addr,val);
        Delay(1);                              // delay 10ms, this is needed between
        addr ++;                               // successive writes to the EEPROM
        cha = GetBufAsc(GetBufIndex() - 1);
    } while (cha == ',');
}

int main (void)
{
    SysTick_Config(SystemCoreClock/100);       // Generate interrupt each ~10 ms

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);       // Enable clock for GPIO
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);      // Enable clock for IOCON

    UART_Init(19200);                          // initialize UART
    EEPROM_Init();

    PrintString("\f\nTest program PCA9500 - (I2C)EEPROM, June 2012\n");
    PrintString(helpTable);
    ua_outchar('*');
    while (1)
    {
        if (ReadCommandLine())                 // returns '1' if command entered
        {
            if (GetBufAsc(0) != '\r')
            {
                switch (GetCommand(cmdTable,4))
                {
                  case 0:  PrintString(helpTable); break;    // Help
                  case 1:  CMD_DE();               break;    // Display EEPROM	
                  case 2:  CMD_FE();               break;    // Fill EEPROM	
                  case 3:  CMD_RB();               break;    // Read Byte
                  case 4:  CMD_WB();               break;    // Write Byte
                  default: PrintString("Command error\n");
                }
                SetBufIndex(0);                // reset position pointer
            }
            ua_outchar('*');
        }
    }
}
