/* ---------------------------------------------------------------------------
 * testdio.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: 
 * Contains the digital Input/Output test Function
 * 
 *
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Mar 06, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

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

/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "task.h"

/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */ 
#include "dio.h"
#include "testdio.h" 
#include "SerOut.h"
#include "ledfunctions.h"
#include "BusProtocol.h"
#include "protocolfunctions.h"
/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */
// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)
#define NumberOfDIOs    8
#else
#define NumberOfDIOs    11              /* Number of digital Inputs         */
#endif
#define NumberOfDOs     8               /* Number of digital Outputs        */
/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */

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


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

BOOLEAN testdioStart (void)
{
    BOOLEAN DIOTestResult;
    BOOLEAN DIOTestResult_MB = FALSE;
    BOOLEAN DIOTestResult_EB = FALSE;
    
    DIOTestResult_MB = doDIOLineTest();
    
// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)
    dio_inMuxEn();
        
    /* Do digital line test for extension Board Connectors                  */
    DIOTestResult_EB = doDIOLineTest();
        
    dio_outMuxEn();
#endif

    if ((DIOTestResult_MB == TRUE)
// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)            
     && (DIOTestResult_EB == TRUE)
#endif
        )
        {
        DIOTestResult = TRUE;
        }
    else
        {
        DIOTestResult = FALSE;
        }
    
    return (DIOTestResult);

}


BOOLEAN doDIOLineTest (void)
{
    UINT32 diocnt = 0;
    BOOLEAN LineTestResult = FALSE;
    BOOLEAN LowTest  = TRUE;
    BOOLEAN AllOther = TRUE;
    BOOLEAN HighTest = TRUE;
    BOOLEAN LowBuffer;
    BOOLEAN AllOtherBuffer;
    BOOLEAN HighBuffer;
    
    dioClean();
    vTaskDelay (100);
    
    
    for (diocnt = 0; diocnt < NumberOfDIOs; diocnt++)
        {
        /* Read LOW Value on selected Digital Input and set Read Result     */
        if ((LowBuffer = !dioRead (thisDeviceNumber, diocnt)) == FALSE)
            {                           /* LowBuffer contains Read Result   */
            LowTest = FALSE;
            }
        
        /* Drive selected Digital Output to HIGH.                           */
        if (diocnt >= NumberOfDOs)
            {
            dioWrite (thisDeviceNumber, (diocnt - NumberOfDOs), TRUE);
            }
        else                            /* if selected Input is > possible  */
            {                           /* Outputs, restart at Output 0     */
            dioWrite (thisDeviceNumber, diocnt, TRUE);
            }
        vTaskDelay (50);                /* small Delay                      */

        /* Check if all Lines but the selected one are LOW                  */
        if ((AllOtherBuffer = CheckAllOtherDIOZero(diocnt, TRUE)) == FALSE)
            {
            AllOther = FALSE;
            }
        
        /* Read HIGH Value on selected Digital Input and set Read Result    */
        if ((HighBuffer = dioRead (thisDeviceNumber, diocnt)) == FALSE)
            {
            HighTest = FALSE;
            }
        
        /* Set selected digital Input back to LOW                           */
        if (diocnt >= NumberOfDOs)
            {
            dioWrite (thisDeviceNumber, (diocnt - NumberOfDOs), FALSE);
            }
        else                            /* if selected Input is > possible  */
            {                           /* Outputs, restart at Output 0     */
            dioWrite (thisDeviceNumber, diocnt, FALSE);
            }
        
        /* Message out Test Results                                         */
        sendString (SerOutPort, TRUE, testMessage,
                "\tLinetest for Digital Input ", ItoDStr(diocnt), ": ");
        sendString (SerOutPort, FALSE, testMessage,
                "  ", Dummy, BoolRestoStr (LowBuffer));
        sendString (SerOutPort, FALSE, testMessage,
                "  ", Dummy, BoolRestoStr (AllOtherBuffer));
        sendString (SerOutPort, FALSE, testMessage,
                "  ", Dummy, BoolRestoStr (HighBuffer));
        vTaskDelay (50);
        }
    
    /* Set complete LineTestResult                                          */
    if ((LowTest == TRUE)  && (HighTest == TRUE) && (AllOther == TRUE))
        {
        LineTestResult = TRUE;
        }
    else
        {
        LineTestResult = FALSE;
        }
    
    return (LineTestResult);
}


BOOLEAN CheckAllOtherDIOZero (UINT32 DIONumber, BOOLEAN local)
{
    UINT32 loopcnt = 0;
    BOOLEAN allZeroResult = TRUE;
    
    for (loopcnt = 0; loopcnt < NumberOfDIOs; loopcnt++) /*Test Line by Line*/
        {
        if ((loopcnt == DIONumber) ||   /* except currently tested Input    */
            (loopcnt == (DIONumber + NumberOfDOs)) ||
            (loopcnt == (DIONumber - NumberOfDOs)))
            {
            if (loopcnt < (NumberOfDIOs - 1))
                {
                loopcnt++;              /* Skip currently tested Input      */
                }
            else
                {
                break;                  /* If currently tested Input is the */
                }                       /* last one, simply break out       */
            }
        
        if (local == TRUE)
            {
            if (dioRead (thisDeviceNumber, loopcnt) == TRUE)
                {
                allZeroResult = FALSE;
                }
            }
        else
            {
            if (dioRead (remoteDeviceNumber, loopcnt) == TRUE)
                {
                allZeroResult = FALSE;
                }
            vTaskDelay (100);
            }
        }
    return (allZeroResult);
}
