/* ---------------------------------------------------------------------------
 * remote_analogue.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 analogue 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_analogue.h"
#include "adc.h"
#include "dac.h"

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


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

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
UINT32 remoteAioReadResult = 0;

BOOLEAN remoteAnalogueInitialised = FALSE;
 
/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */

void remoteAioInit (void)
{
    UINT32 loopcnt;
    RESULT set_mb;
    RESULT set_eb;
    
    remoteAnalogueInitialised = TRUE;       /* Mark driver as initialised   */
    
    sendString (SerOutPort, TRUE, importantMessage,
            NewLine, "Initialise analogue remote buffers", Dummy);
    sendString (SerOutPort, FALSE, importantMessage,
            "\tInputs...", Dummy, Dummy);
    for (loopcnt = 0; loopcnt < NUMBER_OF_TOTAL_AI; loopcnt++)
        {
        remoteAnalogueInputs[loopcnt] = 0;
        }
    sendString (SerOutPort, FALSE, importantMessage,
            "Done", Dummy, Dummy);
    
    sendString (SerOutPort, FALSE, importantMessage,
            "\tOutputs...", Dummy, Dummy);    
    for (loopcnt = 0; loopcnt < NUMBER_OF_TOTAL_AO; loopcnt++)
        {
        remoteAnalogueInputs[loopcnt] = 0;
        }
    sendString (SerOutPort, FALSE, importantMessage,
            "Done", Dummy, Dummy);
    
    vSemaphoreCreateBinary (remoteAnalogueSemaphore);
    sendString (SerOutPort, TRUE, importantMessage,
            "Take analogue semaphore... ", Dummy, Dummy);
    
    if (xSemaphoreTake(remoteAnalogueSemaphore, 0) == pdTRUE)
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Done", Dummy, Dummy);
        }
    else
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Failed", Dummy, Dummy);
        }
    
    
    sendString(SerOutPort, TRUE, importantMessage,
            "reset remote analogue outputs...", Dummy, Dummy);
    set_mb = remoteAioWriteAll (remoteDeviceNumber, analogue_mb, 0);
    set_eb = remoteAioWriteAll (remoteDeviceNumber, analogue_eb, 0);
    if ((set_mb == OK) && (set_eb == OK))
        {
        sendString(SerOutPort, FALSE, importantMessage, "Done", Dummy, Dummy);
        }
    else
        {
        sendString(SerOutPort, FALSE, importantMessage, "Failed", Dummy, Dummy);
        }

}


RESULT remoteAioWrite (UINT8 device, UINT8 channel, INT32 value)
{

    INT32 sendArray[2];
    RESULT returnValue;
    
    if (remoteAnalogueInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tanalogue not intialised", Dummy, Dummy);
        return (ERROR);
        }
    
    sendArray[0] = (INT32) channel;
    sendArray[1] = (INT32) value;
    
    bpSendCallRpc(handleBus1, device, 22, 2, sendArray);
    
    if (xSemaphoreTake(remoteAnalogueSemaphore, 3000) != pdTRUE)
        {
        sendString (SerOutPort, TRUE, importantMessage,
                s_tab, "analogue write was not successful", Dummy);
        
        returnValue = ERROR;
        }
    else
        {
        remoteAnalogueOutputs[channel] = value;
        
        returnValue = OK;
        }

    return (returnValue);
}


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

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

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

    if (xSemaphoreTake(remoteAnalogueSemaphore, 3000) != pdTRUE)
        {
        sendString(SerOutPort, TRUE, importantMessage, s_tab,
                "analogue write was not successful", Dummy);

        returnValue = ERROR;
        } 
    else
        {

        switch (board)
            {
            case analogue_mb:
                loopcnt = 0;
                loopend = NUMBER_OF_AO_MB;
                break;

            case analogue_eb:
                loopcnt = NUMBER_OF_AO_MB;
                loopend = NUMBER_OF_TOTAL_AO;
                break;
            }

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



UINT32 remoteAioRead (UINT8 device, UINT8 channel)
{

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


    bpSendCallRpc(handleBus1, device, 23, 1, (INT32)&channel);
    if (xSemaphoreTake(remoteAnalogueSemaphore, 3000) != pdTRUE)
        {
        sendString (SerOutPort, TRUE, importantMessage,
                s_tab, "analogue read did not receive a readback", Dummy);
        }
    else
        {
        remoteAnalogueInputs[channel] = remoteAioReadResult;
        }
    
    return (remoteAioReadResult);
    
}


void remoteAioReadAll (UINT8 device, t_boardtype_analogue board)
{

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

    bpSendCallRpc(handleBus1, device, 27, 1, (INT32)&board);
    if (xSemaphoreTake(remoteAnalogueSemaphore, 3000) != pdTRUE)
        {
        sendString (SerOutPort, TRUE, importantMessage,
                s_tab, "analogue read all did not receive a readback", Dummy);
        }
    else
        {
        sendString (SerOutPort, TRUE, importantMessage,
                f_tab, "analogue read all finished receiving", Dummy);
        }
}


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

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

    xSemaphoreGive (remoteAnalogueSemaphore);
}

void analogueReadResult (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{
    /* nrOfResults = 2
     * results[0]: analogue input value
     */ 
    
    if (remoteAnalogueInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tanalogue not intialised", Dummy, Dummy);
        return;
        }

    /* Asign remote analogue input result to local variable                 */
    remoteAioReadResult = (UINT32) results[0];

   
    xSemaphoreGive (remoteAnalogueSemaphore);
}


void analogueReadAllResult (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{
    /* nrOfResults = maxDI_Channels
     * results[x]: analogue input x value
     */ 
    
    UINT32 loopcnt;
    
    if (remoteAnalogueInitialised == FALSE)
        {
        /* Remote digital driver is not initialised                         */
        sendString (SerOutPort, TRUE, importantMessage,
                "\t\tanalogue not intialised", Dummy, Dummy);
        return;
        }
    
    for (loopcnt = 0; loopcnt < maxDAC_Channels; loopcnt++)
        {
        /* Copy read result to value array                                  */
        remoteAnalogueInputs[loopcnt] = results[loopcnt];

        }
    xSemaphoreGive (remoteAnalogueSemaphore);
}

