From 85f96e379ea8fa47793b1b83f400f589eca21de3 Mon Sep 17 00:00:00 2001 From: dongjiuzhu Date: Thu, 12 Nov 2020 11:23:08 +0800 Subject: [PATCH] testing/irtest: test ir by LIRC interface N/A Change-Id: I008d2cf3f1db18cfa24bc20a5643f4960a97be3e Signed-off-by: dongjiuzhu --- testing/irtest/Kconfig | 37 ++++ testing/irtest/Make.defs | 23 +++ testing/irtest/Makefile | 32 +++ testing/irtest/cmd.hpp | 185 +++++++++++++++++ testing/irtest/cmdGeneral.cpp | 194 +++++++++++++++++ testing/irtest/cmdLirc.cpp | 377 ++++++++++++++++++++++++++++++++++ testing/irtest/enum.hpp | 77 +++++++ testing/irtest/enumDefine.cpp | 68 ++++++ testing/irtest/main.cpp | 158 ++++++++++++++ 9 files changed, 1151 insertions(+) create mode 100644 testing/irtest/Kconfig create mode 100644 testing/irtest/Make.defs create mode 100644 testing/irtest/Makefile create mode 100644 testing/irtest/cmd.hpp create mode 100644 testing/irtest/cmdGeneral.cpp create mode 100644 testing/irtest/cmdLirc.cpp create mode 100644 testing/irtest/enum.hpp create mode 100644 testing/irtest/enumDefine.cpp create mode 100644 testing/irtest/main.cpp diff --git a/testing/irtest/Kconfig b/testing/irtest/Kconfig new file mode 100644 index 000000000..12bb586fd --- /dev/null +++ b/testing/irtest/Kconfig @@ -0,0 +1,37 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_IRTEST + tristate "IR driver test" + default n + ---help--- + Enable the IR driver test + +if TESTING_IRTEST + +config TESTING_IRTEST_PROGNAME + string "Program name" + default "irtest" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config TESTING_IRTEST_PRIORITY + int "IR driver test task priority" + default 100 + +config TESTING_IRTEST_STACKSIZE + int "IR driver test stack size" + default DEFAULT_TASK_STACKSIZE + +config TESTING_IRTEST_MAX_NIRDEV + int "The Maximum number of IR devices supported" + default 2 + +config TESTING_IRTEST_MAX_SIRDATA + int "The Maximum size of sending data in unsigned int" + default 64 + +endif diff --git a/testing/irtest/Make.defs b/testing/irtest/Make.defs new file mode 100644 index 000000000..a20403a3d --- /dev/null +++ b/testing/irtest/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# testing/irtest/Make.defs +# +# 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. +# +############################################################################ + +ifneq ($(CONFIG_TESTING_IRTEST),) +CONFIGURED_APPS += $(APPDIR)/testing/irtest +endif diff --git a/testing/irtest/Makefile b/testing/irtest/Makefile new file mode 100644 index 000000000..0307f4a53 --- /dev/null +++ b/testing/irtest/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# testing/irtest/Makefile +# +# 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. +# +############################################################################ + +include $(APPDIR)/Make.defs + +PROGNAME = $(CONFIG_TESTING_IRTEST_PROGNAME) +PRIORITY = $(CONFIG_TESTING_IRTEST_PRIORITY) +STACKSIZE = $(CONFIG_TESTING_IRTEST_STACKSIZE) +MODULE = $(CONFIG_TESTING_IRTEST) + +CXXEXT = .cpp +MAINSRC = main.cpp +CXXSRCS = $(filter-out $(MAINSRC), $(wildcard *.cpp)) + +include $(APPDIR)/Application.mk diff --git a/testing/irtest/cmd.hpp b/testing/irtest/cmd.hpp new file mode 100644 index 000000000..d5864a189 --- /dev/null +++ b/testing/irtest/cmd.hpp @@ -0,0 +1,185 @@ +/**************************************************************************** + * testing/irtest/cmd.hpp + * + * 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. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_IRTEST_CMD_HPP +#define __APPS_TESTING_IRTEST_CMD_HPP + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct arg +{ + const char *type; + const char *name; +}; + +struct cmd +{ + const char *name; + const arg *args; + int (*exec)(); +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Note: All commands put into cmds section, these two symbols + * are automatically defined by linker for the section boundary + */ + +extern const cmd __start_cmds; +extern const cmd __stop_cmds; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/* the simple command line parser */ + +static inline const char *get_fisrt_arg(char *cmdline) +{ + return strtok(cmdline, " \t,()\n") ?: ""; +} + +/* for enumerate type */ + +template < typename T > +inline T get_next_arg() +{ + return static_cast < T > (get_next_arg < unsigned int > ()); +} + +template < > +inline const char *get_next_arg() +{ + /* 0 mean from the end of last token */ + + return get_fisrt_arg(0); +} + +template < > +inline int get_next_arg() +{ + return strtol(get_next_arg < const char * > (), 0, 0); +} + +template < > +inline unsigned int get_next_arg() +{ + return strtoul(get_next_arg < const char * > (), 0, 0); +} + +template < > +inline float get_next_arg() +{ + return atof(get_next_arg < const char * > ()); +} + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CMD0(func) \ + static int func(); \ + static const arg func##_args[] = \ + { \ + {0, 0} \ + }; \ + struct cmd func##_cmd __attribute__((section("cmds"))) = \ + { \ + #func, func##_args, func \ + }; \ + static int func() + +#define CMD1(func, type1, arg1) \ + static int func(type1 arg1); \ + static int func##_exec() \ + { \ + type1 arg1 = get_next_arg(); \ + return func(arg1); \ + } \ + static const arg func##_args[] = \ + { \ + {#type1, #arg1}, \ + {0, 0} \ + }; \ + struct cmd func##_cmd __attribute__((section("cmds"))) = \ + { \ + #func, func##_args, func##_exec \ + }; \ + static int func(type1 arg1) + +#define CMD2(func, type1, arg1, type2, arg2) \ + static int func(type1 arg1, type2 arg2); \ + static int func##_exec() \ + { \ + type1 arg1 = get_next_arg(); \ + type2 arg2 = get_next_arg(); \ + return func(arg1, arg2); \ + } \ + static const arg func##_args[] = { \ + {#type1, #arg1}, \ + {#type2, #arg2}, \ + {0, 0} \ + }; \ + struct cmd func##_cmd __attribute__((section("cmds"))) = \ + { \ + #func, func##_args, func##_exec \ + }; \ + static int func(type1 arg1, type2 arg2) + +#define CMD3(func, type1, arg1, type2, arg2, type3, arg3) \ + static int func(type1 arg1, type2 arg2, type3 arg3); \ + static int func##_exec() \ + { \ + type1 arg1 = get_next_arg(); \ + type2 arg2 = get_next_arg(); \ + type3 arg3 = get_next_arg(); \ + return func(arg1, arg2, arg3); \ + } \ + static const arg func##_args[] = { \ + {#type1, #arg1}, \ + {#type2, #arg2}, \ + {#type3, #arg3}, \ + {0, 0} \ + }; \ + struct cmd func##_cmd __attribute__((section("cmds"))) = \ + { \ + #func, func##_args, func##_exec \ + }; \ + static int func(type1 arg1, type2 arg2, type3 arg3) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void init_device(); + +#endif /* __APPS_TESTING_IRTEST_CMD_H */ diff --git a/testing/irtest/cmdGeneral.cpp b/testing/irtest/cmdGeneral.cpp new file mode 100644 index 000000000..7a49b27b0 --- /dev/null +++ b/testing/irtest/cmdGeneral.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** + * testing/irtest/cmdGeneral.cpp + * + * 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 +#include +#include +#include + +#include "enum.hpp" +#include "cmd.hpp" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void wake(int) +{ + pthread_mutex_lock(&mutex); + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&mutex); +} + +static void print_cmd(const cmd *cmd) +{ + printf("%s(", cmd->name); + for (int i = 0; cmd->args[i].name; i++) + { + printf(i ? ", %s" : "%s", cmd->args[i].name); + } + + printf(")\n"); +} + +static int print_cmd(const char *name) +{ + const cmd *cmd = &__start_cmds; + for (; cmd < &__stop_cmds; cmd++) + { + if (strcmp(name, cmd->name) == 0) + { + print_cmd(cmd); + return 0; + } + } + + return -ENOENT; +} + +static void print_all_cmds() +{ + const cmd *cmd = &__stop_cmds - 1; + for (; cmd >= &__start_cmds; cmd--) + { + print_cmd(cmd); + } +} + +static void print_enum(const enum_type *e) +{ + printf("%s\n", e->type); + for (int i = 0; e->value[i].name; i++) + { + printf(e->fmt, e->value[i].value); + printf(" %s\n", e->value[i].name); + } +} + +static int print_enum(const char *type) +{ + const enum_type *e = &__start_enums; + for (; e < &__stop_enums; e++) + { + if (strcmp(type, e->type) == 0) + { + print_enum(e); + return 0; + } + } + + return -ENOENT; +} + +static void print_all_enums() +{ + const enum_type *e = &__stop_enums - 1; + for (; e >= &__start_enums; e--) + { + print_enum(e); + } +} + +static void print_cmd_and_enum(const cmd *cmd) +{ + print_cmd(cmd); + for (int i = 0; cmd->args[i].type; i++) + { + print_enum(cmd->args[i].type); + } +} + +static int print_cmd_and_enum(const char *name) +{ + const cmd *cmd = &__start_cmds; + for (; cmd < &__stop_cmds; cmd++) + { + if (strcmp(name, cmd->name) == 0) + { + print_cmd_and_enum(cmd); + return 0; + } + } + + return -ENOENT; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +CMD0(quit) +{ + exit(0); + return 0; +} + +CMD1(sleep, float, seconds) +{ + int ret; + + pthread_mutex_lock(&mutex); + signal(SIGINT, wake); + if (seconds) + { + struct timeval now; + struct timespec ts; + + gettimeofday(&now, NULL); + ts.tv_sec = now.tv_sec + seconds; + ts.tv_nsec = now.tv_usec * 1000; + ret = pthread_cond_timedwait(&cond, &mutex, &ts); + } + else + { + ret = pthread_cond_wait(&cond, &mutex); + } + + pthread_mutex_unlock(&mutex); + signal(SIGINT, SIG_DFL); + return ret == ETIMEDOUT ? 0 : ret; +} + +CMD1(help, const char *, name) +{ + int r = 0; + if (name != 0 && *name != 0) + { + r = print_cmd_and_enum(name); + } + else + { + print_all_enums(); + print_all_cmds(); + } + + return r; +} diff --git a/testing/irtest/cmdLirc.cpp b/testing/irtest/cmdLirc.cpp new file mode 100644 index 000000000..861650943 --- /dev/null +++ b/testing/irtest/cmdLirc.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** + * testing/irtest/cmdLirc.cpp + * + * 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 +#include +#include +#include + +#include "cmd.hpp" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ERROR -1 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int g_irdevs[CONFIG_TESTING_IRTEST_MAX_NIRDEV]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void init_device() +{ + for (int i = 0; i < CONFIG_TESTING_IRTEST_MAX_NIRDEV; i++) + g_irdevs[i] = -1; +} + +CMD1(open_device, const char *, file_name) +{ + int irdev = open(file_name, O_RDWR); + if (irdev < 0) + { + return irdev; + } + + int index = 0; + for (; index < CONFIG_TESTING_IRTEST_MAX_NIRDEV && + g_irdevs[index] == -1; index++) + { + g_irdevs[index] = irdev; + break; + } + + if (index == CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return index; +} + +CMD1(close_device, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + if (g_irdevs[index] != -1) + { + close(g_irdevs[index]); + g_irdevs[index] = -1; + return OK; + } + + return ERROR; +} + +CMD1(write_data, size_t, index) +{ + unsigned int data[CONFIG_TESTING_IRTEST_MAX_SIRDATA]; + + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + int size = 0; + for (; size < CONFIG_TESTING_IRTEST_MAX_SIRDATA; size++) + { + unsigned int tmp = get_next_arg < unsigned int > (); + if (tmp == 0) + { + break; + } + + data[size] = tmp; + } + + /* lirc require the odd length */ + + if (size % 2 == 0) + { + int result = write(g_irdevs[index], data, + sizeof(unsigned int) * (size - 1)); + usleep(data[size - 1]); + return result; + } + else + { + return write(g_irdevs[index], data, + sizeof(unsigned int) * size); + } +} + +CMD2(read_data, size_t, index, size_t, size) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int data[size]; + int result = read(g_irdevs[index], data, sizeof(data)); + if (result > 0) + { + result /= sizeof(unsigned int); + for (int i = 0; i < result; i++) + { + if (i + 1 == result) + { + printf("%d\n", data[i]); + } + else + { + printf("%d, ", data[i]); + } + } + } + + return result; +} + +CMD1(get_features, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int features; + int result = ioctl(g_irdevs[index], LIRC_GET_FEATURES, &features); + if (result == 0) + { + printf("0x%08x\n", features); + } + + return result; +} + +CMD1(get_send_mode, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int mode; + int result = ioctl(g_irdevs[index], LIRC_GET_SEND_MODE, &mode); + if (result == 0) + { + printf("0x%02x\n", mode); + } + + return result; +} + +CMD1(get_rec_mode, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int mode; + int result = ioctl(g_irdevs[index], LIRC_GET_REC_MODE, &mode); + if (result == 0) + { + printf("0x%02x\n", mode); + } + + return result; +} + +CMD1(get_rec_resolution, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int resolution; + int result = ioctl(g_irdevs[index], LIRC_GET_REC_RESOLUTION, &resolution); + if (result == 0) + { + printf("%d\n", resolution); + } + + return result; +} + +CMD1(get_min_timeout, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int timeout; + int result = ioctl(g_irdevs[index], LIRC_GET_MIN_TIMEOUT, &timeout); + if (result == 0) + { + printf("%d\n", timeout); + } + + return result; +} + +CMD1(get_max_timeout, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int timeout; + int result = ioctl(g_irdevs[index], LIRC_GET_MAX_TIMEOUT, &timeout); + if (result == 0) + { + printf("%d\n", timeout); + } + + return result; +} + +CMD1(get_length, size_t, index) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + unsigned int length; + int result = ioctl(g_irdevs[index], LIRC_GET_LENGTH, &length); + if (result == 0) + { + printf("%d\n", length); + } + + return result; +} + +CMD2(set_send_mode, size_t, index, unsigned int, mode) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_SEND_MODE, &mode); +} + +CMD2(set_rec_mode, size_t, index, unsigned int, mode) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_REC_MODE, &mode); +} + +CMD2(set_send_carrier, size_t, index, unsigned int, carrier) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_SEND_CARRIER, &carrier); +} + +CMD2(set_rec_carrier, size_t, index, unsigned int, carrier) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_REC_CARRIER, &carrier); +} + +CMD2(set_send_duty_cycle, size_t, index, unsigned int, duty_cycle) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_SEND_DUTY_CYCLE, &duty_cycle); +} + +CMD2(set_transmitter_mask, size_t, index, unsigned int, mask) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_TRANSMITTER_MASK, &mask); +} + +CMD2(set_rec_timeout, size_t, index, unsigned int, timeout) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_REC_TIMEOUT, &timeout); +} + +CMD2(set_rec_timeout_reports, size_t, index, unsigned int, enable) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_REC_TIMEOUT_REPORTS, &enable); +} + +CMD2(set_measure_carrier_mode, size_t, index, unsigned int, enable) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_MEASURE_CARRIER_MODE, &enable); +} + +CMD2(set_rec_carrier_range, size_t, index, unsigned int, carrier) +{ + if (index >= CONFIG_TESTING_IRTEST_MAX_NIRDEV) + { + return ERROR; + } + + return ioctl(g_irdevs[index], LIRC_SET_REC_CARRIER_RANGE, &carrier); +} diff --git a/testing/irtest/enum.hpp b/testing/irtest/enum.hpp new file mode 100644 index 000000000..8182a101b --- /dev/null +++ b/testing/irtest/enum.hpp @@ -0,0 +1,77 @@ +/**************************************************************************** + * apps/testing/irtest/enum.hpp + * + * 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. + * + ****************************************************************************/ + +#ifndef __APPS_TESTING_IRTEST_ENUM_HPP +#define __APPS_TESTING_IRTEST_ENUM_HPP + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct enum_value +{ + const char *name; + unsigned int value; +}; + +struct enum_type +{ + const char *type; + const char *fmt; + const enum_value *value; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Note: All enum type put into enums section, these two symbols + * are automatically defined by linker for the section boundary + */ + +extern const enum_type __start_enums; +extern const enum_type __stop_enums; + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* macro to define the enum object */ + +#define ENUM_START(type) \ + static const enum_value type##_value[] = \ + { + +#define ENUM_VALUE(value) \ + {#value, value}, + +#define ENUM_END(type, fmt) \ + {0, 0} \ + }; \ + struct enum_type type##_type __attribute__((section("enums"))) = \ + { \ + #type, fmt, type##_value \ + }; \ + +#endif /* __APPS_TESTING_IRTEST_ENUM_H */ diff --git a/testing/irtest/enumDefine.cpp b/testing/irtest/enumDefine.cpp new file mode 100644 index 000000000..b618e5b0c --- /dev/null +++ b/testing/irtest/enumDefine.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** + * testing/irtest/enumDefine.cpp + * + * 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 "enum.hpp" +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +ENUM_START(mode_t) + ENUM_VALUE(LIRC_MODE_RAW) + ENUM_VALUE(LIRC_MODE_PULSE) + ENUM_VALUE(LIRC_MODE_MODE2) + ENUM_VALUE(LIRC_MODE_SCANCODE) + ENUM_VALUE(LIRC_MODE_LIRCCODE) +ENUM_END(mode_t, "0x%02x") + +ENUM_START(features_t) + ENUM_VALUE(LIRC_CAN_SEND_RAW) + ENUM_VALUE(LIRC_CAN_SEND_PULSE) + ENUM_VALUE(LIRC_CAN_SEND_MODE2) + ENUM_VALUE(LIRC_CAN_SEND_SCANCODE) + ENUM_VALUE(LIRC_CAN_SEND_LIRCCODE) + ENUM_VALUE(LIRC_CAN_SET_SEND_CARRIER) + ENUM_VALUE(LIRC_CAN_SET_SEND_DUTY_CYCLE) + ENUM_VALUE(LIRC_CAN_SET_TRANSMITTER_MASK) + ENUM_VALUE(LIRC_CAN_REC_RAW) + ENUM_VALUE(LIRC_CAN_REC_PULSE) + ENUM_VALUE(LIRC_CAN_REC_MODE2) + ENUM_VALUE(LIRC_CAN_REC_SCANCODE) + ENUM_VALUE(LIRC_CAN_REC_LIRCCODE) + ENUM_VALUE(LIRC_CAN_SET_REC_CARRIER) + ENUM_VALUE(LIRC_CAN_SET_REC_DUTY_CYCLE) + ENUM_VALUE(LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE) + ENUM_VALUE(LIRC_CAN_SET_REC_CARRIER_RANGE) + ENUM_VALUE(LIRC_CAN_GET_REC_RESOLUTION) + ENUM_VALUE(LIRC_CAN_SET_REC_TIMEOUT) + ENUM_VALUE(LIRC_CAN_SET_REC_FILTER) + ENUM_VALUE(LIRC_CAN_MEASURE_CARRIER) + ENUM_VALUE(LIRC_CAN_USE_WIDEBAND_RECEIVER) + ENUM_VALUE(LIRC_CAN_NOTIFY_DECODE) +ENUM_END(features_t, "0x%08x") + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/testing/irtest/main.cpp b/testing/irtest/main.cpp new file mode 100644 index 000000000..7a6013244 --- /dev/null +++ b/testing/irtest/main.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** + * testing/irtest/main.cpp + * + * 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 + +#include "system/readline.h" +#include "cmd.hpp" +#include "enum.hpp" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern cmd *quit_cmd; +extern cmd *sleep_cmd; +extern cmd *help_cmd; +extern cmd *open_device_cmd; +extern cmd *close_device_cmd; +extern cmd *write_data_cmd; +extern cmd *get_features_cmd; +extern cmd *get_send_mode_cmd; +extern cmd *get_rec_mode_cmd; +extern cmd *get_rec_resolution_cmd; +extern cmd *get_min_timeout_cmd; +extern cmd *get_max_timeout_cmd; +extern cmd *get_length_cmd; +extern cmd *read_data_cmd; +extern cmd *set_send_mode_cmd; +extern cmd *set_rec_mode_cmd; +extern cmd *set_send_carrier_cmd; +extern cmd *set_rec_carrier_cmd; +extern cmd *set_send_duty_cycle_cmd; +extern cmd *set_transmitter_mask_cmd; +extern cmd *set_rec_timeout_cmd; +extern cmd *set_rec_timeout_reports_cmd; +extern cmd *set_measure_carrier_mode_cmd; +extern cmd *set_rec_carrier_range_cmd; +extern enum_type *mode_t_type; +extern enum_type *features_t_type; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct enum_type *g_enum_table[] = +{ + mode_t_type, + features_t_type, +}; + +static const struct cmd *g_cmd_table[] = +{ + /* CMD0 */ + + quit_cmd, + + /* CMD1 */ + + sleep_cmd, + help_cmd, + open_device_cmd, + close_device_cmd, + write_data_cmd, + get_features_cmd, + get_send_mode_cmd, + get_rec_mode_cmd, + get_rec_resolution_cmd, + get_min_timeout_cmd, + get_max_timeout_cmd, + get_length_cmd, + + /* CMD2 */ + + read_data_cmd, + set_send_mode_cmd, + set_rec_mode_cmd, + set_send_carrier_cmd, + set_rec_carrier_cmd, + set_send_duty_cycle_cmd, + set_transmitter_mask_cmd, + set_rec_timeout_cmd, + set_rec_timeout_reports_cmd, + set_measure_carrier_mode_cmd, + set_rec_carrier_range_cmd, + + /* CMD3 */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static ssize_t prompt(const char *p, char *buf, size_t len) +{ + fputs(p, stdout); + fflush(stdout); + return readline(buf, len, stdin, stdout); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +extern "C" +{ +int main(int argc, char *argv[]) +{ + char cmdline[512]; + + init_device(); + + while (prompt("$", cmdline, sizeof(cmdline))) + { + const char *name = get_fisrt_arg(cmdline); + if (name != 0 && *name != 0) + { + int res = -ENOSYS; + const cmd *cmd = &__start_cmds; + for (; cmd < &__stop_cmds; cmd++) + { + if (strcmp(name, cmd->name) == 0) + { + res = cmd->exec(); + break; + } + } + + if (res < 0) + { + printf("%s: %s(%d)\n", name, strerror(-res), res); + } + } + } + + return 0; +} +}