/* ---------------------------------------------------------------------------
 * protocolfunctions.                                  (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: collection of protocol-depending functions and 
                initialisations
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Dez 11, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include <stdio.h>
#include <signal.h>
#include <errno.h>  
#include <fcntl.h>
#include <sys/ioctl.h>

/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */ 
#include "bus.h"
#include "BusProtocol.h"
#include "protocolfunctions.h"

/* testfile includes */
#include "analogue_test.h"
#include "BUS_test.h"
#include "CAN_test.h"
#include "CF_test.h"
#include "digital_test.h"
#include "EEPROM_test.h"
#include "ethernet_test.h"
#include "LED_test.h"
#include "relay_test.h"
#include "USB_test.h"
/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */

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

/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
static int sigio_interrupt = 0;
/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */
 
void protocolInit (UINT32 DEV_ID, UINT32 MAX_ID)
{
    bushandler = bpInit( BUS1, THISDEVICENUMBER, MAXDEVICENUMBER, 20 );
    BUS_ATTACHED = TRUE;
    
        
    /* Attach Handshake and Handshake return Functions to every device  */
    bpAttachRpc (bushandler, 1, "Available BusID", (t_rpc_remote_procedure_call) availableBusID, 0);
    bpAttachRpcResult(bushandler, 1, (t_bp_rpcresult_callback) generalResultFunction, 0);
        
    if (THISDEVICENUMBER == MASTERDEVICENUMBER)
        {
        /* This device is Master, attach Master functions to Bus            */
        }
        
    else if (THISDEVICENUMBER > MASTERDEVICENUMBER)
        {
        /* This device is slave, attach slave test functions to bus         */
        /* Functions 0-9 are for general controlling options                */
        bpAttachRpc (bushandler, 9, "Return attached functions", (t_rpc_remote_procedure_call) returnAttachedFunctions, 1);
        
        /* Functions 10-19 are for calibrations purpose                     */
        /* Functions 20-29 re for single channel in-/output driving         */
        bpAttachRpc (bushandler, 20, "Digital write channel", (t_rpc_remote_procedure_call) digitalWrite, 2);
        bpAttachRpc (bushandler, 21, "Digital write all", (t_rpc_remote_procedure_call) digitalWriteAll, 2);
        bpAttachRpc (bushandler, 22, "Digital read channel", (t_rpc_remote_procedure_call) digitalRead, 1);
        bpAttachRpc (bushandler, 23, "Digital read all", (t_rpc_remote_procedure_call) digitalReadAll, 1); 
        
        bpAttachRpc (bushandler, 24, "Analogue write channel", (t_rpc_remote_procedure_call) analogueWrite, 2);
        bpAttachRpc (bushandler, 25, "Analogue write all", (t_rpc_remote_procedure_call) analogueWriteAll, 2);
        bpAttachRpc (bushandler, 26, "Analogue read channel", (t_rpc_remote_procedure_call) analogueRead, 1);
        bpAttachRpc (bushandler, 27, "Analogue read all", (t_rpc_remote_procedure_call) analogueReadAll, 1);
        
        bpAttachRpc (bushandler, 28, "Relay set channel", (t_rpc_remote_procedure_call) relaySet, 1);
        bpAttachRpc (bushandler, 29, "Relay set all", (t_rpc_remote_procedure_call) relaySetAll, 1);


        /* Functions 30-49 are for single test sequences                    */
        bpAttachRpc (bushandler, 30, "AnalogueMB Test", (t_rpc_remote_procedure_call) analogueMB_test_execute, 0);
        bpAttachRpc (bushandler, 31, "AnalogueEB Test", (t_rpc_remote_procedure_call) analogueEB_test_execute, 0);
        bpAttachRpc (bushandler, 32, "BUS Test", (t_rpc_remote_procedure_call) bus_test_execute, 0);
        bpAttachRpc (bushandler, 33, "CAN Test", (t_rpc_remote_procedure_call) can_test_execute, 0);
        bpAttachRpc (bushandler, 34, "CF Test", (t_rpc_remote_procedure_call) cf_test_execute, 0);
        bpAttachRpc (bushandler, 35, "digitalMB Test", (t_rpc_remote_procedure_call) digitalMB_test_execute, 2);
        bpAttachRpc (bushandler, 36, "digitalEB Test", (t_rpc_remote_procedure_call) digitalEB_test_execute, 0);
        bpAttachRpc (bushandler, 37, "EEPROM Test", (t_rpc_remote_procedure_call) eeprom_test_execute, 0);
        bpAttachRpc (bushandler, 38, "ethernet Test", (t_rpc_remote_procedure_call) ethernet_test_execute, 0);
        bpAttachRpc (bushandler, 39, "LED Test", (t_rpc_remote_procedure_call) led_test_execute, 0);
        bpAttachRpc (bushandler, 40, "relayMB Test", (t_rpc_remote_procedure_call) relayMB_test_execute, 0);
        bpAttachRpc (bushandler, 41, "relayEB Test", (t_rpc_remote_procedure_call) relayEB_test_execute, 0);
        bpAttachRpc (bushandler, 42, "USB Test", (t_rpc_remote_procedure_call) usb_test_execute, 0);
        /* Functions 50-59 are for miscellaneous purpose                    */
        }
}
 

void returnAttachedFunctions (UINT8 senderId, UINT8 targetId, UINT8 requestNr, 
                     UINT8 functionId, UINT8 nrOfParams, UINT32 *params)
{
    UINT8 functioncnt = 0;
    t_rpc_entity *lookupEntry;
    
    if (nrOfParams == 0)
        {
        while (functioncnt < 61)            /* Currently 60 functions in    */
            {
            lookupEntry = bpLookupRpcEntry(bushandler, functioncnt);
            if (lookupEntry != 0)
                {
                bpSendRpcResult (bushandler, REMOTEDEVICENUMBER, 9, 1, 1, (INT32 *) lookupEntry->functionName);
                }
            functioncnt++;
            }
        }
    else
        {
        lookupEntry = bpLookupRpcEntry(bushandler, (UINT8) params);
        
        if (lookupEntry != NULL)
            {
            bpSendRpcResult (bushandler, REMOTEDEVICENUMBER, 9, 1, 1, (INT32 *) lookupEntry->functionName);
            }
        }
}


void availableBusID (UINT8 senderId, UINT8 targetId, UINT8 requestNr, 
                     UINT8 functionId, UINT8 nrOfParams, UINT32 *params)
{
    /* Call Result Function to release Semaphore on Master                  */
    bpSendRpcResult(bushandler, 1, 1, 1, 0, NULL);
}


void generalResultFunction (UINT8 requestNr, UINT8 nrOfResults, UINT32 *results)
{
    /* Release generalSemaphore on Call of this Function from the Master    */
    // xSemaphoreGive (generalSemaphore);
}

 
void IO_CPU_Init (void)
{
    IOCTL_interface = -1;
    
    unsigned int oflags;
    int err;
    /* Install signal handler for the control+c signal.                      */  
    signal(SIGINT,sigintHandler);

    /* Install signal handler for the SIGIO signal from the IO controller.   */  
    signal(SIGIO, sigintHandler);
    
    /* Open the interface with the IO controller.                            */
    IOCTL_interface = open("/dev/ioc", O_RDONLY);
    if (IOCTL_interface == -1)
        {
        printf ("Failed to open IO controller (error %s)\n", 
        strerror(errno));
        }
        
    // /* Register this process' as SIGIO signal receiver from IO controller.   */    
    // if (fcntl(IOCTL_interface, F_SETOWN, getpid()) == -1) 
        // {
        // printf ("Failed to F_SETOWN for IO controller (error %s)\n", 
        // strerror(errno));
        // }
    
    // /* Enable asynchronous notification.                                     */    
    // oflags = fcntl (IOCTL_interface, F_GETFL);
    // if (fcntl(IOCTL_interface, F_SETFL, oflags | FASYNC) == -1) 
        // {
        // printf ("Failed to F_SETFL for IO controller (error %s)\n", 
        // strerror(errno));
        // }
}


void appExit (int err)
{
    if (IOCTL_interface > 0) 
        {    
        close (IOCTL_interface);
        }        
    exit (err);
}

void sigintHandler (int s)
{
    switch (s)
        {
        case SIGINT:
            printf("received SIGINT signal.\n");             
            appExit (0);
            break;
        case SIGIO:
            sigio_interrupt = 1;
            break;
        }            
}



