/******************************************************************************
 *
 * RTips Technologies, Bangalore (www.rtipsonline.com)
 *
 * This sample demonstrates interrogating the device and driver/library to get
 * device information and driver/library information. This may be used to 
 * identify the 1553 card being used (based on the device model number) as well
 * as the SDK version being used.
 *
 * Some portions of this file are adapted from the bcdemo.c sample provided in
 * the AceXtreme SDK (BU-69092Sx) of M/s. Data Device Corporation
 *
 *	API's demonstrated in this sample
 *	aceInitialize
 *	aceGetHwVersionInfo

 *	aceFree
 *	aceBCDataBlkWrite
 *  aceGetLibVersion
 *
 * Author: Ganesh Okade
 * Last updated: Dec 01, 2024
 ******************************************************************************/


#include "stdemace.h"

/*******************************************************************************
 * Name:    PrintOutError
 *
 * Description:
 *
 *      This function prints out errors returned from library functions.
 *
 * In   result - the error number
 * Out  none
 ******************************************************************************/
static void PrintOutError
(
    S16BIT nResult
)
{
    char buf[80];
    aceErrorStr(nResult, buf, 80);
    printf("RTL Function Failure-> %s.\n", buf);
}


/*******************************************************************************
 * Name:    PrintDeviceCapabilities
 *
 * Description:
 *
 *      This function prints the device capabilities based on the values in 
 *      HWVERSIONINFO argument.
 *
 * In   HWVERSIONINFO structHWVersionInfo: Structure containing device info
 * Out  none
 ******************************************************************************/
void PrintDeviceCapabilities(HWVERSIONINFO structHWVersionInfo)
{
    printf("\n--------- Device Capabilities ---------");
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MF)
    {
        printf("\nMulti-Function Capable");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_VAR_VOLT_OUT)
    {
        printf("\nVariable Voltage Output");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_COUPLING)
    {
        printf("\nCouplingn");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_TERMINATION)
    {
        printf("\nTermination");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_REPLAY)
    {
        printf("\nReplay");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MTI)
    {
        printf("\nMTI");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MTIE_MEC)
    {
        printf("\nMTIe (MEC)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MTIR_AES)
    {
        printf("\nMTIr (AES)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_EXTERNAL_CLOCK_IN)
    {
        printf("\nExternal Clock In");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_EXTERNAL_CLOCK_OUT)
    {
        printf("\nExternal Clock Out");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_IRIG_IN_ANALOG)
    {
        printf("\nAnalog IRIG Rx (In)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_IRIG_IN_DIGITAL)
    {
        printf("\nDigital IRIG Rx (In)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_IRIG_OUT_DIGITAL)
    {
        printf("\nDigital IRIG Tx (Out)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_IRIG_RANGE)
    {
        printf("\nIRIG Range");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_TX_INHIBIT_BC_DISABLE)
    {
        printf("\nTx Inhibit / BC Disable");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_CAN)
    {
        printf("\nCANbus");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_PPS)
    {
        printf("\n1-Pulse Per Second (PPS)");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_PROG_ARINC_429)
    {
        printf("\nProgrammable ARINC 429");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_PROG_ARINC_717)
    {
        printf("\nProgrammable ARINC 717");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_PROG_SERIAL)
    {
        printf("\nProgrammable Serial");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MSI)
    {
        printf("\nMSI");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_BC_DISABLE)
    {
        printf("\nExternal BC Disable");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_BC_EXT_TRIGGER)
    {
        printf("\nBC External Trigger");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_MRT_DISABLE)
    {
        printf("\nMulti-RT Disable");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_RT_AUTO_BOOT)
    {
        printf("\nRT Auto Boot");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_TX_INHIBIT)
    {
        printf("\nExternal TX Inhibit");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_429_RELAY)
    {
        printf("\n429 Relays");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_PROG_VAR_SPEED_429)
    {
        printf("\nVariable Speed ARINC 429");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_429_TESTER_OPTIONS)
    {
        printf("\nARINC 429 Tester Options");
    }
    if (structHWVersionInfo.dwCapabilities & HWVER_CAPABILITY_VAR_VOLT_OUT_429)
    {
        printf("\n429 Variable Volt Output");
    }

    printf("\n");
}

int main()
{
    /* Variables */
    HWVERSIONINFO structHWVersionInfo;
    U16BIT wLibVer;

    S16BIT DevNum;
    S16BIT wResult;

    /* Get Logical Device # */
    printf("\nSelect BC Logical Device Number (0-31):\n");
    printf("> ");

    scanf("%hd", &DevNum);

    /* Initialise device in test mode in order to interrogate */
    wResult = aceInitialize(DevNum, ACE_ACCESS_CARD, ACE_MODE_TEST, 0, 0, 0);
    if (wResult)
    {
        printf("\naceInitialize Failed : ");
        PrintOutError(wResult);
        return 0;
    }

    /* Get device (hardware) info and print */
    wResult = aceGetHwVersionInfo(DevNum, &structHWVersionInfo);
    if (wResult)
    {
        printf("\aceGetHwVersionInfo Failed : ");
        PrintOutError(wResult);
        return 0;
    }
    else
    {
        /* Print device and driver/library info*/
        printf("\n--------- Device Info ---------\n");
        printf("dwFwVersion 0x%04x,  dwHdlVersion 0x%04x, dwDriverVersion 0x%04x\n",
            structHWVersionInfo.dwFwVersion, structHWVersionInfo.dwHdlVersion, structHWVersionInfo.dwDriverVersion);
        printf("dwSerialNumber %d,  dwModelNumber %d,  dwFamilyNumber %d\n", structHWVersionInfo.dwSerialNumber,
            structHWVersionInfo.dwModelNumber, structHWVersionInfo.dwModelNumber);
        printf("Device Model Name %s\nDriver Version %s\n", structHWVersionInfo.szModelName,
            structHWVersionInfo.szDriverVersion);

        /* Print device capabilities */
        PrintDeviceCapabilities(structHWVersionInfo);
    }

    /* Get library version and print */
    wLibVer = aceGetLibVersion();
    printf("\nAceXtreme SDK Release Rev %d.%d.%d                           *\n",
        (wLibVer >> 8),          /* Major*/
        (wLibVer & 0xF0) >> 4,   /* Minor*/
        (wLibVer & 0xF));        /* Devel*/

    aceFree(DevNum);
}

