mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #7883 from Hyungsin/hamilton-pushbutton
pulse counter driver: initial SAUL-compatible implementation
This commit is contained in:
commit
934b075f76
@ -131,6 +131,11 @@ ifneq (,$(filter hdc1000,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter pulse_counter,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
endif
|
||||
|
||||
ifneq (,$(filter hih6130,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
@ -58,6 +58,9 @@ endif
|
||||
ifneq (,$(filter my9221,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/my9221/include
|
||||
endif
|
||||
ifneq (,$(filter pulse_counter,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/pulse_counter/include
|
||||
endif
|
||||
ifneq (,$(filter ina220,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ina220/include
|
||||
endif
|
||||
|
90
drivers/include/pulse_counter.h
Normal file
90
drivers/include/pulse_counter.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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_pulse_counter extra sensor
|
||||
* @ingroup drivers_sensors
|
||||
*
|
||||
* The connection between the MCU and the PULSE_COUNTER is based on the
|
||||
* GPIO-interface.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Driver for the PULSE_COUNTER extra sensor
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*/
|
||||
|
||||
#ifndef PULSE_COUNTER_H
|
||||
#define PULSE_COUNTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Parameters needed for device initialization
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_t gpio; /**< GPIO pin that sensor is connected to */
|
||||
gpio_flank_t gpio_flank; /**< GPIO flank option */
|
||||
} pulse_counter_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for a PULSE_COUNTER device
|
||||
*/
|
||||
typedef struct {
|
||||
int16_t pulse_count; /**< pulse counter */
|
||||
} pulse_counter_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize an PULSE_COUNTER device
|
||||
*
|
||||
* @param[out] dev device descriptor
|
||||
* @param[in] params configuration parameters
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int pulse_counter_init(pulse_counter_t *dev, const pulse_counter_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Read and reset PULSE_COUNTER value
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return Accumulated pulse counts
|
||||
*/
|
||||
int16_t pulse_counter_read_with_reset(const void *dev);
|
||||
|
||||
/**
|
||||
* @brief Read PULSE_COUNTER value
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*
|
||||
* @return Accumulated pulse counts
|
||||
*/
|
||||
int16_t pulse_counter_read_without_reset(const void *dev);
|
||||
|
||||
/**
|
||||
* @brief Reset PULSE_COUNTER value
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor
|
||||
*/
|
||||
void pulse_counter_reset(const void *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PULSE_COUNTER_H */
|
||||
/** @} */
|
@ -92,6 +92,7 @@ enum {
|
||||
SAUL_SENSE_ANALOG = 0x8a, /**< sensor: raw analog value */
|
||||
SAUL_SENSE_UV = 0x8b, /**< sensor: UV index */
|
||||
SAUL_SENSE_OBJTEMP = 0x8c, /**< sensor: object temperature */
|
||||
SAUL_SENSE_COUNT = 0x8d, /**< sensor: pulse counter */
|
||||
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
|
||||
/* extend this list as needed... */
|
||||
};
|
||||
|
1
drivers/pulse_counter/Makefile
Normal file
1
drivers/pulse_counter/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
68
drivers/pulse_counter/include/pulse_counter_params.h
Normal file
68
drivers/pulse_counter/include/pulse_counter_params.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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_pulse_counter
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for PULSE_COUNTER devices
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*/
|
||||
|
||||
#ifndef PULSE_COUNTER_PARAMS_H
|
||||
#define PULSE_COUNTER_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "pulse_counter.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef PULSE_COUNTER_GPIO
|
||||
#define PULSE_COUNTER_GPIO GPIO_PIN(0,18)
|
||||
#endif
|
||||
|
||||
#ifndef PULSE_COUNTER_GPIO_FLANK
|
||||
#define PULSE_COUNTER_GPIO_FLANK GPIO_FALLING
|
||||
#endif
|
||||
|
||||
#ifndef PULSE_COUNTER_PARAMS
|
||||
#define PULSE_COUNTER_PARAMS { .gpio = PULSE_COUNTER_GPIO, \
|
||||
.gpio_flank = PULSE_COUNTER_GPIO_FLANK }
|
||||
#endif
|
||||
|
||||
#ifndef PULSE_COUNTER_SAUL_INFO
|
||||
#define PULSE_COUNTER_SAUL_INFO { .name = "pulse counter" }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PULSE_COUNTER configuration
|
||||
*/
|
||||
static const pulse_counter_params_t pulse_counter_params[] =
|
||||
{
|
||||
PULSE_COUNTER_PARAMS,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Additional meta information to keep in the SAUL registry
|
||||
*/
|
||||
static const saul_reg_info_t pulse_counter_saul_info[] =
|
||||
{
|
||||
PULSE_COUNTER_SAUL_INFO
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PULSE_COUNTER_PARAMS_H */
|
||||
/** @} */
|
70
drivers/pulse_counter/pulse_counter.c
Normal file
70
drivers/pulse_counter/pulse_counter.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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_pulse_counter
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Driver for the PULSE COUNTER.
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pulse_counter_params.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* Accumulate pulse count */
|
||||
static void pulse_counter_trigger(void *arg)
|
||||
{
|
||||
pulse_counter_t *dev = (pulse_counter_t *)arg;
|
||||
|
||||
/* Use atomic operations to avoid messing with IRQ flags */
|
||||
__atomic_fetch_add(&(dev->pulse_count), 1, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/* Initialize pulse counter */
|
||||
int pulse_counter_init(pulse_counter_t *dev, const pulse_counter_params_t *params)
|
||||
{
|
||||
if (gpio_init_int(params->gpio, GPIO_IN_PU, params->gpio_flank, pulse_counter_trigger, dev)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev->pulse_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the accumulated pulse counts and reset the count to zero */
|
||||
int16_t pulse_counter_read_with_reset(const void *dev)
|
||||
{
|
||||
int16_t pulse_count_output = 0;
|
||||
int16_t reset_value = 0;
|
||||
|
||||
/* Use atomic operations to avoid messing with IRQ flags */
|
||||
__atomic_exchange(&(((pulse_counter_t *)dev)->pulse_count), &reset_value, &pulse_count_output, __ATOMIC_SEQ_CST);
|
||||
return pulse_count_output;
|
||||
}
|
||||
|
||||
/* Return the accumulated pulse counts */
|
||||
int16_t pulse_counter_read_without_reset(const void *dev)
|
||||
{
|
||||
return ((pulse_counter_t *)dev)->pulse_count;
|
||||
}
|
||||
|
||||
/* Reset the pulse count value to zero */
|
||||
void pulse_counter_reset(const void *dev)
|
||||
{
|
||||
((pulse_counter_t *)dev)->pulse_count = 0;
|
||||
}
|
45
drivers/pulse_counter/pulse_counter_saul.c
Normal file
45
drivers/pulse_counter/pulse_counter_saul.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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_pulse_counter
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PULSE_COUNTER adaption to the RIOT actuator/sensor interface
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "saul.h"
|
||||
#include "pulse_counter.h"
|
||||
|
||||
static int read_pulse_counter(const void *dev, phydat_t *res)
|
||||
{
|
||||
res->val[0] = pulse_counter_read_with_reset(dev);
|
||||
res->unit = UNIT_NONE;
|
||||
res->scale = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int write_pulse_counter(const void *dev, phydat_t *data)
|
||||
{
|
||||
pulse_counter_reset(dev);
|
||||
(void) data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t pulse_counter_saul_driver = {
|
||||
.read = read_pulse_counter,
|
||||
.write = write_pulse_counter,
|
||||
.type = SAUL_SENSE_COUNT,
|
||||
};
|
@ -48,6 +48,7 @@ const char *saul_class_to_str(const uint8_t class_id)
|
||||
case SAUL_SENSE_PRESS: return "SENSE_PRESS";
|
||||
case SAUL_SENSE_ANALOG: return "SENSE_ANALOG";
|
||||
case SAUL_SENSE_OBJTEMP:return "SENSE_OBJTEMP";
|
||||
case SAUL_SENSE_COUNT: return "SENSE_PULSE_COUNT";
|
||||
case SAUL_CLASS_ANY: return "CLASS_ANY";
|
||||
default: return "CLASS_UNKNOWN";
|
||||
}
|
||||
|
@ -323,6 +323,10 @@ auto_init_mpu9150();
|
||||
extern void auto_init_tsl2561(void);
|
||||
auto_init_tsl2561();
|
||||
#endif
|
||||
#ifdef MODULE_PULSE_COUNTER
|
||||
extern void auto_init_pulse_counter(void);
|
||||
auto_init_pulse_counter();
|
||||
#endif
|
||||
#ifdef MODULE_HDC1000
|
||||
extern void auto_init_hdc1000(void);
|
||||
auto_init_hdc1000();
|
||||
|
74
sys/auto_init/saul/auto_init_pulse_counter.c
Normal file
74
sys/auto_init/saul/auto_init_pulse_counter.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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 auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization for PULSE_COUNTER devices
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_PULSE_COUNTER
|
||||
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
#include "pulse_counter_params.h"
|
||||
|
||||
/**
|
||||
* @brief Define the number of configured sensors
|
||||
*/
|
||||
#define PULSE_COUNTER_NUM (sizeof(pulse_counter_params) / sizeof(pulse_counter_params[0]))
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for the device descriptors
|
||||
*/
|
||||
static pulse_counter_t pulse_counter_devs[PULSE_COUNTER_NUM];
|
||||
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[PULSE_COUNTER_NUM];
|
||||
|
||||
/**
|
||||
* @brief Define the number of configured sensors
|
||||
*/
|
||||
#define PULSE_COUNTER_INFO_NUM (sizeof(pulse_counter_saul_info) / sizeof(pulse_counter_saul_info[0]))
|
||||
|
||||
/**
|
||||
* @brief Reference the driver struct
|
||||
*/
|
||||
extern saul_driver_t pulse_counter_saul_driver;
|
||||
|
||||
void auto_init_pulse_counter(void)
|
||||
{
|
||||
assert(PULSE_COUNTER_NUM == PULSE_COUNTER_INFO_NUM)
|
||||
for (unsigned i = 0; i < PULSE_COUNTER_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing pulse_counter #%u\n", i);
|
||||
|
||||
int res = pulse_counter_init(&pulse_counter_devs[i], &pulse_counter_params[i]);
|
||||
if (res != 0) {
|
||||
LOG_ERROR("[auto_init_saul] error initializing pulse_counter #%u\n", i);
|
||||
}
|
||||
else {
|
||||
saul_entries[i].dev = &(pulse_counter_devs[i]);
|
||||
saul_entries[i].name = pulse_counter_saul_info[i].name;
|
||||
saul_entries[i].driver = &pulse_counter_saul_driver;
|
||||
saul_reg_add(&(saul_entries[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_PULSE_COUNTER */
|
7
tests/driver_pulse_counter/Makefile
Normal file
7
tests/driver_pulse_counter/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
BOARD_BLACKLIST := msb-430 msb-430h telosb wsn430-v1_3b wsn430-v1_4 z1
|
||||
|
||||
USEMODULE += pulse_counter
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
12
tests/driver_pulse_counter/README.md
Normal file
12
tests/driver_pulse_counter/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# About
|
||||
This is a manual test application for the PULSE_COUNTER driver.
|
||||
|
||||
# Usage
|
||||
This test application will initialize the PULSE_COUNTER sensor with the configuration
|
||||
as specified in the default `pulse_counter_params.h` file.
|
||||
|
||||
If you want to use this test application with different parameters, you can
|
||||
simply override the default PULSE_COUNTER_PARAMS.
|
||||
|
||||
After initialization, the sensor reads the pulse counter values every second and
|
||||
prints them to STDOUT.
|
52
tests/driver_pulse_counter/main.c
Normal file
52
tests/driver_pulse_counter/main.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2017 UC Berkeley
|
||||
*
|
||||
* 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 tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the PULSE_COUNTER driver
|
||||
*
|
||||
* @author Hyung-Sin Kim <hs.kim@cs.berkeley.edu>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "pulse_counter_params.h"
|
||||
|
||||
#define SLEEP US_PER_SEC
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pulse_counter_t dev;
|
||||
|
||||
printf("PULSE_COUNTER driver test application\n");
|
||||
|
||||
/* Initialization */
|
||||
if (pulse_counter_init(&dev, &pulse_counter_params[0])) {
|
||||
printf("[Failed]");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
printf("[OK]\n");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Pulse counter reading */
|
||||
int16_t count = pulse_counter_read_with_reset(&dev);
|
||||
printf("pulse counter: %d\n", count);
|
||||
|
||||
xtimer_usleep(SLEEP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user