/******************************************************************************
*  LPC13xx ADC demoprogram for MicroCore64 board (by Paul Seerden)
*
*  1. Use Systick timer to generate a 10 msec timer tick (interrupt driven).
*  2. Use LPC1300 UART for communication with i.e HyperTerminal (115200 baud).
*  3. Use LPC1300 ADC driver to read 10K potm connected to AD1 (P0.12)
*  4. Use LPC1300 ADC driver to read phototransistor connected to AD2 (P0.13)
*******************************************************************************/

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

const char cmdTable[]  = "HE""RL""RP""RM";
const char helpTable[] = "Command set:\n\n"
                         "HE <cr>        - Help on commands and syntax\n"
                         "RL <cr>        - Read lightsensor (phototransistor) @ AD2 (<Esc> = exit)\n"
                         "RP <cr>        - Read Potm @ AD1 (<Esc> = exit)\n"
                         "RM <nr> <cr>   - Read Potm @ AD1 nr times\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_RL(void)
/**********************/
{
    while (ua_inchar() != 0x1B)                    // exit with <Esc>
    {
        PrintString("Phototransistor reading: ");
        PrintWDecimal(ADC_ReadCH2());
        ua_outchar('\r');
        Delay(10);
    }
    PrintString("\n");
}

static void CMD_RP(void)
/**********************/
{
    while (ua_inchar() != 0x1B)                    // exit with <Esc>
    {
        PrintString("Potm reading: ");
        PrintWDecimal(ADC_ReadCH1());
        ua_outchar('\r');
        Delay(10);
    }
    PrintString("\n");
}

static void CMD_RM(void)
/**********************/
{
  WORD nr, i, j, lowest, highest;

    nr = GetArgument();
    if (nr == 0 || nr > 50000)
    {
        PrintString("err: min. nr = 1 and max. nr = 50000\n");
        return;
    }
    lowest = highest = ADC_ReadCH1();              // take first sample
    for (i=0; i<nr-1; i++)                         // take another nr-1 samples
    {
        j = ADC_ReadCH1();
        if (j < lowest)
            lowest = j;
        if (j > highest)
            highest = j;
    }
    PrintWDecimal(nr);
    PrintString(" potm readings done: lowest = ");
    PrintWDecimal(lowest);
    PrintString(", highest = ");
    PrintWDecimal(highest);
    PrintString("\n");
}

int main(void)
/************/
{
    SysTick_Config(SystemCoreClock/100);           // Generate interrupt each ~10 ms
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);          // enable AHB clock to IOCON

    UART_Init(115200);                             // initialize UART
    ADC_Init(ADC_CLK);

    PrintString("\f\nTest program MCORE64 - LPC1317 ADC, June 2012\n");
#if ADC_IRQ_MODE
    PrintString("MODE = Interrupt driven\n");
#else
    PrintString("MODE = Polling\n");
#endif
    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_RL();               break;  // Read Lightsensor	
                  case 2:  CMD_RP();               break;  // Read Potm
                  case 3:  CMD_RM();               break;  // Read Potm Multiple	
                  default: PrintString("Command error\n");
                }
                SetBufIndex(0);                            // reset position pointer
            }
            ua_outchar('*');
        }
    }
}
