AudioScience HPI Version_4.20.8

HPI GPIO

HPI example that uses GPIO.

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

  Test GPIO universal controls using HPI functions

  Usage: asihpigpio --help

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 )

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

#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

/* Option variables */
static int do_dump = 0;
static int input = -1;
static int set = -1;
static int clear = -1;
static int do_loop = -1;
static int wAdapterIndex = 0;
static int verbose = 1;

static struct option long_options[] = {
        {"adapter", required_argument, 0, 'a'},
        {"input", required_argument, 0, 'i'},
        {"set", required_argument, 0, 's'},
        {"clear", required_argument, 0, 'c'},
        {"dump", no_argument, 0, 'd'},
        {"loop", no_argument, 0, 'l' },
        {"verbose", no_argument, 0, 'v' },
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
};

static const char *short_options = "a:i:s:c:dlvh?";

static const char *option_help[] = {
        "<adapter number> to test.",
        "<decimal value> input show GPIO input N (zero based)",
        "<decimal value> set sets GPIO output N (zero based)",
        "<decimal value> clear clears GPIO output N (zero based)",
        "dump state of all GPIO inputs and outputs",
        "loops, turning each GPIO output on and off continuously",
        "turn on verbose output",
        "Show this text."
};

static void help(void)
{
        int i = 0;
        printf("\nASIHPIGPIO - GPIO example code");
        printf("\nUsage - asihpigpio [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 'd':
                        do_dump = 1;
                        break;
                case 's':
                        set = atoi(optarg);
                        break;
                case 'c':
                        clear = atoi(optarg);
                        break;
                case 'i':
                        input = atoi(optarg);
                        break;
                case 'l':
                        do_loop = 1;
                        break;
                case 'v':
                        verbose = 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: ");
        }

}

/*******************************************************************/
/*
 * gpio_index of -1 implies dump settings, otherwise range is 0..N-1
 */
static hpi_err_t set_gpio_output(hpi_handle_t hMixer, int gpio_index, int val)
{
        struct hpi_control_t asihpi_control;
        hpi_handle_t block;
        hpi_handle_t param;
        size_t value_size = 0;
        size_t value_items = 0;
        hpi_err_t err = 0;
        uint8_t *value;
        int i;

        /* set source and destination node */
        asihpi_control.wSrcNodeType = HPI_SOURCENODE_ADAPTER;
        asihpi_control.wSrcNodeIndex = 0;
        asihpi_control.wDstNodeType = 0;
        asihpi_control.wDstNodeIndex = 0;

        err = HPI_Object_BlockHandle(hMixer,
                        asihpi_control.wSrcNodeType, asihpi_control.wSrcNodeIndex,
                        asihpi_control.wDstNodeType, asihpi_control.wDstNodeIndex,
                        "GPIO",
                        &block );

        if ( !err ) {
                err = HPI_Object_ParameterHandle( hMixer, block, "Outputs", &param);
        }

        if ( !err ) {
                err = HPI_Object_GetInfo( param,
                        entity_type_boolean, entity_role_value,
                        NULL, &value_size, &value_items);
        }

        value = calloc(value_items, 1);
        if (!value)
                err = HPI_ERROR_MEMORY_ALLOC;

        if ( !err ) {
                err = HPI_Object_GetValue(param, entity_type_boolean, value_items,
                            value, value_size );
        }

        if (gpio_index >= 0) {

                if (gpio_index >= (int)value_items) {
                        printf("Index %d out of range\n", gpio_index);
                        err = HPI_ERROR_ENTITY_ITEM_COUNT;
                }

                if ( !err ) {
                        if (val)
                                value[gpio_index] = 'T';
                        else
                                value[gpio_index] = 'F';
                }

                if ( !err ) {
                        err = HPI_Object_SetValue(param, entity_type_boolean, value_items,
                                        value, value_size );
                }
        }

        if ( !err ) {
                if (gpio_index < 0) {
                        /* dump all outputs */
                        printf("GPIO Outputs: ");
                        for (i = 0; i < (int)value_items; i++)
                                printf("%c", value[i]);
                        printf("\n");
                } else {
                        /* dump single output (that was changed by this call) */
                        printf("GPIO Output [%d]: %c\n", gpio_index, value[gpio_index]);
                }
        }

        if (err) {
                printf("Error %d setting GPIO output.\n",err);
        }

        if (value)
                free(value);

        return err;
}

/*******************************************************************/
/*
 * gpio_index of -1 implies dump settings, otherwise range is 0..N-1
 */
static hpi_err_t get_gpio_input(hpi_handle_t hMixer, int gpio_index)
{
        struct hpi_control_t asihpi_control;
        hpi_handle_t block;
        hpi_handle_t param;
        size_t value_size = 0;
        size_t value_items = 0;
        hpi_err_t err = 0;
        uint8_t *value;
        int i;

        /* set source and destination node */
        asihpi_control.wSrcNodeType = HPI_SOURCENODE_ADAPTER;
        asihpi_control.wSrcNodeIndex = 0;
        asihpi_control.wDstNodeType = 0;
        asihpi_control.wDstNodeIndex = 0;

        err = HPI_Object_BlockHandle(hMixer,
                        asihpi_control.wSrcNodeType, asihpi_control.wSrcNodeIndex,
                        asihpi_control.wDstNodeType, asihpi_control.wDstNodeIndex,
                        "GPIO",
                        &block );

        if ( !err ) {
                err = HPI_Object_ParameterHandle( hMixer, block, "Inputs", &param);
        }

        if ( !err ) {
                err = HPI_Object_GetInfo( param,
                        entity_type_boolean, entity_role_value,
                        NULL, &value_size, &value_items);
        }

        value = calloc(value_items, 1);
        if (!value)
                err = HPI_ERROR_MEMORY_ALLOC;

        if ( !err ) {
                err = HPI_Object_GetValue(param, entity_type_boolean, value_items,
                            value, value_size );
        }

        if (gpio_index >= (int)value_items) {
                printf("Index %d out of range\n", gpio_index);
                err = HPI_ERROR_ENTITY_ITEM_COUNT;
        }

        if ( !err ) {
                if (gpio_index < 0) {
                        /* dump all inputs */
                        printf("GPIO Inputs: ");
                        for (i = 0; i < (int)value_items; i++)
                                printf("%c", value[i]);
                        printf("\n");
                } else {
                        /* dump single input */
                        printf("GPIO Input [%d]: %c\n",
                                gpio_index, value[gpio_index]);
                }
        }

        if (err) {
                printf("Error %d getting GPIO input.\n",err);
        }

        if (value)
                free(value);

        return err;
}

static void dump_settings(hpi_handle_t hMixer)
{
        get_gpio_input(hMixer, -1);
        set_gpio_output(hMixer, -1, 0);
}

/************************************** MAIN ***********************/
int main(int argc, char *argv[])
{
        hpi_hsubsys_t *hSubSys;
        hpi_err_t err = 0;
        uint16_t wVersion;
        uint32_t dwSerialNumber;
        uint16_t wType;
        uint16_t wNumOutStreams;
        uint16_t wNumInStreams;
        hpi_handle_t hMixer = 0;

        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);

        if ( do_dump ) {  // Dump all settings
                dump_settings(hMixer);
        }

        if (input >= 0) { // Input bit
                get_gpio_input(hMixer, input);
        }
        if (set >= 0) {  // Output set
                set_gpio_output(hMixer, set, 1);
        }

        if (clear >= 0) {  // Output clear
                set_gpio_output(hMixer, clear, 0);
        }
        if (do_loop >= 0) {  // Output clear
                int i = 0;
                while (1)
                        for (i = 0; i < 4; i++)
                        {
                                set_gpio_output(hMixer, i, 1);
                                dump_settings(hMixer);
                                Sleep(2000);
                                set_gpio_output(hMixer, i, 0);
                                printf("\n");
                        }
        }


        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 */