From 8562e17ef13f7138f69d9509be1430adb21f869a Mon Sep 17 00:00:00 2001 From: dongjiuzhu Date: Thu, 29 Oct 2020 21:05:33 +0800 Subject: [PATCH] rc/dummy: add dummy driver to test driver skeleton N/A Change-Id: Iae3c22587f9939f6923b102bf4c51bb7f88a6429 Signed-off-by: dongjiuzhu --- drivers/rc/Kconfig | 16 +++ drivers/rc/Make.defs | 4 + drivers/rc/dummy.c | 234 +++++++++++++++++++++++++++++++++++++++ include/nuttx/rc/dummy.h | 51 +++++++++ 4 files changed, 305 insertions(+) create mode 100644 drivers/rc/dummy.c create mode 100644 include/nuttx/rc/dummy.h diff --git a/drivers/rc/Kconfig b/drivers/rc/Kconfig index c76c7ec6b5..65cf457181 100644 --- a/drivers/rc/Kconfig +++ b/drivers/rc/Kconfig @@ -8,3 +8,19 @@ menuconfig DRIVERS_RC default n ---help--- Drivers for various remote control + +if DRIVERS_RC + +config RC_DUMMY + bool "Dummy RC Device Support" + select SCHED_LPWORK + default n + ---help--- + We test RC driver architecture by dummy rc device. + Test Item: 1. Test all the IOCTL commands; 2. Test all API interface, + ex: tx_ir, tx_scancode; 3. We use the way of workqueue to periodically + feed data to the downstream buffer(userspace->kernelspace) to simulate + reading data from IR device; 4. Write IR data to device by tx_ir/tx_scancode + to simulate as remote control. + +endif # DRIVERS_RC diff --git a/drivers/rc/Make.defs b/drivers/rc/Make.defs index 4deffdb88c..cd52d0430c 100644 --- a/drivers/rc/Make.defs +++ b/drivers/rc/Make.defs @@ -24,6 +24,10 @@ ifeq ($(CONFIG_DRIVERS_RC),y) CSRCS += lirc_dev.c +ifeq ($(CONFIG_RC_DUMMY),y) +CSRCS += dummy.c +endif + # Include remote control driver build support DEPPATH += --dep-path rc diff --git a/drivers/rc/dummy.c b/drivers/rc/dummy.c new file mode 100644 index 0000000000..074deba353 --- /dev/null +++ b/drivers/rc/dummy.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * drivers/rc/dummy.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 + +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DUMMY_MAX_EVENT_SIZE 512 +#define DUMMY_WORK_PERIOD SEC2TICK(1) + +/**************************************************************************** + * Private + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int dummy_open(FAR struct lirc_lowerhalf_s *lower); +static void dummy_close(FAR struct lirc_lowerhalf_s *lower); +static int dummy_s_tx_mask(FAR struct lirc_lowerhalf_s *lower, + unsigned int mask); +static int dummy_s_tx_carrier(FAR struct lirc_lowerhalf_s *lower, + unsigned int carrier); +static int dummy_s_tx_duty_cycle(FAR struct lirc_lowerhalf_s *lower, + unsigned int duty_cycle); +static int dummy_s_rx_carrier_range(FAR struct lirc_lowerhalf_s *lower, + unsigned int min, unsigned int max); +static int dummy_tx_ir(FAR struct lirc_lowerhalf_s *lower, + FAR unsigned int *txbuf, unsigned int n); +static int dummy_tx_scancode(FAR struct lirc_lowerhalf_s *lower, + FAR struct lirc_scancode *txbuf); +static int dummy_s_learning_mode(FAR struct lirc_lowerhalf_s *lower, + int enable); +static int dummy_s_carrier_report(FAR struct lirc_lowerhalf_s *lower, + int enable); +static int dummy_s_timeout(FAR struct lirc_lowerhalf_s *lower, + unsigned int timeout); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct dummy_dev_s +{ + struct lirc_lowerhalf_s lower; + struct work_s work; + unsigned test_sample; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct lirc_ops_s g_dummy_ops = +{ + .driver_type = LIRC_DRIVER_IR_RAW, + .open = dummy_open, + .close = dummy_close, + .s_tx_mask = dummy_s_tx_mask, + .s_tx_carrier = dummy_s_tx_carrier, + .s_tx_duty_cycle = dummy_s_tx_duty_cycle, + .s_rx_carrier_range = dummy_s_rx_carrier_range, + .tx_ir = dummy_tx_ir, + .tx_scancode = dummy_tx_scancode, + .s_learning_mode = dummy_s_learning_mode, + .s_carrier_report = dummy_s_carrier_report, + .s_timeout = dummy_s_timeout, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void dummy_worker(FAR void *arg) +{ + struct dummy_dev_s *dummy = arg; + unsigned sample = dummy->test_sample; + + if (sample % 2 == 0) + { + sample = LIRC_SPACE(sample); + } + else + { + sample = LIRC_PULSE(sample); + } + + lirc_sample_event(&dummy->lower, sample); + + rcinfo("Dummy RC read Raw Data from device:%d\n", sample); + dummy->test_sample++; + + work_queue(LPWORK, &dummy->work, dummy_worker, dummy, + DUMMY_WORK_PERIOD); +} + +static int dummy_open(FAR struct lirc_lowerhalf_s *lower) +{ + struct dummy_dev_s *dummy = (struct dummy_dev_s *)lower; + + rcinfo("Called %s\n", __func__); + + dummy->test_sample = 0; + return work_queue(LPWORK, &dummy->work, dummy_worker, dummy, + DUMMY_WORK_PERIOD); +} + +static void dummy_close(FAR struct lirc_lowerhalf_s *lower) +{ + struct dummy_dev_s *dummy = (struct dummy_dev_s *)lower; + + rcinfo("Called %s\n", __func__); + + work_cancel(LPWORK, &dummy->work); +} + +static int dummy_s_tx_mask(FAR struct lirc_lowerhalf_s *lower, + unsigned int mask) +{ + rcinfo("Called %s, mask:%u\n", __func__, mask); + return 0; +} + +static int dummy_s_tx_carrier(FAR struct lirc_lowerhalf_s *lower, + unsigned int carrier) +{ + rcinfo("Called %s, carrier:%u\n", __func__, carrier); + return 0; +} + +static int dummy_s_tx_duty_cycle(FAR struct lirc_lowerhalf_s *lower, + unsigned int duty_cycle) +{ + rcinfo("Called %s, duty_cycle:%u\n", __func__, duty_cycle); + return 0; +} + +static int dummy_s_rx_carrier_range(FAR struct lirc_lowerhalf_s *lower, + unsigned int min, unsigned int max) +{ + rcinfo("Called %s, min:%u, max:%u\n", __func__, min, max); + return 0; +} + +static int dummy_tx_ir(FAR struct lirc_lowerhalf_s *lower, + unsigned *txbuf, unsigned int n) +{ + rcinfo("Dummy RC send raw data:%d(size:%d) to device\n", *txbuf, n); + return n; +} + +static int dummy_tx_scancode(FAR struct lirc_lowerhalf_s *lower, + FAR struct lirc_scancode *txbuf) +{ + rcinfo("Dummy RC send scancode data:%u to device\n", txbuf->scancode); + return 0; +} + +static int dummy_s_learning_mode(FAR struct lirc_lowerhalf_s *lower, + int enable) +{ + rcinfo("Called %s, enable:%d\n", __func__, enable); + return 0; +} + +static int dummy_s_carrier_report(FAR struct lirc_lowerhalf_s *lower, + int enable) +{ + rcinfo("Called %s, enable:%d\n", __func__, enable); + return 0; +} + +static int dummy_s_timeout(FAR struct lirc_lowerhalf_s *lower, + unsigned int timeout) +{ + rcinfo("Called %s, timeout:%u\n", __func__, timeout); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int rc_dummy_initialize(int devno) +{ + struct dummy_dev_s *dummy; + + dummy = kmm_malloc(sizeof(*dummy)); + if (!dummy) + { + rcerr("failed to alloc memory for dummy\n"); + return -ENOMEM; + } + + dummy->lower.ops = &g_dummy_ops; + dummy->lower.buffer_bytes = DUMMY_MAX_EVENT_SIZE * sizeof(unsigned); + + dummy->work.worker = NULL; + dummy->test_sample = 0; + + return lirc_register(&dummy->lower, devno); +} diff --git a/include/nuttx/rc/dummy.h b/include/nuttx/rc/dummy.h new file mode 100644 index 0000000000..3b5385161a --- /dev/null +++ b/include/nuttx/rc/dummy.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * include/nuttx/rc/dummy.h + * + * 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 __INCLUDE_NUTTX_RC_DUMMY_H +#define __INCLUDE_NUTTX_RC_DUMMY_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +int rc_dummy_initialize(int devno); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif