#include "archinc.h"
#include "board.h"
#include "cli.h"
#include "clichar.h"
#include "eventq.h"
#include "events.h"

#include <stdio.h>

static int iostatHandler(int argc, char * argv[], int flags);
static int greenLedHandler(int argc, char * argv[], int flags);

static boolean busyLedLock;

#ifdef CONFIG_TOOLCHAIN_IAR
//#pragma inline
#endif
void INLINE_KEYWORD boardSetBusyLed(boolean onOff)
{
#if defined(CONFIG_BOARD_MEDUSA) || defined(CONFIG_BOARD_MEDUSA_REV2)
  if (busyLedLock == false) {
    medusaSetOrangeLed(onOff);
    }
#endif

#ifdef CONFIG_BOARD_OLIMEX_P213X
    olimexSetYellowLed(onOff);
#endif

}

//'locks' the LED into a state where it is not affected by set commands
void boardLockBusyLed(boolean lockState)
{
  if (lockState == true) {
    boardSetBusyLed(true);
    busyLedLock = true;
    }
  else {
    busyLedLock = false;
    }

}

#ifdef CONFIG_TOOLCHAIN_IAR
#pragma inline
#endif
void INLINE_KEYWORD boardSetTimerLed(boolean onOff)
{
#if defined(CONFIG_BOARD_MEDUSA) || defined(CONFIG_BOARD_MEDUSA_REV2)
  medusaSetGreenLed(onOff);
#endif

#ifdef CONFIG_BOARD_OLIMEX_P213X
  olimexSetGreenLed(onOff);
#endif
}

#ifdef CONFIG_TOOLCHAIN_IAR
//#pragma inline
#endif
void INLINE_KEYWORD boardTimerLedToggle(void)
{
#if defined(CONFIG_BOARD_MEDUSA) || defined(CONFIG_BOARD_MEDUSA_REV2)
  medusaToggleGreenLed();
#endif

#ifdef CONFIG_BOARD_OLIMEX_P213X
  olimexToggleGreenLed();
#endif
}

static void handleRunLedOnEvent(void)
{
  boardSetTimerLed(true);
}

static void handleRunLedOffEvent(void)
{
  boardSetTimerLed(false);
}

void boardInit(void)
{
#ifdef CONFIG_BOARD_OLIMEX_P213X
  olimexInit();
#endif

#if defined(CONFIG_BOARD_MEDUSA) || defined(CONFIG_BOARD_MEDUSA_REV2)
  medusaInit();
#endif

}

void boardInit2(void)
{
  busyLedLock = false;

  eventqRegisterHandler(RUN_LED_ON,  handleRunLedOnEvent );
  eventqRegisterHandler(RUN_LED_OFF, handleRunLedOffEvent);

  cliRegisterCommand("iostat", iostatHandler, "iostat - shows lpc210x IOPIN and IODIR regs");
  cliRegisterCommand("runled", greenLedHandler, "runled - turn on and off the run LED");
}

static int iostatHandler(int argc, char * argv[], int flags)
{
  int retVal = -1;
  int bufLen;
  char * pOutBuf;

  pOutBuf = clicharGetOutputBuffer(&bufLen);
  
  // TODO: put this in a while loop to process a list of op/data pairs

#if defined(CONFIG_BOARD_MEDUSA_REV2) || defined(CONFIG_BOARD_OLIMEX_P213X)
  sprintf(pOutBuf, "IO0PIN[%08x] IO0DIR[%08x]\r\n", ((IO0PIN) & 0xffffffff), ((IO0DIR) & 0xffffffff) );
  clicharSendOutputBuffer(pOutBuf, bufLen);
  sprintf(pOutBuf, "IO1PIN[%08x] IO1DIR[%08x]\r\n", ((IO1PIN) & 0xffffffff), ((IO1DIR) & 0xffffffff) );
  clicharSendOutputBuffer(pOutBuf, bufLen);
#endif

#ifdef CONFIG_BOARD_MEDUSA
  sprintf(pOutBuf, "IOPIN[%08x] IODIR[%08x]\n", ((IOPIN) & 0xffffffff), ((IODIR) & 0xffffffff) );
  clicharSendOutputBuffer(pOutBuf, bufLen);
#endif

  retVal = 0;

  return retVal;
}

static int greenLedHandler(int argc, char * argv[], int flags)
{
  int retVal = -1;
  int bufLen;
  char * pOutBuf;

  if (argc != 2)
    return -1;

  switch(*argv[1]) {
    case 'n':
    case 'N':
    case '0':
      boardSetTimerLed(false);
      retVal = 0;
      break;
    case 'y':
    case 'Y':
    case '1':
      boardSetTimerLed(true);
      retVal = 0;
      break;
    }

  return retVal;
}
  
