/****************************************************************************
 *
 * MODULE:
 *
 * COMPONENT:          $RCSfile: $
 *
 * VERSION:            $Name: $
 *
 * REVISION:           $Revision: $
 *
 * DATED:              $Date: $
 *
 * STATUS:             $State: $
 *
 * AUTHOR:
 *
 * DESCRIPTION:
 *
 * LAST MODIFIED BY:   $Author: $
 *                     $Modtime: $
 *
 */
/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
#include <jendefs.h>
#include <AppHardwareAPI.h>

/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/

/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/
PUBLIC void AppWarmStart(void);
PUBLIC void bumpLEDs(uint32 u32Device, uint32 u32ItemBitmap);
PUBLIC void writeString(char *buf);
PUBLIC void writeLine(char *buf);
PUBLIC void writeChar(char c);
PUBLIC void writeNumber(uint32 n, uint8 base);

/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
uint8 i = 0;
int8 increment = 1;
uint8 pins[] = {0, 1, 2, 3, 8, 9, 10, 11, 13, 14};

/****************************************************************************/
/***        Exported Functions                                            ***/
/****************************************************************************/

/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 * Entry point for application from boot loader.
 *
 * RETURNS:
 * Never returns.
 *
 ****************************************************************************/
PUBLIC void AppColdStart(void)
{
    AppWarmStart();
}

/****************************************************************************
 *
 * NAME: AppWarmStart
 *
 * DESCRIPTION:
 * Entry point for application from boot loader.
 *
 * RETURNS:
 * Never returns.
 *
 ****************************************************************************/
PUBLIC void AppWarmStart(void)
{
    uint32 outputPins = 0;
    uint32 on = 1;

    (void)u32AHI_Init();
    vAHI_UartEnable(E_AHI_UART_0);
    vAHI_UartSetClockDivisor(E_AHI_UART_0, E_AHI_UART_RATE_115200);
    vAHI_UartSetBaudDivisor(E_AHI_UART_0, 9);
    vAHI_UartSetControl(E_AHI_UART_0, E_AHI_UART_EVEN_PARITY, E_AHI_UART_PARITY_DISABLE, E_AHI_UART_WORD_LEN_8, E_AHI_UART_1_STOP_BIT, E_AHI_UART_RTS_HIGH);
    vAHI_UartSetRTSCTS(E_AHI_UART_0, FALSE);

    writeLine("Setting pins to output");
    for (i = 0; i < sizeof(pins); i++) {
        writeString("Setting pin ");
        writeNumber(pins[i], 10);
        writeLine("");
        outputPins |= (on << pins[i]);
    }
    i = 0;
    vAHI_DioSetPullup(0, 0xFFFFFFFF);
    // Why does this work when 0x6F0F (as generated above) doesn't?
    outputPins = 0x7F0F;
    writeString("Bitmask is ");
    writeNumber(outputPins, 2);
    writeLine("");
    vAHI_DioSetDirection(0, outputPins);
    writeLine("Initial tick");
    bumpLEDs(0, 0);

    writeLine("Setting up timer");
    vAHI_TickTimerWrite(0);
    vAHI_TickTimerInterval(800000);
    vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_RESTART);
    vAHI_TickTimerInit(bumpLEDs);
    vAHI_TickTimerIntEnable(TRUE);

// Program flow from this point on is done through timers in bumpLEDs
    while (1) {
    }
}

/****************************************************************************/
/***        Local Functions                                               ***/
/****************************************************************************/

PUBLIC void writeChar(char c) {
    while (!(E_AHI_UART_LS_THRE & u8AHI_UartReadLineStatus(E_AHI_UART_0))) {
    }
    vAHI_UartWriteData(E_AHI_UART_0, c);
}

PUBLIC void writeString(char *buf) {
    char *ptr = buf;
    while (*ptr != '\0') {
        writeChar(*ptr);
        ptr++;
    }
}

PUBLIC void writeLine(char *buf) {
    writeString(buf);
    writeString("\r\n");
}

// Based off the Arduino SoftwareSerial::PrintNumber
void writeNumber(uint32 n, uint8 base)
{
    char buf[32];
    uint8 i = 0;

    if (n == 0) {
        writeChar('0');
        return;
    }

  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--) {
    writeChar((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
  }
}


PUBLIC void bumpLEDs(uint32 u32Device, uint32 u32ItemBitmap) {
    vAHI_DioSetOutput(1 << pins[i], ~(1 << pins[i]));

    i += increment;
    if (i == (sizeof(pins) - 1)) {
        increment = -1;
    } else if (0 == i) {
        increment = 1;
    }

    return;
}

/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/

