1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 00:29:46 +01:00

drivers/ir_nec: ir remote implementation

This commit is contained in:
Dario Petrillo 2022-04-13 20:18:24 +02:00
parent 32ac29bd98
commit 18f8a476e6
No known key found for this signature in database
GPG Key ID: 3A137B00436E37AB
9 changed files with 294 additions and 0 deletions

View File

@ -10084,6 +10084,8 @@ drivers/io1_xplained/include/io1_xplained_internals\.h:[0-9]+: warning: Member I
drivers/io1_xplained/include/io1_xplained_params\.h:[0-9]+: warning: Member IO1_XPLAINED_PARAMS \(macro definition\) of file io1_xplained_params\.h is not documented\.
drivers/io1_xplained/include/io1_xplained_params\.h:[0-9]+: warning: Member IO1_XPLAINED_PARAM_ADDR \(macro definition\) of file io1_xplained_params\.h is not documented\.
drivers/io1_xplained/include/io1_xplained_params\.h:[0-9]+: warning: Member IO1_XPLAINED_SAUL_INFO \(macro definition\) of file io1_xplained_params\.h is not documented\.
drivers/ir_nec/include/ir_nec_params\.h:35: warning: Member IR_NEC_PARAM_PIN \(macro definition\) of file ir_nec_params\.h is not documented\.
drivers/ir_nec/include/ir_nec_params\.h:39: warning: Member IR_NEC_PARAMS \(macro definition\) of file ir_nec_params\.h is not documented\.
drivers/isl29020/include/isl29020\-internal\.h:[0-9]+: warning: Member ISL29020_CMD_EN \(macro definition\) of file isl29020\-internal\.h is not documented\.
drivers/isl29020/include/isl29020\-internal\.h:[0-9]+: warning: Member ISL29020_CMD_LIGHT \(macro definition\) of file isl29020\-internal\.h is not documented\.
drivers/isl29020/include/isl29020\-internal\.h:[0-9]+: warning: Member ISL29020_CMD_MODE \(macro definition\) of file isl29020\-internal\.h is not documented\.

88
drivers/include/ir_nec.h Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2022 Dario Petrillo
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup drivers_ir_nec IR NEC Remote receiver
* @ingroup drivers_misc
* @brief Receives commands from NEC IR remotes
*
* @{
*
* @file
*
* @author Dario Petrillo <dario.pk1@gmail.com>
*/
#ifndef IR_NEC_H
#define IR_NEC_H
#include <stdint.h>
#include "isrpipe.h"
#include "periph/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief NEC command structure
*/
typedef struct {
uint8_t addr; /**< Address (usually 0, depends on the remote) */
uint8_t cmd; /**< Command */
} ir_nec_cmd_t;
/**
* @brief Device initialization parameters
*/
typedef struct {
gpio_t pin; /**< Input pin */
} ir_nec_params_t;
/**
* @brief Device descriptor for the driver
*/
typedef struct {
gpio_t pin; /**< Input pin */
isrpipe_t isrpipe; /**< Internal pipe for commands */
uint32_t last_rising; /**< Timestamp of the last rising edge */
uint32_t data; /**< Data packet being received */
uint8_t read_bits; /**< Number of bits read so far. 0xff if not currently reading */
uint8_t isrpipe_buf[2 * sizeof(ir_nec_cmd_t)]; /**< Buffer for the isrpipe */
} ir_nec_t;
/**
* @brief Initialize the given device
*
* @param[inout] dev Device descriptor of the driver
* @param[in] params Initialization parameters
*
* @return 0 on success
*/
int ir_nec_init(ir_nec_t *dev, const ir_nec_params_t *params);
/**
* @brief Read a command packet. Blocks until one is received
*
* @param[inout] dev Device descriptor of the driver
* @param[out] command Structure to write the result into
*
* @retval 0 Success
* @retval -1 Isrpipe returned too few bytes. Should never happen
*/
int ir_nec_read(ir_nec_t *dev, ir_nec_cmd_t *command);
#ifdef __cplusplus
}
#endif
#endif /* IR_NEC_H */
/** @} */

13
drivers/ir_nec/Kconfig Normal file
View File

@ -0,0 +1,13 @@
# Copyright (c) 2022 Dario Petrillo
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
config MODULE_IR_NEC
bool "IR NEC Remote receiver"
depends on TEST_KCONFIG
select MODULE_ISRPIPE
select MODULE_PERIPH_GPIO_IRQ
select MODULE_ZTIMER
select MODULE_ZTIMER_USEC

1
drivers/ir_nec/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,4 @@
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
USEMODULE += isrpipe
USEMODULE += ztimer_usec

View File

@ -0,0 +1,2 @@
USEMODULE_INCLUDES_ir_nec := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_ir_nec)

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2022 Dario Petrillo
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_ir_nec
* @{
*
* @file
* @brief Internal addresses, registers and constants
*
* @author Dario Petrillo <dario.pk1@gmail.com>
*/
#ifndef IR_NEC_CONSTANTS_H
#define IR_NEC_CONSTANTS_H
#ifdef __cplusplus
extern "C" {
#endif
#define IR_NEC_START_US 4500 /**< Width of the start pulse, in microseconds */
#define IR_NEC_ZERO_US 562 /**< Width of the zero pulse, in microseconds */
#define IR_NEC_ONE_US 1687 /**< Width of the one pulse, in microseconds */
#define IR_NEC_EPS_US 350 /**< Maximum timing deviation for value detection, in microseconds */
#ifdef __cplusplus
}
#endif
#endif /* IR_NEC_CONSTANTS_H */
/** @} */

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2022 Dario Petrillo
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_ir_nec
*
* @{
* @file
* @brief Default configuration
*
* @author Dario Petrillo <dario.pk1@gmail.com>
*/
#ifndef IR_NEC_PARAMS_H
#define IR_NEC_PARAMS_H
#include "board.h"
#include "ir_nec.h"
#include "ir_nec_constants.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Set default configuration parameters
* @{
*/
#ifndef IR_NEC_PARAM_PIN
#define IR_NEC_PARAM_PIN GPIO_UNDEF
#endif
#ifndef IR_NEC_PARAMS
#define IR_NEC_PARAMS { .pin = IR_NEC_PARAM_PIN }
#endif
/**@}*/
/**
* @brief Configuration struct
*/
static const ir_nec_params_t ir_nec_params[] =
{
IR_NEC_PARAMS
};
#ifdef __cplusplus
}
#endif
#endif /* IR_NEC_PARAMS_H */
/** @} */

92
drivers/ir_nec/ir_nec.c Normal file
View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2022 Dario Petrillo
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_ir_nec
* @{
*
* @file
* @brief Device driver implementation for the IR NEC Remote receiver
*
* @author Dario Petrillo <dario.pk1@gmail.com>
*
* @}
*/
#include "ir_nec.h"
#include "ir_nec_constants.h"
#include "ir_nec_params.h"
#include <stdlib.h>
#include "ztimer.h"
#include "ir_nec.h"
static void ir_nec_isr(void *arg)
{
ir_nec_t *ir = (ir_nec_t *)arg;
if (gpio_read(ir->pin) != 0) { // rising edge
ir->last_rising = ztimer_now(ZTIMER_USEC);
}
else { // falling edge
int length = ztimer_now(ZTIMER_USEC) - ir->last_rising;
if (abs(length - IR_NEC_START_US) <= IR_NEC_EPS_US) {
ir->data = 0;
ir->read_bits = 0;
}
else if ((length - IR_NEC_ZERO_US) <= IR_NEC_EPS_US && ir->read_bits < 32) {
ir->data = (ir->data << 1);
ir->read_bits++;
}
else if (abs(length - IR_NEC_ONE_US) <= IR_NEC_EPS_US && ir->read_bits < 32) {
ir->data = (ir->data << 1) | 1;
ir->read_bits++;
}
else { // Interpacket delay
ir->read_bits = 0xff;
}
if (ir->read_bits == 32) {
ir->read_bits = 0xff;
uint8_t addr = (ir->data >> 24) & 0xff;
uint8_t addr_inv = (ir->data >> 16) & 0xff;
uint8_t cmd = (ir->data >> 8) & 0xff;
uint8_t cmd_inv = ir->data & 0xff;
if ((addr ^ addr_inv) == 0xff && (cmd ^ cmd_inv) == 0xff) {
ir_nec_cmd_t command = { .addr = addr, .cmd = cmd };
isrpipe_write(&ir->isrpipe, (void*)&command, sizeof(command));
}
}
}
}
int ir_nec_read(ir_nec_t *ir, ir_nec_cmd_t *command)
{
int to_read = sizeof(ir_nec_cmd_t);
if (isrpipe_read(&ir->isrpipe, (void*)command, to_read) != to_read) {
return -1;
}
return 0;
}
int ir_nec_init(ir_nec_t *ir, const ir_nec_params_t *params)
{
ir->pin = params->pin;
ir->data = 0;
ir->last_rising = 0;
ir->read_bits = 0;
isrpipe_init(&ir->isrpipe, ir->isrpipe_buf, sizeof(ir->isrpipe_buf));
gpio_init_int(ir->pin, GPIO_IN, GPIO_BOTH, ir_nec_isr, ir);
return 0;
}