/* ---------------------------------------------------------------------------
 * menufunctions.c                                     (c) 2008 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: 
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Nov 14, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include "LPC23xx.h"
#include "types.h"

/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "Task.h"
#include "semphr.h"
/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "topoftest.h"
#include "logging.h"

#include "BusProtocol.h"

#include "menufunctions.h"
#include "menuargs.h"

#include "remote_misc.h"
#include "remote_tests.h"

#include "ledfunctions.h"
#include "taskfunctions.h"
#include "protocolfunctions.h"

/* Driver includes */
#include "serOut.h"
#include "adc.h"
#include "can.h"
#include "dac.h"
#include "dio.h"
#include "calibrateaio.h"
#include "logging.h"
#include "rtc.h"

/* Test includes */
#include "testLED.h"
#include "testdio.h"
#include "testaio.h"
#include "testBUS.h"
#include "testcan.h"
#include "testeeprom.h"
#include "testMMC.h"
#include "testpower.h"
#include "testrtc.h"
#include "calibrateaio.h"

/* remote drivers */
#include "remote_analogue.h"
#include "remote_digital.h"
#include "remote_relay.h"

/* Remote test includes */
#include "test_analogue.h"
#include "test_digital.h"
#include "test_leds.h"

#include "fat_test.h"
#include "fat_public.h"

/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
extern const char *command_table[NUMBER_OF_COMMANDS];

extern UINT32 arg1;
extern UINT32 arg2;
extern UINT32 arg3;

extern BOOLEAN quit;

extern UINT32 UINT32result;


/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */


/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */


void m_run(void)
{
    dioClean();
    diotasksdelete();
    // \MARK Automatic Test not necessary on Olimex Board
#if ((PINSET_TESTER == 1) || (PINSET_TESTER == 2)) 
//    automaticdesigntest();                  // \TODO NO AUTOMATIC TEST AVAILABLE
#else
    sendString(MenuPort, TRUE, importantMessage,
            "Automatic Test not available! -> OlimexBoard", Dummy, Dummy);
#endif
}

/*
 * INPUT AND OUTPUT SECTION
 */        

/* Set analogue Output */
void m_confout (void)
    {
    /* arg1: Channel
     * arg2: Mode
     */
    if ((arg2 == 1) && ((arg1 >= 0) && (arg1 < 10)))
        {
        if (arg1 == 9)
            {
            dacModeAll(dacCURRENT);
            } 
        else
            {
            dacMode(arg1, dacCURRENT);
            }
        sendString(MenuPort, TRUE, importantMessage, "Configured Output ",
                ItoDStr(arg1), " to CURRENT");

        }
    else if ((arg2 == 0) && ((arg1 >= 0) && (arg1 < 10)))
        {
        if (arg1 == 9)
            {
            dacModeAll(dacVOLTAGE);
            } 
        else
            {
            dacMode(arg1, dacVOLTAGE);
            }
        sendString(MenuPort, TRUE, importantMessage, "Configured Output ",
                ItoDStr(arg1), " to VOLTAGE");

        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage, "ARGUMENT ERROR! Did nothing... ",
                Dummy, Dummy);
        }
}


/* Set analogue Input */
void m_confin (void)
    {
    /* arg1: Channel
     * arg2: Mode
     */
    if ((arg2 == 1) && ((arg1 >= 0) && (arg1 < 10)))
        {
        if (arg1 == 9)
            {
            adcModeAll(adcCURRENT);
            } 
        else
            {
            adcMode(arg1, dacCURRENT);
            }
        sendString(MenuPort, TRUE, importantMessage, "Configured Input ",
                ItoDStr(arg1), " to CURRENT");

        } 
    else if ((arg2 == 0) && ((arg1 >= 0) && (arg1 < 10)))
        {
        if (arg1 == 9)
            {
            adcModeAll(adcVOLTAGE);
            } 
        else
            {
            adcMode(arg1, dacVOLTAGE);
            }
        sendString(MenuPort, TRUE, importantMessage, "Configured Input ",
                ItoDStr(arg1), " to VOLTAGE");

        } 
        else
        {
        sendString(MenuPort, TRUE, importantMessage, "ARGUMENT ERROR! Did nothing... ",
                Dummy, Dummy);
        }
}


void m_switchMux(void)
{
    /* arg1: Mux type (0: DI; 1: DO; 2: AI; 3: AO)
     * arg2: value (0: main board; 1: extensionboard)
     */

    if (((arg1 >= 0) && (arg1 < 4)) && ((arg2 == 0) || (arg2 == 1)))
        {
        switch (arg1)
            {
            case 0:
                /* Effect Mux of digital input                              */
                dio_inMuxEn(arg2);
                if (arg2 == 0)
                    {
                sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched digital input mux to Mainboard", Dummy, Dummy);
                    }
                else if (arg2 == 1)
                    {
                    sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched digital input mux to Extensionboard", Dummy, Dummy);
                    }
                break;
            case 1:
                /* Effect Mux of digital output                             */
                dio_outMuxEn(arg2);
                if (arg2 == 0)
                    {
                sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched digital output mux to Mainboard", Dummy, Dummy);
                    }
                else if (arg2 == 1)
                    {
                    sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched digital output mux to Extensionboard", Dummy, Dummy);
                    }
                break;
            case 2:
                /* Effect Mux of analogue input                             */
                adc_MuxEn(arg2);
                if (arg2 == 0)
                    {
                sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched analogue input mux to Mainboard", Dummy, Dummy);
                    }
                else if (arg2 == 1)
                    {
                    sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched analogue input mux to Extensionboard", Dummy, Dummy);
                    }
                break;
            case 3:
                /* Effect Mux of analogue output                            */
                dac_MuxEn(arg2);
                if (arg2 == 0)
                    {
                sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched analogue output mux to Mainboard", Dummy, Dummy);
                    }
                else if (arg2 == 1)
                    {
                    sendString (SerOutPort, GotoNewLine, importantMessage,
                        "Switched analogue output mux to Extensionboard", Dummy, Dummy);
                    }
                break;

            }
        }
}


/* Drive local or remote Current Output */
void m_curout(void)
{
    /* arg1: device
     * arg2: channel
     * arg3: value
     */

    RESULT writeResult;

    /* check arguments: vaild device number, valid channel, valid value     */
    if ((arg1 >= 0) && (arg2 < maxDAC_Channels) && ((arg3 >= 0) && (arg3
            <= maxDAC_CURRENT)))
        {
        if (arg1 == remoteDeviceNumber)
            {
            adcMode(arg2, dacCURRENT);
            vTaskDelay(100);
            writeResult = remoteAioWrite(arg1, arg2, arg3);

            if (writeResult == OK)
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "Wrote Output to: ", ItoDStr(arg3), " uA");
                }
            else
                {
                sendString (SerOutPort, TRUE, importantMessage,
                        "\tan error occured on writing", Dummy, Dummy);
                }
            } 
        else
            {
            adcMode(arg2, adcCURRENT);
            dacMode(arg2, dacCURRENT);

            vTaskDelay(100);
            dacWrite(arg1, arg2, arg3);

            sendString(MenuPort, TRUE, importantMessage, "Wrote Output to: ",
                    ItoDStr(dacReadBack(arg1, arg2)), " uA");
            }
        } else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Drive local or remote Voltage Output x */
void m_volout(void)
{
    /* arg1: device
     * arg2: channel
     * arg3: value
     */
    if ((arg1 >= 0) && (arg2 < maxDAC_Channels) && ((arg3 >= 0) && (arg3
            <= maxDAC_VOLTAGE)))
        {
        if (arg1 == 0)
            {
            dacMode(arg2, dacVOLTAGE);
            adcMode(arg2, dacVOLTAGE);
            if (arg2 < 4)
                {
                adcMode((arg2 + 4), dacVOLTAGE);
                }
            else
                {
                adcMode((arg2 - 4), dacVOLTAGE);
                }
            vTaskDelay(100);
            dacWrite(arg1, arg2, arg3);
            sendString(MenuPort, TRUE, importantMessage, "Wrote Output to: ",
                    ItoDStr(dacReadBack(arg1, arg2)), " mV");
            }

        else
            {
            sendString(MenuPort, TRUE, importantMessage,
                    "\tremote device does not support voltage outputs", Dummy,
                    Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }

}


/* Drive local or remote digital Output x */
void m_digiout(void)
{
    /* arg1: device
     * arg2: channel
     * arg3: value
     */

    RESULT writeStatus;

    if ((arg1 >= 0) && (arg2 < NUMBER_OF_TOTAL_DO) && ((arg3 >= 0) && (arg3
            < 2)))
        {
        if (arg1 == remoteDeviceNumber)
            {
            /* working on slave device of test environment                  */

            if (arg3 == 0)
                {
                writeStatus = remoteDioWrite((UINT8)arg1, (UINT8)arg2, FALSE);
                } 
            else
                {
                writeStatus = remoteDioWrite((UINT8)arg1, (UINT8)arg2, TRUE);
                }
            if (writeStatus == OK)
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "Wrote Output to: ",
                        BooltoStr(remoteDigitalOutputs[arg2]), Dummy);
                }
            else
                {
                sendString (SerOutPort, TRUE, importantMessage,
                        "\tan error occured on writing", Dummy, Dummy);
                }
            } 
        else
            {
            if (arg3 == 0)
                {
                dioWrite(arg1, arg2, FALSE);
                } else if (arg3 == 1)
                {
                dioWrite(arg1, arg2, TRUE);
                }
            sendString(MenuPort, TRUE, importantMessage, "Wrote Output to: ",
                    BooltoStr(arg3), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Read Voltage on Input x */
void m_volin(void)
{
    /* arg1: device
     * arg2: channel
     */

    if ((arg1 >= 0) && (arg2 < maxADC_Channels))
        {
        if (arg1 != remoteDeviceNumber)
            {
            adcMode(arg2, adcVOLTAGE);
            sendString(MenuPort, TRUE, importantMessage, "Voltage on Input ",
                    ItoDStr(arg2), ": ");
            sendString(MenuPort, FALSE, importantMessage, ItoDStr(adcRead(
                    arg1, arg2)), Dummy, Dummy);
            }
        else
            {
            sendString (SerOutPort, TRUE, importantMessage,
                    "\tremote device does not support voltage inputs", Dummy, Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }

}


/* Read Current on specific analogue Input */
void m_curin(void)
{
    /* arg1: device
     * arg2: channel
     */
    if ((arg1 >= 0) && (arg2 < maxADC_Channels))
        {
        adcMode(arg2, adcCURRENT);
        sendString(MenuPort, TRUE, importantMessage, "Current on Input ",
                ItoDStr(arg2), ": ");
        sendString(MenuPort, FALSE, importantMessage,
                ItoDStr(adcRead(arg1, arg2)), Dummy, Dummy);
        }
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Read local or remote digital Output x */
void m_digiin(void)
{
    /* arg1: device
     * arg2: channel
     */

    if ((arg1 >= 0) && (arg2 < NUMBER_OF_TOTAL_DI))
        {
        if (arg1 == remoteDeviceNumber)
            {
            /* working on the slave device of test environment              */
        sendString(MenuPort, TRUE, importantMessage, "Value on Input ",
                ItoDStr(arg2), ": ");
        sendString(MenuPort, FALSE, importantMessage, 
                BooltoStr(remoteDioRead(arg1, arg2)), Dummy, Dummy);
            }
        else
            {
            sendString(MenuPort, TRUE, importantMessage, "Value on Input ",
                    ItoDStr(arg2), ": ");
            sendString(MenuPort, FALSE, importantMessage, 
                    BooltoStr(dioRead(arg1, arg2)), Dummy, Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


void m_canread (void)
{
    CAN_MSG ReceiveMessage;
    
    CANPullMessage(&ReceiveMessage);
    
    sendString (SerOutPort, TRUE, resultMessage,
            "read on CAN: \n\r", "\tData1: ", ItoHStr (ReceiveMessage.Dat1));
    sendString (SerOutPort, TRUE, resultMessage,
            "\tDataA: ", ItoHStr (ReceiveMessage.DatA), Dummy);
    sendString (SerOutPort, TRUE, resultMessage,
            "\tDataB: ", ItoHStr (ReceiveMessage.DatB), Dummy);
}


/* Write on the CAN bus */
void m_canwrite (void)
{
    CAN_MSG SendMessage;

    SendMessage.Dat1 = arg1;                /* Set Length and Filter        */
    SendMessage.DatA = arg2;                /* Define first 4 Bytes         */
    SendMessage.DatB = arg3;                /* Define last 4 bytes          */
    
    CANPushMessage(&SendMessage);
    
    sendString (SerOutPort, TRUE, importantMessage,
            "wrote to CAN: \n\r", "\tData1: ", ItoHStr (SendMessage.Dat1));
    sendString (SerOutPort, TRUE, importantMessage,
            "\tDataA: ", ItoHStr (SendMessage.DatA), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "\tDataB: ", ItoHStr (SendMessage.DatB), Dummy);   
}


/*
 * CALIBRATION SECTION
 */

/* Calibrate Voltage Outputs */
void m_cvout (void)
{
    dioClean();
    diotasksdelete();
    calibrateVoltageOutput();
}


/* Calibrate Voltage Inputs */
void m_cvin (void)
{
    dioClean();
    diotasksdelete();
    calibrateVoltageInput();
}


/* Calibrate Current Outputs */
void m_ccout (void)
{
    dioClean();
    diotasksdelete();
    calibrateCurrentOutput();
}


/* Calibrate Current Inputs */
void m_ccin (void)
{
    dioClean();
    diotasksdelete();
    calibrateCurrentInput();
}


/* Delete calibrate values in EEPROM */
void m_cdel(void)
{
    // \TODO TEST ARG2, WAS INT32 BEFORE
    /* arg1: device
     * arg2: calibration type
     */
    if ((arg1 >= 0) && (arg2 < maxCAL_types))
        {
        if (arg1 == remoteDeviceNumber)
            {
            /* Overwrite old Values in EEPROM with default Value 0xFFF              */
            bpSendCallRpc(handleBus1, 2, 12, 1, (INT32)&arg2);
            sendString(MenuPort, TRUE, importantMessage,
                    "Calibration Values on Slave for Type ", ItoDStr(arg2),
                    " deleted");
            }
        else if (arg1 == thisDeviceNumber)
            {
            deleteCorrectionValue(arg2);
            sendString(MenuPort, TRUE, importantMessage,
                    "Calibration Values for Type ", ItoDStr(arg2), " deleted");
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Load calibration Values from EEPROM */
void m_cload(void)
{
    // \TODO TEST ARG2, WAS INT32 BEFORE
    /* arg1: device
     * arg2: calibration type
     */
    if ((arg1 >= 0) && (arg2 < maxCAL_types))
        {
        if (arg1 == remoteDeviceNumber)
            {
            /* Overwrite old Values in EEPROM with default Value 0xFFF              */
            bpSendCallRpc(handleBus1, 2, 11, 1, (INT32)&arg2);
            sendString(MenuPort, TRUE, importantMessage,
                    "Calibration Values on Slave for Type ", ItoDStr(arg2),
                    " loaded from EEPROM");
            } 
        else if (arg1 == thisDeviceNumber)
            {
            loadCorrectionValue_defaultTarget(arg2);
            sendString(MenuPort, TRUE, importantMessage,
                    "Calibration Values for Type ", ItoDStr(arg2),
                    " loaded from EEPROM");
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Show Status of Calibration Values in EEPROM */
void m_c_stat(void)
{
    UINT8 readback;
    // \TODO TEST ARG2, WAS INT32 BEFORE
    /* arg1: device
     * arg2: calibration type
     */
    if ((arg1 >= 0) && (arg2 < maxCAL_types))
        {
        if (arg1 == thisDeviceNumber)
            {
            readback = returnCalibrationStatus(arg2);
            if (readback == ident_default)
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "Values are in DEFAULT Mode", Dummy, Dummy);
                } 
            else if (readback == ident_calibrated)
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "Values are in CALIBRATED Mode", Dummy, Dummy);
                } 
            else
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "NO VALID VALUES IN EEPROM", Dummy, Dummy);
                }
            }

        else if (arg1 == remoteDeviceNumber)
            {
            xSemaphoreTake(generalSemaphore, 0);
            bpSendCallRpc(handleBus1, arg1, 13, 1, (INT32)&arg2);
            if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
                {
                /* Semaphore is not released, timeout in transmission   */
                sendString(SerOutPort, TRUE, importantMessage,
                        "\tTimeout occoured!", Dummy, Dummy);
                xSemaphoreGive(generalSemaphore);

                } 
            else
                {
                if (UINT32result & ident_default)
                    {
                    sendString(MenuPort, TRUE, importantMessage,
                            "Values are in DEFAULT Mode", Dummy, Dummy);
                    } 
                else if (UINT32result & ident_calibrated)
                    {
                    sendString(MenuPort, TRUE, importantMessage,
                            "Values are in CALIBRATED Mode", Dummy, Dummy);
                    } 
                else
                    {
                    sendString(MenuPort, TRUE, importantMessage,
                            "NO VALID VALUES IN EEPROM", Dummy, Dummy);
                    }
                }
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Kill Status of Calibration in EEPROM */
void m_c_kill(void)
{
    /* arg1: device
     * arg2: calibration type
     */
    if ((arg1 >= 0) && (arg2 < maxCAL_types))
        {
        if (arg1 == thisDeviceNumber)
            {
            killStats();
            } 
        else if (arg1 == remoteDeviceNumber)
            {
            xSemaphoreTake(generalSemaphore, 0);
            bpSendCallRpc(handleBus1, arg1, 14, 0, NULL);
            if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
                {
                /* Semaphore is not released, timeout in transmission   */
                sendString(MenuPort, TRUE, importantMessage,
                        "\tTimeout occoured!", Dummy, Dummy);
                xSemaphoreGive(generalSemaphore);

                } 
            else
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "\tKilled all Calibration Stats!", Dummy, Dummy);
                }
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Reset Status of Calibration in EEPROM */
void m_c_def(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == thisDeviceNumber)
            {
            defaultStats();
            } 
        else if (arg1 == remoteDeviceNumber)
            {
            xSemaphoreTake(generalSemaphore, 0);
            bpSendCallRpc(handleBus1, arg1, 15, 0, NULL);
            if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
                {
                /* Semaphore is not released, timeout in transmission   */
                sendString(MenuPort, TRUE, importantMessage,
                        "\tTimeout occoured!", Dummy, Dummy);
                xSemaphoreGive(generalSemaphore);

                }
            else
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "\tKilled all Calibration Stats!", Dummy, Dummy);
                }
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Set "Calibrated" of Calibration-Status in EEPROM */
void m_c_cal(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == thisDeviceNumber)
            {
            defaultStats();
            } 
        else if (arg1 == remoteDeviceNumber)
            {
            xSemaphoreTake(generalSemaphore, 0);
            bpSendCallRpc(handleBus1, arg1, 16, 0, NULL);
            if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
                {
                /* Semaphore is not released, timeout in transmission   */
                sendString(MenuPort, TRUE, importantMessage,
                        "\tTimeout occoured!", Dummy, Dummy);
                xSemaphoreGive(generalSemaphore);

                } 
            else
                {
                sendString(MenuPort, TRUE, importantMessage,
                        "\tKilled all Calibration Stats!", Dummy, Dummy);
                }
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Show all Stats from EEPROM */
void m_c_show(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            sendString(MenuPort, TRUE, importantMessage, "\tVoltage Input:\t",
                    Dummy, Dummy);
            showRemoteCalibrationStatus(VoltageInput);
            sendString(MenuPort, TRUE, importantMessage,
                    "\tVoltage Output:\t", Dummy, Dummy);
            showRemoteCalibrationStatus(VoltageOutput);
            sendString(MenuPort, TRUE, importantMessage, "\tCurrent Input:\t",
                    Dummy, Dummy);
            showRemoteCalibrationStatus(CurrentInput);
            sendString(MenuPort, TRUE, importantMessage,
                    "\tCurrent Output:\t", Dummy, Dummy);
            showRemoteCalibrationStatus(CurrentOutput);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, importantMessage, "\tVoltage Input:\t",
                    Dummy, Dummy);
            showLocalCalibrationStatus(VoltageInput);
            sendString(MenuPort, TRUE, importantMessage,
                    "\tVoltage Output:\t", Dummy, Dummy);
            showLocalCalibrationStatus(VoltageOutput);
            sendString(MenuPort, TRUE, importantMessage, "\tCurrent Input:\t",
                    Dummy, Dummy);
            showLocalCalibrationStatus(CurrentInput);
            sendString(MenuPort, TRUE, importantMessage,
                    "\tCurrent Output:\t", Dummy, Dummy);
            showLocalCalibrationStatus(CurrentOutput);
            }
        }
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call Analogue Calibration Procedure on Slave Device */
void m_cslave(void)
{
    dioClean();
    diotasksdelete();
// \TODO NO REMOTE            
#if NO_REMOTE            
    calibrateSlaveInOut();
#endif
}



/*
 * TEST COMMAND SECTION
 */      



/* Call Battery Test */
// \TODO IS THIS NECESSARY? BATTERYTEST ON TESTEE?
void m_battery(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_BatteryTest(&g_batterytest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\tDONE NOTHING",
                    Dummy, Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call LED Test */
void m_ledtest(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_LEDTest(&g_ledtest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tLED Test\t",
                    BoolRestoStr(g_ledtest = testledStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call Digital Input/Output Test */
void m_dio(void)
{
    /* arg1: device
     * arg2: board (0: MB, 1: EB) (Only on remote tests)
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            if (arg2 == 0)
                {
                remoteDigitalLinetestMBExecute();
                }
            else if (arg2 == 1)
                {
                remoteDigitalLinetestEBExecute();
                }
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tDIO Test\t",
                    BoolRestoStr(g_diotest = testdioStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call AnalogueInput/Output Test */
void m_aio(void)
{
    /* arg1: device
     * arg2: board (0: MB, 1: EB) (Only on remote tests)
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            if (arg2 == 0)
                {
                remoteAnalogueLinetestMBExecute();
                }
            else if (arg2 == 1)
                {
                remoteAnalogueLinetestEBExecute();
                }
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tAIO Test\t",
                    BoolRestoStr(g_diotest = testaioStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call Bus System Test */
void m_bus (void)
    {
    sendString (MenuPort, TRUE, resultMessage, "\t\t\t\tBus Test\t",
            BoolRestoStr(g_diotest = testbusStart()), Dummy);
    }

void m_cantest (void)
{
    dioClean();
    sendString (MenuPort, TRUE, resultMessage, "\t\t\t\tCAN Test\t",
            BoolRestoStr(g_cantest = testCanStart()), Dummy);
}


/* Call EEPROM Test */
void m_eeprom(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_EEPROMTest(&g_eepromtest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tEEPROM Test\t",
                    BoolRestoStr(g_eepromtest = testeepromStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call MemoryCard Test */
void m_mmc(void)
{
    /* arg1: device
     */
    if ((arg1 >= 0) && (LogFlag != TRUE))
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_MMCTest(&g_mmctest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tMMC Test\t",
                    BoolRestoStr(g_mmctest = testmmcStart()), Dummy);
            }
        } 
    else if (arg1 < 0)
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
    else if (LogFlag == TRUE)
        {
        {
        sendString(MenuPort, TRUE, importantMessage,
                "Logflag active, card test impossible ", Dummy, Dummy);
        }
        }
}


/* Call PowerSupply Test */
void m_power(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_PowerTest(&g_powertest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tPower Test\t",
                    BoolRestoStr(g_powertest = testpowerStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


/* Call RealTime Clock Test */
void m_rtc(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == remoteDeviceNumber)
            {
            dioClean();
            bpSendCallRpc(handleBus1, arg1, 4, 0, NULL); /* remote clean   */
            xSemaphoreTake(generalSemaphore, 0);
            r_RTCTest(&g_rtctest);
            } 
        else if (arg1 == thisDeviceNumber)
            {
            sendString(MenuPort, TRUE, resultMessage, "\t\t\t\tRTC Test\t",
                    BoolRestoStr(g_rtctest = testrtcStart()), Dummy);
            }
        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}

void m_fattest (void)
{
    sendString (MenuPort, GotoNewLine, importantMessage,
            "Start SD/MMC Filesystem Test Sequence", Dummy, Dummy);
    ffTestStart();
}

/* 
 * LOGGING SECTION
 */
void m_initSD (void)
{
    MMC_StatusOut(MmcInitMedia());          /* Init Card and give Status        */
}


/* Mount device (SD-CARD) to MMC Filesystem */
void m_sdMount (void)
{
    FAT_StatusOut (f_mount (0, &SD_CARD));
}


void m_logEnable (void)
{
    /* arg1: Enable / Disable
     */

    if (arg1 == 1)
        {
        sendString(MenuPort, TRUE, importantMessage,
                "Logging enabled", Dummy, Dummy);
        enableLog();
        }
    
    else if (arg1 == 0)
        {
        sendString(MenuPort, TRUE, importantMessage,
                "Logging disabled", Dummy, Dummy);
        disableLog();

        }
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}


void m_logStart (void)
{
    /* arg1: file name
     */

    if (arg1 >= 0)
        {
        startLog(arg1);
        }
}

void m_logStop (void)
{
    stopLog();
}


void m_loglist (void)
{
    listLog ("/");
}



/*
 * MISC SECTION
 */

void m_setRTC (void)
{
    /* arg1: UINT8  |day|hour|min|sec| (arg1 is 32bit)
     * arg2: UINT8  |0|0|0|0|dow|mon|  (arg2 is 32bit)
     * arg3: UINT16 |doy|year|         (arg3 is 32bit)
     */

    t_rtc timedate;
    
    timedate.sec  =  (arg1 & 0x000000FF);   /* Get seconds from arg1        */
    timedate.min  = ((arg1 & 0x0000FF00) >>  8);    /* Get minutes from arg1*/
    timedate.hour = ((arg1 & 0x00FF0000) >> 16);    /* Get hours from arg1  */
    timedate.day  = ((arg1 & 0xFF000000) >> 24);    /* get day from arg1    */
    
    timedate.dow  =  (arg2 & 0x000000FF);   /* Get day of week from arg2    */
    timedate.mon  = ((arg2 & 0x0000FF00) >>  8);    /* get month from arg2  */
    
    timedate.year =  (arg3 & 0x0000FFFF);   /* Get year from arg3           */
    timedate.doy  = ((arg3 & 0xFFFF0000) >> 16);    /* get day of year      */
    
    rtcWrite (&timedate);                   /* Write Time&Date to RTC       */
}


void m_readRTC (void)
{
    t_rtc timedate;
    
    rtcRead (&timedate);                    /* Read RTC values              */

    sendString (SerOutPort, TRUE, importantMessage,
            "Seconds: \t", ItoDStr (timedate.sec), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Minutes: \t", ItoDStr (timedate.min), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Hours: \t\t", ItoDStr (timedate.hour), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Day: \t\t", ItoDStr (timedate.day), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Day of Week: \t", ItoDStr (timedate.dow), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Month: \t\t", ItoDStr (timedate.mon), Dummy);
    sendString (SerOutPort, TRUE, importantMessage,
            "Year: \t\t", ItoDStr (timedate.year), Dummy);
}


void m_callRemoteFunction (void)
{
    /* arg1: Remote function number
     * arg2: Number of function Arguments
     * arg3: arguments
     */

    bpSendCallRpc (handleBus1, remoteDeviceNumber, arg1, arg2, arg3);
}


void m_listLocalattachments(void)
{
    /* arg1 : function ID
     */

    UINT8 functioncnt = 0;
    t_rpc_entity *lookupEntry;

    if (arg1 == 0)
        {
        while (functioncnt < 61)
            {
            lookupEntry = bpLookupRpcEntry(handleBus1, functioncnt);
            if (lookupEntry != NULL)
                {
                sendString(MenuPort, TRUE, importantMessage,
                        ItoDStr(functioncnt), s_tab, lookupEntry->functionName);
                }
            
            functioncnt++;
            }
        }

    else
        {
        lookupEntry = bpLookupRpcEntry(handleBus1, (UINT8) arg1);

        if (lookupEntry != NULL)
            {

            sendString(MenuPort, TRUE, importantMessage,
                    lookupEntry->functionName, s_tab, ItoDStr(arg1));
            }
        }
}


void m_listRemoteattachments(void)
{

}


void m_clean(void)
{
    /* arg1: device
     */
    if (arg1 >= 0)
        {
        if (arg1 == thisDeviceNumber)
            {
            dioClean();
            } 
        else if (arg1 == remoteDeviceNumber)
            {
            bpSendCallRpc(handleBus1, remoteDeviceNumber, 4, 0, NULL);
            }

        } 
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
}

/* Call DIO Tasks delete sequence */
void m_tasksdelete(void)
{
    diotasksdelete();
}


/* Quit Prompt Menu */
void m_quit(void)
{
    sendString(MenuPort, TRUE, importantMessage, "quit", Dummy, Dummy);
    quit = TRUE;
}


/* Call Help Menu */
void m_help(void)
{
    UINT32 loopcnt;
    for (loopcnt = 0; loopcnt < NUMBER_OF_COMMANDS; loopcnt++)
        {
        sendString (MenuPort, GotoNewLine, importantMessage,
                (char *)command_table[loopcnt], Dummy, Dummy);
        vTaskDelay(10);
        }
    sendString (MenuPort, GotoNewLine, importantMessage,
            NewLine, "Type command + _help for individual information", Dummy);
}


void m_menuDebug (void)
{
    /* arg1: enable/disable (0: disable; 1: enable)
     */

    if ((arg1 >= 0) && (arg1 < 2))
        {
        if (arg1 == TRUE)
            {
            block_MenuMessage = FALSE;
            sendString(MenuPort, TRUE, importantMessage,
                    "\n\r\tMenu debug messages enabled", Dummy, Dummy);
            }
        else if (arg1 == FALSE)
            {
            block_MenuMessage = TRUE;
            sendString(MenuPort, TRUE, importantMessage,
                    "\n\r\tMenu debug messages disabled", Dummy, Dummy);
            }
        }
    else
        {
        sendString(MenuPort, TRUE, importantMessage,
                "ARGUMENT ERROR! Did nothing... ", Dummy, Dummy);
        }
        
}
