#include "quattro_regs.h"
#include "8_x_6_charset.h"

void delay(int delay);
void init_lcd(void);
void lcd_putchar(unsigned char c);
void lcd_print_crlf(char *s);
void set_line(unsigned char line);
void lcd_clear(void);
void i2c_write(unsigned data);
void toggle_led(void);
void print_page1(void);
void print_page2(void);
void print_page3(void);
void page_delay(void);


#define CHAR_DELAY 100
#define LINE_DELAY 100
#define BLINK_DELAY 1000
#define CLEAR_DELAY 40000

#define ON 0
#define OFF 1

static unsigned char line_ctr;
static unsigned char led1,led2;
static unsigned time_to_clear;
static unsigned blink_delay;


void main(void)
{  
  line_ctr = 0;
  time_to_clear = CLEAR_DELAY;
  blink_delay = 0;
  init_lcd();
  lcd_clear();
  led1 = ON;
  led2 = OFF;
  while(1)
  {
      print_page1();
      page_delay();
      print_page2();
      page_delay();
      print_page3();
      page_delay();      
  }
} /* blinky_main */

void delay(int delay)
{
   while (delay)
   {
      delay--;
   }
} /* delay */

void init_lcd(void)
{
   /* Enable I2C1 clock */
   *I2CCLK_CTRL = 0x1;
   *I2C1_CLK_CTRL_HI = 0x41;
   *I2C1_CLK_CTRL_LO = 0x41;
} /* init_lcd */

void lcd_putchar(unsigned char c)
{
   int i;
   for(i=0;i<6;i++)
   {
      i2c_write(charset[(c-32)][i]);
   }
} /* lcd_putchar */

void lcd_print_crlf(char *s)
{
   if(line_ctr > 4)
   {
      line_ctr = 0;
   }
   set_line(line_ctr);
   while ( *s != 0 )
   {
      lcd_putchar(*s++);
   }
   line_ctr++;
} /* lcd_print_crlf */

void set_line(unsigned char line)
{
   i2c_write(0x17A);
   i2c_write((0x60+line));
   i2c_write(0x0);
} /* set_line */

void lcd_clear(void)
{
   int i,j;
   for(i=0;i<5;i++)
   {
   set_line(i);
      for(j=0;j<16;j++)
      {
         lcd_putchar(0x20);
      }
   }
   set_line(0);
} /* lcd_clear */

void i2c_write(unsigned data)
{
   *I2C1_TX = data;
   delay(CHAR_DELAY);
   toggle_led();
}

void toggle_led(void)
{
   blink_delay++;
   if(blink_delay == BLINK_DELAY)
   {
      if( led1 == ON)
      {
      *IOSET = 0x200;
      led1 = OFF;
      }
      else
      {
      *IOCLR = 0x200;
      led1 = ON;
      }
      if( led2 == ON)
      {
      *IOSET = 0x400;
      led2 = OFF;
      }
      else
      {
      *IOCLR = 0x400;
      led2 = ON;
      }
   blink_delay = 0;
   }
}

void print_page1(void)
{
   lcd_print_crlf("PHILIPS LPC3000 ");
   lcd_print_crlf("ARM926EJ + VFP9 ");
   lcd_print_crlf("32K I&D Cach MMU");
   lcd_print_crlf("200MHz 90nm 1.2V");
   lcd_print_crlf("Nohau Board     ");
}

void print_page2(void)
{
   lcd_print_crlf("Embedded Trace  ");
   lcd_print_crlf("Buffer (ETB)    ");
   lcd_print_crlf("USB OTG         ");
   lcd_print_crlf("USB Host+Device ");
   lcd_print_crlf("Secure Digital  ");
}

void print_page3(void)
{
   lcd_print_crlf("Floating Point  ");
   lcd_print_crlf("VFP9            ");
   lcd_print_crlf("5X Performance  ");
   lcd_print_crlf("Reduce Code     ");
   lcd_print_crlf("Reduce Power    ");
}

void page_delay(void)
{
   while(time_to_clear--)
   {
      toggle_led();
      if (time_to_clear == 0)
      {
         lcd_clear();
      }
      delay(110);
   }
   time_to_clear = CLEAR_DELAY;
}

