Skip to content
Snippets Groups Projects
Commit d8f096e1 authored by Marc-Oliver Westerburg's avatar Marc-Oliver Westerburg Committed by Jenkins
Browse files

Added analog IO test to ltp @bit@ testsuite (refs #34386)

* Needed for Sanvito ( with external expansion board)
* Merges linux-mx:r8376, linux-mx:r8377, linux-mx:r8378,
         linux-mx:r8379, linux-mx:r8380
** some clean-up
** changed error tolerance from percent to absolute value
   due to accuracy issues with values close to 0.
** fixed @aio@ parameters for new absolute error tolerance

* Fixed include path in rocko, needed because of changed ltp base version

Change-Id: I0aa09a81701b2bfab7e771bf6191c0dc701bae85
Reviewed-on: http://gfweb/gerrit/487
parent 5ea8723e
No related branches found
No related tags found
No related merge requests found
......@@ -52,7 +52,7 @@ RS485_12 rs485pingpong -b 32 -r 4 -s 115200 -x 100 -o 1 -d /d
RS485_34 rs485pingpong -b 32 -r 4 -s 115200 -x 100 -o 1 -d /dev/ttyUSB3 -n
Touch touchmon -z -r /touch_tst_socket
Ambient_Proximity ambprox.sh
AnalogIO aio.sh 3;
AnalogIO aio -e 0.4 -r 3 -i 5;
Buzzer echo 1 >/sys/class/pwm/pwmchip3/pwm0/enable; usleep 100000; echo 0 >/sys/class/pwm/pwmchip3/pwm0/enable
Wait sleep 0.9
......
......@@ -9,11 +9,23 @@
TARGET=aio
top_srcdir ?= $(SYSROOT)/usr
all:
CFLAGS+= -I$(top_srcdir)/include -Wall -Werror
LOADLIBES+= -L$(top_srcdir)/lib -lltp -lm
SRCS=$(TARGET).c
all: $(TARGET)
$(TARGET): $(SRCS)
@mkdir -p ../bin
@cp *.sh ../bin/
@$(CC) $(CFLAGS) $(LDFLAGS) $< $(LOADLIBES) -o ../bin/$@
clean:
rm -f $(TARGET) *.o *.bak *~
/******************************************************************************/
/* Copyright (C) 2018 Garz&Fricke GmbH */
/******************************************************************************/
/******************************************************************************/
/* */
/* File: aio.c */
/* */
/* Description: This is a test for analog io on sanvito expansion board */
/* */
/* Total Tests: 1 */
/* */
/* Test Name: aio */
/* */
/* Test Assertion */
/* & Strategy: */
/* */
/******************************************************************************/
/* Standard Include Files */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <math.h>
#include <libgen.h>
/* Harness Specific Include Files. */
#include "old/test.h"
#include "config.h"
/* Local Defines */
#if !defined(TRUE) && !defined(FALSE)
#define TRUE 1
#define FALSE 0
#endif
#if LTP_VERSION >= 20140115
#define Tst_count tst_count
#endif
/* Extern Global Variables */
extern int Tst_count; /* counter for tst_xxx routines. */
extern char *TESTDIR; /* temporary dir created by tst_tmpdir() */
/* Global Variables */
char *TCID = "aio "; /* test program identifier. */
int TST_TOTAL = 1; /* total number of tests in this file. */
FILE *fd_in; /* file descriptor of the input device */
FILE *fd_out; /* file descriptor of the output device */
time_t t; /* used for the random generator */
double in_scale = 0.0f; /* scale factor for input values (read from IIO) */
double out_scale = 0.0f; /* scale factor for output values (read from IIO) */
char *conf_iio_path = "/sys/bus/iio/devices/"; /* path to IIO devices */
char *conf_indevice_name = "iio:device0/in_voltage_raw"; /* name of the standard input device */
char *conf_outdevice_name = "iio:device1/out_voltage0_raw"; /* name of the standard output device */
double conf_low = 0.0f; /* default minimum test-value */
double conf_high = 20.0f; /* default maximum test-value */
double conf_err = 0.4f; /* default error tolerance */
int conf_dummy_reads = 3; /* default number of dummy reads before evaluating input */
int conf_quiet = 0; /* quiet mode */
int conf_verbose = 0;
/* Extern Global Functions */
/******************************************************************************/
/* */
/* Function: cleanup */
/* */
/* Description: Performs all one time clean up for this test on successful */
/* completion, premature exit or failure. Closes all temporary */
/* files, removes all temporary directories exits the test with */
/* appropriate return code by calling tst_exit() function. */
/* */
/* Input: None. */
/* */
/* Output: None. */
/* */
/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
/* On success - Exits calling tst_exit(). With '0' return code. */
/* */
/******************************************************************************/
extern void cleanup()
{
tst_exit();
}
/* Local Functions */
/******************************************************************************/
/* */
/* Function: getscale */
/* */
/* Description: Reads scale value for an IIO device */
/* */
/* Input: device_name: name of IIO device to open */
/* relative to conf_iio_path */
/* scale_name: name of scale-file for IIO device */
/* */
/* Output: None. */
/* */
/* Return: On failure - -1.0. */
/* On success - scale value. */
/* */
/******************************************************************************/
double getscale(char *device_name, char *scale_name)
{
char *name = NULL;
FILE *fd = NULL;
double scale = -1.0f;
if (!device_name || !scale_name) {
tst_brkm(TBROK, cleanup, "Invalid IIO device");
return scale;
}
/* read input scale value */
char *temp = strdup(device_name);
if (!temp)
goto error;
char *iio_dev = dirname(temp);
name = calloc(sizeof(char), strlen(conf_iio_path)+strlen(iio_dev)+strlen(scale_name)+2);
if (!name)
goto error;
sprintf(name, "%s%s/%s", conf_iio_path, iio_dev, scale_name);
fd = fopen(name, "r");
if (!fd)
goto error;
if (1 != fscanf(fd, "%lf", &scale))
goto error;
error:
if (fd)
fclose(fd);
if (name)
free(name);
if (temp)
free(temp);
if (scale < 0.0f)
tst_brkm(TBROK, cleanup,
"Unable to open the IIO device %s. Error: %d, %s",
device_name, errno, strerror(errno));
return scale;
}
/******************************************************************************/
/* */
/* Function: opendevice */
/* */
/* Description: Opens an IIO device for reading or writing */
/* */
/* Input: device_name: name of IIO device to open */
/* relative to conf_iio_path */
/* mode: see fopen() */
/* */
/* Output: None. */
/* */
/* Return: On failure - returns NULL. */
/* On success - returns open FILE handle. */
/* */
/******************************************************************************/
FILE *opendevice(char *device_name, const char *mode)
{
char *name = NULL;
FILE *fd = NULL;
if (!device_name || !mode) {
tst_brkm(TBROK, cleanup, "Invalid IIO device");
return fd;
}
name = calloc(sizeof(char), strlen(conf_iio_path)+strlen(device_name)+1);
if (!name) {
tst_brkm(TBROK, cleanup,
"Unable to open the IIO device %s. Error: %d, %s",
device_name, errno, strerror(errno));
return fd;
}
sprintf(name, "%s%s", conf_iio_path, device_name);
fd = fopen(name, mode);
if (!fd) {
tst_brkm(TBROK, cleanup,
"Unable to open the IIO device %s. Error: %d, %s",
device_name, errno, strerror(errno));
return fd;
}
free(name);
return fd;
}
/******************************************************************************/
/* */
/* Function: setup */
/* */
/* Description: Performs all one time setup for this test. This function is */
/* typically used to capture signals, create temporary dirs */
/* and temporary files that may be used in the course of this */
/* test. */
/* */
/* Input: None. */
/* */
/* Output: None. */
/* */
/* Return: On failure - Exits by calling cleanup(). */
/* On success - Nothing. */
/* */
/******************************************************************************/
void setup()
{
/* read scale values */
in_scale = getscale(conf_indevice_name, "in_voltage_scale");
out_scale = getscale(conf_outdevice_name, "out_voltage_scale");
/* initialize the random generator */
time(&t);
srand((int)t);
}
/******************************************************************************/
/* */
/* Function: test */
/* */
/* Description: This function controls the write and the read commands to the */
/* i2c slave. The procedure is repeated twice as two registers */
/* are tested. */
/* */
/* Input: None. */
/* */
/* Output: None. */
/* */
/* Return: On failure - returns -1. */
/* On success - returns 0. */
/* */
/******************************************************************************/
int test()
{
int j;
long high = (long) floor(conf_high / out_scale);
long low = (unsigned) ceil(conf_low / out_scale);
long range = high - low;
double res = 0.0f;
int in_val = 0;
int out_val = rand() % range;
// calculate expected value
double expect = ((double)out_val * out_scale) + conf_low;
tst_resm(TINFO, "Write output %f * %f = %u", ((double)out_val * out_scale) + conf_low, out_scale, out_val);
// write output value
// (we must open/close/sync file here or SysFS-IIO-API won't work properly)
fd_out = opendevice(conf_outdevice_name, "w");
fprintf(fd_out, "%u", out_val);
fclose (fd_out);
sync();
for (j = 0; j < conf_dummy_reads; j++)
{
// read input value
// (we must open/close/sync file here or SysFS-IIO-API won't work properly)
fd_in = opendevice(conf_indevice_name, "r");
fscanf(fd_in, "%u", &in_val);
fclose (fd_in);
// calculate input value from read raw-value
res = ((double)in_val * in_scale) + conf_low;
tst_resm(TINFO, "Read input %u = %f * %f", in_val, res, in_scale);
}
// check input value against expections
if ((res < (expect - conf_err)) ||
(res > (expect + conf_err))) {
tst_resm(TINFO, "Input %f outside range %f +/- %f", res, expect, conf_err);
return -1;
}
tst_resm(TINFO, "Input %f within range %f +/- %f", res, expect, conf_err);
return 0;
}
/******************************************************************************/
/* */
/* Function: help */
/* */
/* Description: This function is called when the test is started with */
/* parameter -h. It displays all parameter options specifically */
/* available for this test. */
/* */
/* Input: None. */
/* */
/* Output: None. */
/* */
/* Return: Nothing. */
/* */
/******************************************************************************/
void help()
{
printf(" -i s Select the input IIO-device and channel s (default: %s)\n", conf_indevice_name);
printf(" -o s Select the output IIO-device and channel s (default: %s)\n", conf_outdevice_name);
printf(" -d f Specifies minimum output value (default: %lf) \n", conf_low);
printf(" -u f Specifies maximum output value (default: %lf) \n", conf_high);
printf(" -e f Specifies maximum allowed absoulte error from input (default: %lf) \n", conf_err);
printf(" -r n Specifies number of dummy reads for input to settle (default: %u) \n", conf_dummy_reads);
printf(" -q Suppress info messages\n");
}
/******************************************************************************/
/* */
/* Function: main */
/* */
/* Description: Entry point to this test-case. It parses all the command line */
/* inputs, calls the global setup and executes the test. It logs */
/* the test status and results appropriately using the LTP API's */
/* On successful completion or premature failure, cleanup() func */
/* is called and test exits with an appropriate return code. */
/* */
/* Input: Command line parameters (see help()) */
/* */
/* Exit: On failure - Exits by calling cleanup(). */
/* On success - exits with 0 exit value. */
/* */
/******************************************************************************/
int main(int argc, char **argv)
{
int opt_v = 0, opt_i = 0, opt_o = 0, opt_d = 0, opt_u = 0, opt_e = 0, opt_r = 0, opt_q = 0, ret = 0, lc;
char *str_i, *str_o, *str_d, *str_u, *str_e, *str_r;
option_t options[] = {
{"i:", &opt_i, &str_i},
{"o:", &opt_o, &str_o},
{"d:", &opt_d, &str_d},
{"u:", &opt_u, &str_u},
{"e:", &opt_e, &str_e},
{"r:", &opt_r, &str_r},
{"v", &opt_v, NULL},
{"q", &opt_q, NULL},
{NULL, NULL, NULL}
};
/* parse options */
#if LTP_VERSION > 20140115
tst_parse_opts(argc, argv, options, &help);
#else
char *msg;
if((msg = parse_opts(argc, argv, options, &help)) != NULL)
tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
#endif
if (opt_i)
conf_indevice_name = str_i;
if (opt_o)
conf_outdevice_name = str_o;
if (opt_d) {
if (sscanf(str_d, "%lf", &conf_low) != 1)
tst_resm(TWARN,
"double number for minimum value expected. Using default %f now.", conf_low);
}
if (opt_u) {
if (sscanf(str_u, "%lf", &conf_high) != 1)
tst_resm(TWARN,
"double number for maximum value expected. Using default %f now.", conf_high);
}
if (opt_e) {
if (sscanf(str_e, "%lf", &conf_err) != 1)
tst_resm(TWARN,
"double number for error value expected. Using default %f now.", conf_err);
}
if (opt_r) {
if (sscanf(str_r, "%u", &conf_dummy_reads) != 1)
tst_resm(TWARN,
"Number for dummy reads expected. Using default %u now.", conf_dummy_reads);
}
if (opt_q)
conf_quiet = 1;
if (opt_v){
conf_verbose = 1;
conf_quiet = 0;
}
/* do initialization */
setup();
/* start the test */
tst_resm(TINFO,
"Starting aio test. (in: %s, out: %s, err: %f reads: %u)",
conf_indevice_name, conf_outdevice_name, conf_err, conf_dummy_reads);
/* perform the test */
for (lc=0; TEST_LOOPING(lc) && ret == 0; lc++)
{
ret = test();
if (!conf_quiet)
{
// In normal mode display each test result
if (ret != 0)
tst_resm(TFAIL,
"Input value outside error-tolerance. Test failed.");
else
tst_resm(TPASS,
"Input value within error-tolerance. Test passed.");
}
}
if (conf_quiet)
{
// In quiet mode only display summary
if (ret != 0)
tst_resm(TFAIL,
"Input value outside error-tolerance. Test failed.");
else
tst_resm(TPASS,
"Input value within error-tolerance. Test passed.");
}
cleanup();
tst_exit();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment