Analog Devices / Mbed OS tinyiiod-example

example.cpp

Committer:
adisuciu
Date:
2019-12-13
Revision:
0:bf917bb43db6

File content as of revision 0:bf917bb43db6:

/*
 * libtinyiiod - Tiny IIO Daemon Library
 *
 * Copyright (C) 2016 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include "mbed.h"
#include "platform/mbed_thread.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include "tinyiiod.h"

Serial pc(USBTX, USBRX, 115200);
DigitalOut led1(LED1);
DigitalOut led2(LED2);


static ssize_t read_data(char *buf, size_t len)
{
    // get data from UART
    for(int i=0;i<len;i++)
        buf[i]=pc.getc();
    return len;
}

static ssize_t write_data(const char *buf, size_t len)
{
    // send data over UART
    for(int i=0;i<len;i++)
        pc.putc(buf[i]);
    return len;
}

static ssize_t read_attr(const char *device, const char *attr,
                         char *buf, size_t len, bool debug)
{
    // dispatcher method for read device attr
    if (!strcmp(device, "adc") || !strcmp(device, "0")) {
        if (debug) {
            if (!strcmp(attr, "direct_reg_access"))
                return (ssize_t) snprintf(buf, len, "0");
        } else {
            if (!strcmp(attr, "sample_rate"))
                return (ssize_t) snprintf(buf, len, "1000");
        }
    }

    return -ENOENT;
}

static ssize_t write_attr(const char *device, const char *attr,
                          const char *buf, size_t len, bool debug)
{
    // dispatcher method for write device attr
    return -ENOSYS;
}

static ssize_t ch_read_attr(const char *device, const char *channel,
                            bool ch_out, const char *attr, char *buf, size_t len)
{
    
    // dispatcher method for channel read attr
    int temp;
    if (!strcmp(device, "adc") || !strcmp(device, "0")) {
        if (ch_out)
            return -ENOENT;

        if (!strcmp(channel, "voltage0")) {
            if (!strcmp(attr, "scale"))
                return (ssize_t) snprintf(buf, len, "0.033");
            else if (!strcmp(attr, "led"))
            {
                temp=led1;
                return (ssize_t) snprintf(buf, len, "%d",temp);
                }
                
        } else if (!strcmp(channel, "voltage1")) {
            if (!strcmp(attr, "scale"))
                return (ssize_t) snprintf(buf, len, "0.033");
            else if (!strcmp(attr, "led2"))
                {temp=led2;
                return (ssize_t) snprintf(buf, len, "%d",temp);
                    }
        }
    }

    return -ENOENT;
}

static ssize_t ch_write_attr(const char *device, const char *channel,
                             bool ch_out, const char *attr, const char *buf, size_t len)
{
    // dispatcher method for write channel attribute
    ssize_t retval;
    int temp;
    if (!strcmp(device, "adc") || !strcmp(device, "0")) {
        if (ch_out)
            return -ENOENT;

        if (!strcmp(channel, "voltage0")) {
            if (!strcmp(attr, "scale"))
                return -ENOSYS;
            else if (!strcmp(attr, "led"))
            {
            //    return (ssize_t) snprintf(buf, len, "%d",led1);
                retval = (ssize_t) sscanf(buf,"%d",&temp);
                led1=temp;
                return retval;
            
            }
        } else if (!strcmp(channel, "voltage1")) {
            if (!strcmp(attr, "scale"))
                return -ENOSYS;
            else if (!strcmp(attr, "led2"))
                {
                    retval = (ssize_t) sscanf(buf,"%d",&temp);
                led2=temp;
                return retval;
                    }
        }
    }
    return -ENOSYS;
}

// XML describes the IIO context hierarchy
static const char * const xml =
    "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE context [<!ELEMENT context "
    "(device)*><!ELEMENT device (channel | attribute | debug-attribute)*><!ELEMENT "
    "channel (scan-element?, attribute*)><!ELEMENT attribute EMPTY><!ELEMENT "
    "scan-element EMPTY><!ELEMENT debug-attribute EMPTY><!ATTLIST context name "
    "CDATA #REQUIRED description CDATA #IMPLIED><!ATTLIST device id CDATA "
    "#REQUIRED name CDATA #IMPLIED><!ATTLIST channel id CDATA #REQUIRED type "
    "(input|output) #REQUIRED name CDATA #IMPLIED><!ATTLIST scan-element index "
    "CDATA #REQUIRED format CDATA #REQUIRED scale CDATA #IMPLIED><!ATTLIST "
    "attribute name CDATA #REQUIRED filename CDATA #IMPLIED><!ATTLIST "
    "debug-attribute name CDATA #REQUIRED>]><context name=\"tiny\" "
    "description=\"Tiny IIOD\" >"
    "<device id=\"0\" name=\"adc\" >"
    "<channel id=\"voltage0\" type=\"input\" >"
    "<attribute name=\"scale\" /><attribute name=\"led\" /></channel>"
    "<channel id=\"voltage1\" type=\"input\" >"
    "<attribute name=\"scale\" /><attribute name=\"led2\" /></channel>"
    "<attribute name=\"sample_rate\" />"
    "<debug-attribute name=\"direct_reg_access\" />"
    "</device></context>";

static ssize_t get_xml(char **outxml)
{

    *outxml = (char*)calloc(1, strlen(xml) + 1);
    if (!(*outxml))
        return -ENOMEM;
    memcpy(*outxml, xml, strlen(xml));

    return 0;
}

struct tinyiiod_ops ops = {
    .read = read_data,
    .write = write_data,

    .read_attr = read_attr,
    .write_attr = write_attr,
    .ch_read_attr = ch_read_attr,
    .ch_write_attr = ch_write_attr,
    .get_xml = get_xml,
};

static bool stop;

static void set_handler(int32_t signal_nb, void (*handler)(int32_t))
{
    // error handling commented out due to errors with mbed
    /*
    struct sigaction sig;
    sigaction(signal_nb, NULL, &sig);
    sig.sa_handler = handler;
    sigaction(signal_nb, &sig, NULL);*/
}

static void quit_all(int32_t sig)
{
    stop = true;
}

int32_t main(void)
{
    struct tinyiiod *iiod = tinyiiod_create(&ops);
    led1=1;

    // error handling commented out
    /*set_handler(SIGHUP, &quit_all);
    set_handler(SIGPIPE, &quit_all);
    set_handler(SIGINT, &quit_all);
    set_handler(SIGSEGV, &quit_all);
    set_handler(SIGTERM, &quit_all);*/

    while (!stop)
        tinyiiod_read_command(iiod);

    tinyiiod_destroy(iiod);

    return 0;
}