/* ---------------------------------------------------------------------------
 * remote_digital.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: remote digital test sequence
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Dez 15, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

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

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "remote_digital.h"
#include "dio.h"

#include "protocolfunctions.h"
#include "BusProtocol.h"
#include "SerOut.h"


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

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
BOOLEAN remoteDigitalInitialised = FALSE;
/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
BOOLEAN remoteDioReadResult = FALSE;
 
/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */

void remoteDioInit (void)
{
    UINT32 loopcnt;
    RESULT set_mb;
    RESULT set_eb;
    
    remoteDigitalInitialised = TRUE;        /* Mark driver as initialised   */
    
    sendString (SerOutPort, TRUE, importantMessage,
            NewLine, "Initialise digital remote buffers", Dummy);
    sendString (SerOutPort, FALSE, importantMessage,
            "\tInputs...", Dummy, Dummy);
    for (loopcnt = 0; loopcnt < NUMBER_OF_TOTAL_DI; loopcnt++)
        {
        remoteDigitalInputs[loopcnt] = FALSE;
        }
    sendString (SerOutPort, FALSE, importantMessage,
            "Done", Dummy, Dummy);
    
    sendString (SerOutPort, FALSE, importantMessage,
            "\tOutputs...", Dummy, Dummy);    
    for (loopcnt = 0; loopcnt < NUMBER_OF_TOTAL_DO; loopcnt++)
        {
        remoteDigitalOutputs[loopcnt] = FALSE;
        }
    sendString (SerOutPort, FALSE, importantMessage,
            "Done", Dummy, Dummy);
    
    
    vSemaphoreCreateBinary (remoteDigitalSemaphore);
    sendString (SerOutPort, TRUE, importantMessage,
            "Take digital semaphore... ", Dummy, Dummy);  
    if (xSemaphoreTake(remoteDigitalSemaphore, 0) == pdTRUE)
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Done", Dummy, Dummy);
        }
    else
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Failed", Dummy, Dummy);
        }
    
    
    sendString(SerOutPort, TRUE, importantMessage,
            "reset remote digital outputs...", Dummy, Dummy);
    set_mb = remoteDioWriteAll (remoteDeviceNumber, digital_mb, FALSE);
    set_eb = remoteDioWriteAll (remoteDeviceNumber, digital_eb, FALSE);
    
    if ((set_mb == OK) && (set_eb == OK))
        {
        sendString(SerOutPort, FALSE, importantMessage, "Done", Dummy, Dummy);
        }
    else
        {
        sendString(SerOutPort, FALSE, importantMessage, "Failed", Dummy, Dummy);
        }
    
}


RESULT remoteDioWrite (UINT8 device, UINT8 channel, BOOLEAN value)
{
    INT32 sendArray[2];
    RESULT returnValue;
    
    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return (ERROR);
        }
    
    sendArray[0] = (INT32) channel;
    sendArray[1] = (INT32) value;
    
    bpSendCallRpc(handleBus1, device, 20, 2, sendArray);
    
    if (xSemaphoreTake(remoteDigitalSemaphore, 3000) != pdTRUE)
            {
            sendString (SerOutPort, TRUE, importantMessage,
                    s_tab, "digital write was not successful", Dummy);
            
            returnValue = ERROR;
            }
        else
            {
            remoteDigitalOutputs[channel] = value;
            
            returnValue = OK;
            }
    
    return (returnValue);
}


RESULT remoteDioWriteAll(UINT8 device, t_boardtype_digital board, BOOLEAN value)
{
    INT32 sendArray[2];
    UINT8 loopcnt = 0;
    UINT8 loopend = 0;
    
    RESULT returnValue;
    
    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return (ERROR);
        }

    sendArray[0] = (INT32)board;
    sendArray[1] = (INT32)value;

    bpSendCallRpc(handleBus1, device, 21, 2, sendArray);

    if (xSemaphoreTake(remoteDigitalSemaphore, 3000) != pdTRUE)
        {
        sendString(SerOutPort, TRUE, importantMessage, s_tab,
                "digital write was not successful", Dummy);
        
        returnValue = ERROR;
        } 
    else
        {

        switch (board)
            {
            case digital_mb:
                loopcnt = 0;
                loopend = NUMBER_OF_DO_MB;
                break;

            case digital_eb:
                loopcnt = NUMBER_OF_DO_MB;
                loopend = NUMBER_OF_TOTAL_DO;
                break;
            }

        for (loopcnt; loopcnt < loopend; loopcnt++)
            {
            remoteDigitalOutputs[loopcnt] = value;
            // \TODO IS THIS LOOP WORKING??
            }
        
        returnValue = OK;
        }
    
    return (returnValue);
}


BOOLEAN remoteDioRead (UINT8 device, INT32 channel)
{
    INT32 channelArray[1];
    
    channelArray[0] = channel;


    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
    return (ERROR);
    }


    bpSendCallRpc(handleBus1, device, 22, 1, channelArray);
    if (xSemaphoreTake(remoteDigitalSemaphore, 3000) != pdTRUE)
        {
        sendString (SerOutPort, TRUE, importantMessage,
                s_tab, "digital read did not receive a readback", Dummy);
        }
    else
        {
        remoteDigitalInputs[channel] = remoteDioReadResult;
        }

    return (remoteDioReadResult);
}


void remoteDioReadAll (UINT8 device, t_boardtype_digital board)
{
    INT32 boardArray[1];
    
    boardArray[0] = board;

    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return;
        }

    bpSendCallRpc(handleBus1, device, 23, 1, boardArray);
    if (xSemaphoreTake(remoteDigitalSemaphore, 3000) != pdTRUE)
        {
        sendString (SerOutPort, TRUE, importantMessage,
                s_tab, "digital read all did not receive a readback", Dummy);
        }
    else
        {
        sendString (SerOutPort, TRUE, importantMessage,
                f_tab, "digital read all finished receiving", Dummy);
        }
    
}


void remoteDigitalSemaphoreRelease (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{

    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return;
        }

    xSemaphoreGive (remoteDigitalSemaphore);
}

void digitalReadResult (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{

    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return;
        }

    /* nrOfResults = 2
     * results[0]: digital input value (0: LOW, !0: HIGH)
     */ 
    if (results[0] == 0)
        {
        /* Remote digital input is LOW                                      */
        remoteDioReadResult = FALSE;
        }
    else
        {
        /* Remote digital input is HIGH                                     */
        remoteDioReadResult = TRUE;
        }    
    xSemaphoreGive (remoteDigitalSemaphore);
}


void digitalReadAllResult (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{
    /* nrOfResults = 2
     * results[0]: boardType (0: MB; 1: EB)
     * results[1]: digital input value
     */ 
    
    UINT32 loopcnt;
    UINT32 tempValue;
    
    if (remoteDigitalInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tdigital not intialised", Dummy, Dummy);
        return;
        }
    
    sendString (SerOutPort, TRUE, importantMessage,
            "\t\tdigital real all: ", ItoHStr (results[1]), Dummy);
    
    if (results[0] == 0)
        {
        /* Incoming Results are from Mainboard                              */
        for (loopcnt = 0; loopcnt < NUMBER_OF_DI_MB; loopcnt++)
            {
            tempValue = (results[1] & (0x0000 | (1 << loopcnt)));
            if (tempValue == 0)
                {
                remoteDigitalInputs[loopcnt] = FALSE;
                }
            else
                {
                remoteDigitalInputs[loopcnt] = TRUE;
                }
            }
        }
    
    else if (results[0] == 1)
        {
        /* Incoming Results are from Extensionboard                         */
        for (loopcnt = 0; loopcnt < NUMBER_OF_DI_EB; loopcnt++)
            {
            tempValue = (results[1] & (0x0000 | (1 << loopcnt)));
            
            if (tempValue == 0)
                {
                remoteDigitalInputs[(loopcnt + NUMBER_OF_DI_MB)] = FALSE;
                }
            else
                {
                remoteDigitalInputs[(loopcnt + NUMBER_OF_DI_MB)] = TRUE;
                }
            }
        }
    
    xSemaphoreGive (remoteDigitalSemaphore);
}
