// Texas Instruments ATC Demo board Demonstration Program
// Copyright (c) 2002, 2003 Rowley Associates Limited

#include <msp430x41x.h>
#include <string.h>
#include <stdio.h>

#define _A  (1<<0)   //      AAA
#define _B  (1<<1)   //     F   B
#define _C  (1<<4)   //     F   B
#define _D  (1<<2)   //      GGG
#define _E  (1<<7)   //     E   C
#define _F  (1<<5)   //     E   C
#define _G  (1<<3)   //      DDD
#define _UL (1<<6)   //   Underline

static const unsigned char digits[] =
{
  _A | _B | _C | _D | _E | _F,   // 0
  _B | _C,                       // 1
  _A | _B | _D | _E | _G,        // 2
  _A | _B | _C | _D | _G,        // 3
  _B | _C | _F | _G,             // 4
  _A | _F | _G | _C | _D,        // 5
  _A | _F | _G | _C | _D | _E,   // 6
  _F | _A | _B | _C,                 // 7
  _A | _B | _C | _D | _E | _F | _G,  // 8
  _F | _A | _B | _G | _C | _D        // 9
};

static void
show_digit(int digit, int pos)
{
  LCDMEM[pos] = digits[digit];
}

static void
blank_digit(int pos)
{
  LCDMEM[pos] = 0;
}

void
show_unsigned(unsigned i)
{
  unsigned n = 10;
  int pos;
  for (pos = 1; pos < 5; ++pos)
    {
      unsigned q = i / n;
      if (q)
        show_digit(q % 10, pos);
      else
        blank_digit(pos);
      n *= 10;
    }
  show_digit(i % 10, 0);
}

void
show_unsigned_long(unsigned long i)
{
  unsigned long n = 10;
  int pos;
  for (pos = 1; pos < 7; ++pos)
    {
      unsigned long q = i / n;
      if (q)
        show_digit(q % 10, pos);
      else
        blank_digit(pos);
      n *= 10;
    }
  show_digit(i % 10, 0);
}

void
main(void)
{
  // watchdog Disable.
  WDTCTL = WDTPW+WDTHOLD;

  // Initialise the FLL.
  FLL_CTL0 = XCAP10PF;

  // Initialise unused ports.
  P1OUT = 0x00;
  P1DIR = 0xFF; 
  P2OUT = 0x01;
  P2DIR = 0xfe;
  P3OUT = 0x00;
  P3DIR = 0xff;
  P4OUT = 0x00;
  P4DIR = 0xff;
  P5OUT = 0x00;
  P5DIR = 0xff;
  P6OUT = 0x00;
  P6DIR = 0xff;

  // Enable R(LCD) + COM Lines.
  P5SEL = 0xfc;

  // Initialise LCD.
  LCDCTL = LCDON + LCD4MUX + LCDP2;  // STK LCD 4Mux, S0-S23

  // Initialise basic timer.
  // ACLK, 32768/256/8 = 8Hz Interrupt Frequency, LCD frame
  // frequency @4Mux: 64Hz
  BTCTL = 0x33;

  // Clear down LCD display memory.
  memset(LCDMEM, 0x00, 12);

  // Enable basic timer interrupts.
  IFG2 &= ~BTIFG;
  IE2 |= BTIE;

  // Enable general interrupts.
  _EINT();

  for (;;)
    LPM3;
}

void
basic_timer_isr(void) __interrupt[BASICTIMER_VECTOR]
{
  static unsigned long i = 0;
  show_unsigned_long(i++);
}
