drivertest/adc : support cmocka_driver_adc
Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
This commit is contained in:
parent
d420036cbc
commit
c7955e5faf
@ -75,6 +75,11 @@ MAINSRC += drivertest_watchdog.c
|
||||
PROGNAME += cmocka_driver_watchdog
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ADC),)
|
||||
MAINSRC += drivertest_adc.c
|
||||
PROGNAME += cmocka_driver_adc
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_I2C)$(CONFIG_SPI),)
|
||||
ifneq ($(CONFIG_SENSORS_BMI160),)
|
||||
MAINSRC += drivertest_i2c_spi.c
|
||||
|
233
testing/drivertest/drivertest_adc.c
Normal file
233
testing/drivertest/drivertest_adc.c
Normal file
@ -0,0 +1,233 @@
|
||||
/****************************************************************************
|
||||
* apps/testing/drivertest/drivertest_adc.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cmocka.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/analog/ioctl.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define OPTARG_TO_VALUE(value, type, base) \
|
||||
do { \
|
||||
FAR char* ptr; \
|
||||
value = (type)strtoul(optarg, &ptr, base); \
|
||||
if (*ptr != '\0') { \
|
||||
printf("Parameter error: -%c %s\n", ch, optarg); \
|
||||
adc_help(argv[0]); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct adc_state_s
|
||||
{
|
||||
char devpath[PATH_MAX]; /* device to adc device path */
|
||||
int adc_diff; /* adc value difference */
|
||||
int duration; /* duration of sampling adc in seconds */
|
||||
bool soft_trigger; /* soft trigger : true or false */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void adc_help(FAR char *process_name)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n", process_name);
|
||||
printf(" -p adc device path , default : /dev/adc0\n");
|
||||
printf(" -d sample adc changes over set-up value. default : 200\n");
|
||||
printf(" -t duration of adc test [second] , default: 10s\n");
|
||||
printf(" -m adc conversion method, 1 -- soft trigger, "
|
||||
"0 -- interrupt , default: 1\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: parse_commandline
|
||||
****************************************************************************/
|
||||
|
||||
static void parse_commandline(FAR struct adc_state_s *adc_state, int argc,
|
||||
FAR char **argv)
|
||||
{
|
||||
int ch;
|
||||
int converted;
|
||||
|
||||
while ((ch = getopt(argc, argv, "p:d:m:t:h")) != ERROR)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'p':
|
||||
strlcpy(adc_state->devpath, optarg, sizeof(adc_state->devpath));
|
||||
adc_state->devpath[sizeof(adc_state->devpath) - 1] = '\0';
|
||||
break;
|
||||
case 'd':
|
||||
OPTARG_TO_VALUE(converted, int, 10);
|
||||
if (converted < 0 || converted > 5000)
|
||||
{
|
||||
printf("sample adc value changes over: %d\n", converted);
|
||||
adc_help(argv[0]);
|
||||
}
|
||||
|
||||
adc_state->adc_diff = (uint8_t)converted;
|
||||
break;
|
||||
case 't':
|
||||
OPTARG_TO_VALUE(converted, int, 10);
|
||||
if (converted < 1 || converted > INT_MAX)
|
||||
{
|
||||
printf("Duty out of range: %d\n", converted);
|
||||
adc_help(argv[0]);
|
||||
}
|
||||
|
||||
adc_state->duration = (int)converted;
|
||||
break;
|
||||
case 'm':
|
||||
OPTARG_TO_VALUE(converted, uint8_t, 10);
|
||||
adc_state->soft_trigger = converted ? true : false;
|
||||
break;
|
||||
case '?':
|
||||
printf("Unsupported option: %s\n", optarg);
|
||||
|
||||
case 'h':
|
||||
adc_help(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t adc_read_one_sample(int fd, bool soft_trigger)
|
||||
{
|
||||
struct adc_msg_s sample;
|
||||
int ret;
|
||||
int nbytes;
|
||||
|
||||
/* software trigger to start one ADC conversion */
|
||||
|
||||
if (soft_trigger)
|
||||
{
|
||||
ret = ioctl(fd, ANIOC_TRIGGER, 0);
|
||||
assert_return_code(ret, OK);
|
||||
}
|
||||
|
||||
/* Read one samples */
|
||||
|
||||
nbytes = read(fd, &sample, sizeof(struct adc_msg_s));
|
||||
|
||||
/* Handle unexpected return values */
|
||||
|
||||
assert_true(nbytes == sizeof(struct adc_msg_s));
|
||||
|
||||
return sample.am_data;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_case_adc
|
||||
****************************************************************************/
|
||||
|
||||
static void test_case_adc(FAR void** state)
|
||||
{
|
||||
int fd;
|
||||
bool succ = false;
|
||||
int32_t value1;
|
||||
int32_t value2;
|
||||
struct timeval tv1;
|
||||
struct timeval tv2;
|
||||
struct timeval res;
|
||||
FAR struct adc_state_s *adc_state;
|
||||
adc_state = (FAR struct adc_state_s *)*state;
|
||||
|
||||
/* Open the ADC device for reading */
|
||||
|
||||
fd = open(adc_state->devpath, O_RDONLY);
|
||||
assert_true(fd > 0);
|
||||
|
||||
value1 = adc_read_one_sample(fd, adc_state->soft_trigger);
|
||||
|
||||
/* ADC sample value should be changed in duration [seconds] */
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
while (true)
|
||||
{
|
||||
value2 = adc_read_one_sample(fd, adc_state->soft_trigger);
|
||||
if (abs(value2 - value1) > adc_state->adc_diff)
|
||||
{
|
||||
succ = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gettimeofday(&tv2, NULL);
|
||||
timersub(&tv2, &tv1, &res);
|
||||
if (res.tv_sec >= adc_state->duration)
|
||||
{
|
||||
printf("adc test timed out\n");
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(adc_state->soft_trigger ? 1000000 : 200000);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
assert_true(succ);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* drivertest_adc_main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
/* Initialize the state data */
|
||||
|
||||
struct adc_state_s adc_state = {
|
||||
.devpath = "/dev/adc0",
|
||||
.adc_diff = 200,
|
||||
.duration = 10,
|
||||
.soft_trigger = true,
|
||||
};
|
||||
|
||||
parse_commandline(&adc_state, argc, argv);
|
||||
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_prestate(test_case_adc, &adc_state),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user