AudioScience HPI Version_4.20.5

HPI CobraNet HMI

HPI example that communicates to CobraNet HMI interface.

/******************************************************************************
\file asihpicn.c

  Test Hardware Programming Interface (HPI) using HPI functions

  Usage: asihpicn --help

note to cleanup this file, use "astyle --style=linux -s4 asihpicn.c"

Copyright (C) 1997-2017 AudioScience, Inc. All rights reserved.

This software is provided 'as-is', without any express or implied warranty.
In no event will AudioScience Inc. be held liable for any damages arising
from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This copyright notice and list of conditions may not be altered or removed
   from any source distribution.

AudioScience, Inc. <support@audioscience.com>

( This license is GPL compatible see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses )

******************************************************************************/

#define SECONDS (1000/POLL_INTERVAL)
#define MINUTES (60*SECONDS)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <getopt.h>
#ifdef __APPLE__
#include <hpi/hpi.h>
#include <hpi/hpidebug.h>
#else
#include <hpi.h>
#include <hpidebug.h>
#endif

#define verbose_printf if (verbose) printf

typedef struct {
        uint16_t wControlType;  // HPI_CONTROL_METER, _VOLUME etc
        uint16_t wSrcNodeType;
        uint16_t wSrcNodeIndex;
        uint16_t wDstNodeType;
        uint16_t wDstNodeIndex;
} hpi_control_t;

// local protos
static void HandleError(hpi_err_t err);

// global
#define BLOCK_SIZE 32768L       //30720L //6144 //12288 //16384 //19200 //9600
static uint8_t abBuffer[BLOCK_SIZE];
static short haveFiles = 0;

/* Option variables */
static uint32_t hmi_address = 1;
static uint32_t hmi_size = 4;
static uint32_t do_write = 0;
static uint32_t do_read = 0;
static uint32_t do_list = 0;
static uint32_t do_test = 0;
static int write_value = 0;
static int wAdapterIndex = 0;
static int verbose = 0;

static struct option long_options[] = {
        {"adapter", required_argument, 0, 'a'},
        {"list", no_argument, 0, 'l'},
        {"mi-address", required_argument, 0, 'm'},
        {"mi-size", required_argument, 0, 's'},
        {"write-dec", required_argument, 0, 'd'},
        {"write-hex", required_argument, 0, 'x'},
        {"test", no_argument, 0, 't'},
        {"verbose", no_argument, 0, 'v'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
};

static const char *short_options = "a:ld:m:s:tvx:h?";

static const char *option_help[] = {
        "<adapter number> to test.",
        "List example set of HMI variables.",
        "<addr> hex HMI address.",
        "<count> HMI bytes to get.",
        "<decimal value> Write a value.",
        "<hex value> Write a value.",
        "Test code",
        "Verbose mode",
        "Show this text."
};

static void help(void)
{
        int i = 0;
        printf("\nASIHPICN - Cobranet HMI access");
        printf("\nUsage - asihpicn [options]\n");
        while (long_options[i].name != 0) {
                printf("--%s -%c %s\n",
                        long_options[i].name,
                        (char)(long_options[i].val), option_help[i]);
                i++;
        }
        exit(0);
}

static void parse_options(
        int argc,
        char *argv[]
)
{
        int c;
    /*********** Parse the command line options ***************/
        while (1) {
                // int this_option_optind = optind ? optind : 1;
                int option_index = 0;

                c = getopt_long(argc, argv, short_options,
                        long_options, &option_index);
                if (c == -1)
                        break;

                switch (c) {
                case 0:
                        printf("option %s", long_options[option_index].name);
                        if (optarg)
                                printf(" with arg %s", optarg);
                        printf("\n");
                        break;
                case 'a':
                        wAdapterIndex = atoi(optarg);
                        break;
                case 'm':
                        do_read = 1;
                        hmi_address = strtoul(optarg, (char **)NULL, 16);
                        break;
                case 's':
                        hmi_size = atoi(optarg);
                        break;
                case 'l':
                        do_list = 1;
                        break;
                case 't':
                        do_test = 1;
                        break;
                case 'v':
                        verbose = 1;
                        break;
                case 'x':
                        write_value = strtoul(optarg, (char **)NULL, 16);
                        do_write = 1;
                        break;
                case 'd':
                        write_value = strtoul(optarg, (char **)NULL, 10);
                        do_write = 1;
                        break;
                case '?':
                case 'h':
                        help();
                        break;

                default:
                        printf("?? getopt returned character code 0%o ??\n",
                                c);
                }
        }

        if (optind < argc) {
                // printf ("non-option ARGV-elements: ");
        }

}

static void byteSwap(uint8_t *b, unsigned int nBytes)
{
        unsigned int i=0;

        while(nBytes>4)  {
                unsigned char c0, c1, c2, c3;
                c3 = b[i];
                c2 = b[i+1];
                c1 = b[i+2];
                c0 = b[i+3];

                b[i] = c0;
                b[i+1] = c1;
                b[i+2] = c2;
                b[i+3] = c3;
                nBytes -= 4;
                i += 4;
        }
}
/************************************** MAIN ***********************/
int main(int argc, char *argv[])
{
        hpi_hsubsys_t *hSubSys;
        hpi_err_t err = 0;
        uint32_t dwVersion = 0;
        uint16_t wNumAdapters = 0;
        uint16_t awAdapterList[20];
        uint16_t wListLength = 20;
        uint16_t wVersion;
        uint32_t dwSerialNumber;
        uint16_t wType;
        uint16_t wNumOutStreams;
        uint16_t wNumInStreams;

        hpi_handle_t hMixer = 0;
        hpi_handle_t hControl;

        uint32_t i = 0;

        long testcount = 0;

        parse_options(argc, argv);

        verbose_printf
                ("********************************************************************\n");
        verbose_printf("\n** Test HPI using Functions **\n");

        // open subsystem and find adapters
        verbose_printf
                ("********************************************************************\n");
        verbose_printf("HPI_SubSysCreate\n");
        hSubSys = HPI_SubSysCreate();
        if (hSubSys == NULL) {
                printf("hSubSys==NULL\n");
                exit(1);
        }

        err = HPI_AdapterClose(hSubSys, wAdapterIndex);
        verbose_printf("HPI_AdapterClose \n");
        HandleError(err);

        // open 1st adapter
        err = HPI_AdapterOpen(hSubSys, wAdapterIndex);
        verbose_printf("HPI_AdapterOpen \n");
        HandleError(err);

        err = HPI_AdapterGetInfo(hSubSys,
                wAdapterIndex,
                &wNumOutStreams,
                &wNumInStreams, &wVersion, &dwSerialNumber, &wType);
        verbose_printf("HPI_AdapterGetInfo\n");
        HandleError(err);
        verbose_printf("Adapter ID=%4X Index=%d NumOutStreams=%d NumInStreams=%d S/N=%d\nHw Version %c%d DSP code version %03d\n", wType, wAdapterIndex, wNumOutStreams, wNumInStreams, dwSerialNumber, ((wVersion >> 3) & 0xf) + 'A',  // Hw version major
                wVersion & 0x7, // Hw version minor
                ((wVersion >> 13) * 100) + ((wVersion >> 7) & 0x3f)     // DSP code version
                );

        // open the mixer of this adapter
        err = HPI_MixerOpen(hSubSys, wAdapterIndex, &hMixer);
        verbose_printf("HPI_MixerOpen: handle=%X\n", hMixer);
        HandleError(err);

        verbose_printf("Get cobranet control\n");
        err = HPI_MixerGetControl(hSubSys, hMixer,
                HPI_SOURCENODE_COBRANET, 0, HPI_DESTNODE_COBRANET, 0,
                HPI_CONTROL_COBRANET, &hControl);
        HandleError(err);

        if (!err) {

#define BUFSIZE 100
                char cnData[BUFSIZE];
                uint32_t byteCount;
                unsigned int i;

                if (hmi_size > BUFSIZE)
                        hmi_size = BUFSIZE;

                memset(cnData, 0, BUFSIZE);

                if (do_write) {

                        printf("Write %#x to %#X\n", write_value,
                                hmi_address);
                        *((uint32_t *)&cnData[0]) = write_value;

                        err = HPI_Cobranet_HmiWrite(hSubSys,
                                hControl,
                                hmi_address, hmi_size, (uint8_t *)&cnData);

                        HandleError(err);

                }

                if( do_read ) {
                        verbose_printf("Read a value from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);

                        HandleError(err);

                        printf("%d bytes.  ", byteCount);
                        printf("Hex: %#X %#X ", *(int *)&cnData[0],
                                *(int *)&cnData[4]);
                        printf("Decimal: %u %u\n", *(int *)&cnData[0],
                                *(int *)&cnData[4]);
                        for (i = 0; i < byteCount; i++) {
                                printf("%02hhx ", cnData[i]);
                        }
                        printf("\n");
                }

                {
                        uint32_t status = 0, readable = 0, writeable = 0;
                        err = HPI_Cobranet_HmiGetStatus(hSubSys, hControl,
                                &status, &readable, &writeable);
                        HandleError(err);
                        printf("Cobranet status 0x%02X Readable=0x%04X Writeable=0x%04X\n", status, readable, writeable);
                }
                // list some HMI variables
                // "magic" HMI address codes from CobraNet Programmer's Reference v2.5
                if(do_list) {
                        unsigned int bundle;

                        // sysDescripton
                        hmi_address = 0x100000;
                        hmi_size = 84;
                        memset(cnData, 0, BUFSIZE);
                        verbose_printf("Read sysDescripton from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);
                        byteSwap(cnData,byteCount);
                        printf("sysDescription : %s\n",&cnData[4]);
                        HandleError(err);

                        // sysName
                        hmi_address = 0x100300;
                        hmi_size = 60;
                        memset(cnData, 0, BUFSIZE);
                        verbose_printf("Read sysName from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);
                        byteSwap(cnData,byteCount);
                        printf("sysName : %s\n",&cnData[4]);
                        HandleError(err);

                        // Tx1 bundle
                        hmi_address = 0x50100;
                        hmi_size = sizeof(bundle);
                        verbose_printf("Read txBundle (tx1) from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&bundle);
                        printf("txBundle[1] : %d\n",bundle);
                        HandleError(err);

                        // Tx1 submap
                        hmi_address = 0x50200;
                        hmi_size = 8 * sizeof(int);
                        memset(cnData, 0, BUFSIZE);
                        verbose_printf("Read tx1 submap from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);
                        for(i=0;i<8;i++)
                                printf("txSubMap (tx1) audio channel %d, audio routing channel %d\n",
                                        i,
                                        ((int *)&cnData)[i]
                                        );
                        HandleError(err);

                        // Rx1 bundle
                        hmi_address = 0x40100;
                        hmi_size = sizeof(bundle);
                        verbose_printf("Read rxBundle (rx1) from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&bundle);
                        printf("rxBundle[1] : %d\n",bundle);
                        HandleError(err);
                        // Rx1 submap
                        hmi_address = 0x40200;
                        hmi_size = 8 * sizeof(int);
                        memset(cnData, 0, BUFSIZE);
                        verbose_printf("Read rx1 submap from %#X\n", hmi_address);
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);
                        for(i=0;i<8;i++)
                                printf("rxSubMap (rx1) audio channel %d, audio routing channel %d\n",
                                        i,
                                        ((int *)&cnData)[i]
                                        );
                        HandleError(err);
                }
                // test HMI variable read/write
                // various test cases
                if( do_test ) {
                        int *o;

                        // 1. Read Rx1 submap, then swap the submap around and write it back.

                        printf("Swapping audio submap channels for Rx1\n");

                        hmi_address = 0x40200;
                        hmi_size = 8 * sizeof(int);
                        memset(cnData, 0, BUFSIZE);

                        // read submap
                        err = HPI_Cobranet_HmiRead(hSubSys,
                                hControl,
                                hmi_address, hmi_size, &byteCount, (uint8_t *)&cnData);
                        HandleError(err);

                        // swap audio routing channels
                        o = (int *)&cnData;
                        for(i=0; i<4; i++) {
                                int t;
                                t = o[i*2];
                                o[i*2] = o[i*2+1];
                                o[i*2+1] = t;
                        }

                        // write submap
                        err = HPI_Cobranet_HmiWrite(hSubSys,
                                hControl,
                                hmi_address, hmi_size, (uint8_t *)&cnData);
                        HandleError(err);
                }
        }

        err = HPI_MixerClose(hSubSys, hMixer);
        verbose_printf("\nHPI_MixerClose\n");
        HandleError(err);

        err = HPI_AdapterClose(hSubSys, wAdapterIndex);
        verbose_printf("HPI_AdapterClose\n");
        HandleError(err);

        HPI_SubSysFree(hSubSys);
        return 0;
}

/****************************** HandleError **********************/
static int getch(void)
{
        return getchar();
}

static void HandleError(hpi_err_t err)
{
        char szError[256];
        char nK = 0;

        if (err) {
                HPI_GetErrorText(err, szError);
                printf("ERROR %d %s\n", err, szError);
                printf("press Enter to continue, (q,Enter) to exit...\n");
                nK = getch();
                if (nK == 'q')
                        exit(0);
        }
}
/* END_OF_CODE */