/* ---------------------------------------------------------------------------
 * remote_tests.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: Function to call single tests on remote system
 * 
 * NOTE: allMemoryUseSameLED is defined in taskfunctions.h
 * 
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Aug 29, 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 "remote_tests.h"
#include "SerOut.h"
#include "dio.h"
#include "ledfunctions.h"
#include "protocolfunctions.h"
#include "taskfunctions.h"
#include "BusProtocol.h"

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

#include "remote_analogue.h"
#include "remote_digital.h"
#include "remote_relay.h"
/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
extern BOOLEAN auto_testResult;
extern BOOLEAN GotoNewLine;
extern BOOLEAN block_SpinningWheel;

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

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

void r_TestInit (void)
{
    remoteDioInit();
    vTaskDelay (200);
    remoteAioInit();
    vTaskDelay (200);
    remoteRelayInit();
    vTaskDelay (200);
}


void r_BatteryTest (BOOLEAN * batterytest)
{   
    /* Test for Battery and batterysupplied Memory                          */ 
    sendString(SerOutPort, TRUE, headerMessage, 
        StartMessage, f_lines, "Battery Test");
    bpSendCallRpc(handleBus1, 2, 17, 0, NULL);  /* Write on Battery Memory  */
    sendString(SerOutPort, TRUE, noteMessage,
            NewLine, "\t\tSwitch SLAVE OFF for 5 Seconds", Dummy);
    if (xSemaphoreTake(slaveRestartSemaphore, 60000) == pdPASS)
        {                                         /* Wait for slave Restart */
        bpSendCallRpc(handleBus1, 2, 18, 0, NULL); /* Read from Memory      */
        xSemaphoreTake(generalSemaphore, 3000);
        }
    else
        {
        auto_testResult = FALSE;
        xSemaphoreGive (slaveRestartSemaphore);
        }

    *batterytest = auto_testResult;
#if (allMemoryUseSameLED == 1)
    postpareTest(*batterytest, &d_batteryled, BATTERYLED, (void *)dioToggle,
        (pUINT8) "batteryerror", &batteryled);
#endif
    bpSendCallRpc(handleBus1, 2, 4, 0, NULL);   /* Call dioClean()          */
    sendString (SerOutPort, TRUE, resultMessage,
                "n\rBATTERY Test Result: ", s_lines, BoolRestoStr (*batterytest));

}
 

void r_LEDTest (BOOLEAN * ledtest)
{
    /* Local Variable declaration                                           */
    UINT8 buffer = 0;
    UINT8 captureDio;
    UINT8 dioAllOn = 0xFF;
    BOOLEAN receive = FALSE;
    
    /* Test for all accessable LEDs                                         */
    sendString(SerOutPort, TRUE, headerMessage, 
        StartMessage, f_lines, "LED TEST");
    captureDio = dioCapture();
    diotaskssuspend();
    dioResume (dioAllOn);
    bpSendCallRpc(handleBus1, 2, 21, 0, NULL);  /* Call ledTest()           */
    sendString (SerOutPort, TRUE, noteMessage,
            "\n\tAre all LEDs turned on? ", 
            "\n\r\tPRESS y (YES) oder n (NO): ", 
            NewLine);
    
    do                                  /* do-while loop for String input   */
        {
        vTaskDelay (10);
        buffer = 0;    
        receive = serGet(SerOutPort, &buffer);

        } while ((buffer != 121) && (buffer != 110));
    
    if (buffer == 121)                  /* 121 = y (ScanCode)               */
        {
        *ledtest = TRUE;
        }
    else if (buffer == 110)             /* 110 = n (ScanCode)               */
        {
        *ledtest = FALSE;
        }
    xSemaphoreTake(generalSemaphore, 5000);
    dioResume(captureDio);
    diotasksresume();
    bpSendCallRpc(handleBus1, 2, 32, 0, NULL);   /* Postpare Test on Slave  */
    postpareTest(*ledtest, &d_ledtestled, LEDTESTLED, (void *)dioToggle,
            (pUINT8) "LEDerror", &ledtestled);
    bpSendCallRpc(handleBus1, 2, 4, 0, NULL);   /* Call dioClean()          */
    sendString (SerOutPort, GotoNewLine, resultMessage,
            "n\rLED Test Result: ", s_lines, BoolRestoStr (*ledtest));
}


void r_EEPROMTest (BOOLEAN * eepromtest)
{ 
    /* Test for EEPROM Memory                                               */
    sendString(SerOutPort, TRUE, headerMessage, 
            StartMessage, f_lines, "EEPROM");
    sendString (SerOutPort, FALSE, importantMessage,
            "\t", Dummy, Dummy);
    
    block_SpinningWheel = FALSE;
    bpSendCallRpc(handleBus1, 2, 22, 0, NULL);  /* Call eepromTest()        */
    
    if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
        {
        block_SpinningWheel = TRUE;
        sendString (SerOutPort, TRUE, importantMessage,
                "\tTimeout occoured!", Dummy, Dummy);
        auto_testResult = FALSE;
        xSemaphoreGive (generalSemaphore);
        }
    block_SpinningWheel = TRUE;
    *eepromtest = auto_testResult;    
#if (allMemoryUseSameLED == 0)
    postpareTest(*eepromtest, &d_eepromled, EEPROMLED, (void *)dioToggle,
        (pUINT8) "EEPROMerror", eepromled);
#else
    postpareTest(*eepromtest, &d_memoryled, MEMORYLED, (void *)dioToggle,
        (pUINT8) "memoryerror", &memoryled);
#endif
    bpSendCallRpc(handleBus1, 2, 4, 0, NULL);   /* Call dioClean()          */
    sendString(SerOutPort, GotoNewLine, resultMessage, 
            "\n\rEEPROM Test Result:", 
            s_lines, BoolRestoStr(*eepromtest));



}


void r_MMCTest(BOOLEAN * mmctest)
{ 
    /* Test for Multimedia Card                                             */
    sendString(SerOutPort, TRUE, headerMessage, 
    StartMessage, f_lines, "MMC");
    sendString (SerOutPort, FALSE, importantMessage,
            "\t", Dummy, Dummy);
    
    block_SpinningWheel = FALSE;
    bpSendCallRpc(handleBus1, 2, 27, 0, NULL); /* Call MMCTest()            */

    if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
        {
        block_SpinningWheel = TRUE;
        sendString(SerOutPort, TRUE, importantMessage, "\tTimeout occoured!",
                Dummy, Dummy);
        auto_testResult = FALSE;
        xSemaphoreGive (generalSemaphore);
        }
    
    block_SpinningWheel = TRUE;
    *mmctest = auto_testResult;

    postpareTest(*mmctest, &d_mmcled, MMCLED, (void *)dioToggle,
            (pUINT8) "MMCerror", &mmcled);
    sendString(SerOutPort, GotoNewLine, resultMessage,
            "\n\rMMC Test Result: ", s_lines, BoolRestoStr(*mmctest));
}


void r_PowerTest (BOOLEAN * powertest)
{   /* Test for Power Supply                                                */
    sendString(SerOutPort, TRUE, headerMessage, 
            StartMessage, f_lines, "Power Supply");
    sendString (SerOutPort, FALSE, importantMessage,
            "\t", Dummy, Dummy);

    block_SpinningWheel = FALSE;
    bpSendCallRpc(handleBus1, 2, 28, 0, NULL);  /* Call eepromTest()        */
    
    if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
        {
        block_SpinningWheel = TRUE;
        sendString (SerOutPort, TRUE, importantMessage,
                "\tTimeout occoured!", Dummy, Dummy);
        auto_testResult = FALSE;
        xSemaphoreGive (generalSemaphore);
        }
    block_SpinningWheel = TRUE;
    *powertest = auto_testResult;
    postpareTest(*powertest, &d_powerled, POWERLED, (void *)dioToggle,
            (pUINT8) "POWERerror", &powerled);

    sendString(SerOutPort, GotoNewLine, resultMessage,
            "\n\rPower Supply Test Result:", 
            f_lines, BoolRestoStr(*powertest));
}


void r_RTCTest (BOOLEAN * rtctest)
{   /* Test for Real Time Clock                                             */
    sendString(SerOutPort, TRUE, headerMessage, 
            StartMessage, f_lines, "RealTimeClock");
    sendString (SerOutPort, FALSE, importantMessage,
            "\t", Dummy, Dummy);
    
    block_SpinningWheel = FALSE;
    bpSendCallRpc(handleBus1, 2, 29, 0, NULL);  /* Call eepromTest()        */
    
    if (xSemaphoreTake(generalSemaphore, 5000) != pdPASS)
        {
        block_SpinningWheel = TRUE;
        sendString (SerOutPort, TRUE, importantMessage,
                "\tTimeout occoured!", Dummy, Dummy);
        auto_testResult = FALSE;
        xSemaphoreGive (generalSemaphore);
        }
    block_SpinningWheel = TRUE;
    *rtctest = auto_testResult;
    postpareTest(*rtctest, &d_rtcled, RTCLED, (void *)dioToggle,
            (pUINT8) "RTCerror", &rtcled);
    
    sendString(SerOutPort, GotoNewLine, resultMessage, 
            "\n\rRealTimeClock Test Result:", 
            f_lines, BoolRestoStr(*rtctest));
}


/* Function to handle all necessary commands and calculations after a
 * single test. Because these are all the same, they are done in a
 * extra function
 */
void postpareTest (BOOLEAN TestResult, portBASE_TYPE *basetype, 
              UINT32 LEDNumber, pdTASK_CODE TaskCode,
              pUINT8 taskname, xTaskHandle *pTaskHandler)
{
        
    if (TestResult == TRUE)
        {                               /* if Test is passed                */
        if (*basetype == pdPASS)        /* If defined Task exists           */
            {
            vTaskDelete (*pTaskHandler);/* Delete defined Task              */
            *basetype = 0;              /* Reset corresponding bastetype    */
            }
        dioWrite( 0, LEDNumber, TRUE);  /* illume corresponding LED         */
        } 
    else
        {                               /* if DIO Test fails                */
        if (*basetype == pdPASS)
            {
            /* Task already exists, so do nothing                           */
            }
        else
            {
            *basetype = xTaskCreate((void *)TaskCode,
                    ( signed portCHAR * ) taskname, 
                    configMINIMAL_STACK_SIZE, (UINT16 *)LEDNumber, 
                    tskIDLE_PRIORITY + 2, pTaskHandler);
            }                           /* Create Task to flash LED         */
        }
        
}
