Browse Source

Merge pull request #3538 from haukepetersen/add_sensif_actif

Introducing SAUL, the [S]ensor [A]ctuator [U]ber [L]ayer
cc430
Kaspar Schleiser 7 years ago
parent
commit
e53dc6f5e2
  1. 16
      Makefile.dep
  2. 2
      Makefile.pseudomodules
  3. 6
      boards/fox/Makefile.dep
  4. 58
      boards/fox/include/l3g4200d_params.h
  5. 56
      boards/fox/include/lps331ap_params.h
  6. 62
      boards/fox/include/lsm303dlhc_params.h
  7. 8
      boards/iotlab-m3/Makefile.dep
  8. 56
      boards/iotlab-m3/include/gpio_params.h
  9. 57
      boards/iotlab-m3/include/isl29020_params.h
  10. 59
      boards/iotlab-m3/include/l3g4200d_params.h
  11. 56
      boards/iotlab-m3/include/lps331ap_params.h
  12. 62
      boards/iotlab-m3/include/lsm303dlhc_params.h
  13. 1
      boards/samr21-xpro/include/board.h
  14. 48
      boards/samr21-xpro/include/gpio_params.h
  15. 10
      drivers/include/isl29020.h
  16. 36
      drivers/include/l3g4200d.h
  17. 9
      drivers/include/lps331ap.h
  18. 55
      drivers/include/lsm303dlhc.h
  19. 157
      drivers/include/saul.h
  20. 42
      drivers/include/saul/periph.h
  21. 45
      drivers/isl29020/isl29020_saul.c
  22. 44
      drivers/l3g4200d/l3g4200d_saul.c
  23. 45
      drivers/lps331ap/lps331ap_saul.c
  24. 59
      drivers/lsm303dlhc/lsm303dlhc_saul.c
  25. 7
      drivers/saul/Makefile
  26. 49
      drivers/saul/gpio_saul.c
  27. 52
      drivers/saul/saul_str.c
  28. 16
      examples/default/Makefile
  29. 4
      sys/auto_init/Makefile
  30. 27
      sys/auto_init/auto_init.c
  31. 3
      sys/auto_init/saul/Makefile
  32. 73
      sys/auto_init/saul/auto_init_gpio.c
  33. 74
      sys/auto_init/saul/auto_init_isl29020.c
  34. 74
      sys/auto_init/saul/auto_init_l3g4200d.c
  35. 74
      sys/auto_init/saul/auto_init_lps331ap.c
  36. 82
      sys/auto_init/saul/auto_init_lsm303dlhc.c
  37. 175
      sys/include/phydat.h
  38. 144
      sys/include/saul_reg.h
  39. 1
      sys/phydat/Makefile
  40. 81
      sys/phydat/phydat_str.c
  41. 1
      sys/saul_reg/Makefile
  42. 133
      sys/saul_reg/saul_reg.c
  43. 15
      sys/shell/commands/Makefile
  44. 75
      sys/shell/commands/sc_isl29020.c
  45. 77
      sys/shell/commands/sc_l3g4200d.c
  46. 86
      sys/shell/commands/sc_lps331ap.c
  47. 98
      sys/shell/commands/sc_lsm303dlhc.c
  48. 155
      sys/shell/commands/sc_saul_reg.c
  49. 43
      sys/shell/commands/shell_commands.c

16
Makefile.dep

@ -390,3 +390,19 @@ endif
ifneq (,$(filter xtimer,$(USEMODULE)))
FEATURES_REQUIRED += periph_timer
endif
ifneq (,$(filter saul_reg,$(USEMODULE)))
USEMODULE += saul
endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul
endif
ifneq (,$(filter saul,$(USEMODULE)))
USEMODULE += phydat
endif
ifneq (,$(filter phydat,$(USEMODULE)))
USEMODULE += fmt
endif

2
Makefile.pseudomodules

@ -19,6 +19,8 @@ PSEUDOMODULES += newlib
PSEUDOMODULES += pktqueue
PSEUDOMODULES += schedstatistics
PSEUDOMODULES += netif
PSEUDOMODULES += saul_default
PSEUDOMODULES += saul_gpio
# include variants of the AT86RF2xx drivers as pseudo modules
PSEUDOMODULES += at86rf23%

6
boards/fox/Makefile.dep

@ -2,3 +2,9 @@ ifneq (,$(filter gnrc_netif_default,$(USEMODULE)))
USEMODULE += at86rf231
USEMODULE += gnrc_nomac
endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += lps331ap
USEMODULE += l3g4200d
USEMODULE += lsm303dlhc
endif

58
boards/fox/include/l3g4200d_params.h

@ -0,0 +1,58 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_fox
*
* @file
* @brief L3G4200D board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef L3G4200D_PARAMS_H
#define L3G4200D_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief L3G4200D configuration
*/
static const l3g4200d_params_t l3g4200d_params[] =
{
{
.i2c = L3G4200D_I2C,
.addr = L3G4200D_ADDR,
.int1_pin = L3G4200D_INT,
.int2_pin = L3G4200D_DRDY,
.mode = L3G4200D_MODE_200_25,
.scale = L3G4200D_SCALE_500DPS,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t l3g4200d_saul_info[] =
{
{
.name = "l3g4200d",
},
};
#ifdef __cplusplus
}
#endif
#endif /* L3G4200D_PARAMS_H */
/** @} */

56
boards/fox/include/lps331ap_params.h

@ -0,0 +1,56 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_fox
* @{
*
* @file
* @brief LPS331AP board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LPS331AP_PARAMS_H
#define LPS331AP_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LPS331AP configuration
*/
static const lps331ap_params_t lps331ap_params[] =
{
{
.i2c = LPS331AP_I2C,
.addr = LPS331AP_ADDR,
.rate = LPS331AP_RATE_7HZ,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t lps331ap_saul_info[] =
{
{
.name = "lps331ap",
},
};
#ifdef __cplusplus
}
#endif
#endif /* LPS331AP_PARAMS_H */
/** @} */

62
boards/fox/include/lsm303dlhc_params.h

@ -0,0 +1,62 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_fox
* @{
*
* @file
* @brief LSM303DLHC board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LSM303DLHC_PARAMS_H
#define LSM303DLHC_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LSM303DLHC configuration
*/
static const lsm303dlhc_params_t lsm303dlhc_params[] =
{
{
.i2c = LSM303DLHC_I2C,
.acc_addr = LSM303DLHC_ACC_ADDR,
.acc_pin = LSM303DLHC_INT1,
.acc_rate = LSM303DLHC_ACC_SAMPLE_RATE_10HZ,
.acc_scale = LSM303DLHC_ACC_SCALE_4G,
.mag_addr = LSM303DLHC_MAG_ADDR,
.mag_pin = LSM303DLHC_DRDY,
.mag_rate = LSM303DLHC_MAG_SAMPLE_RATE_15HZ,
.mag_gain = LSM303DLHC_MAG_GAIN_450_400_GAUSS,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t lsm303dlhc_saul_info[] =
{
{
.name = "lsm303dlhc",
},
};
#ifdef __cplusplus
}
#endif
#endif /* LSM303DLHC_PARAMS_H */
/** @} */

8
boards/iotlab-m3/Makefile.dep

@ -2,3 +2,11 @@ ifneq (,$(filter gnrc_netif_default,$(USEMODULE)))
USEMODULE += at86rf231
USEMODULE += gnrc_nomac
endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
USEMODULE += isl29020
USEMODULE += lps331ap
USEMODULE += l3g4200d
USEMODULE += lsm303dlhc
endif

56
boards/iotlab-m3/include/gpio_params.h

@ -0,0 +1,56 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_iotlab-m3
* @{
*
* @file
* @brief Board specific configuration of direct mapped GPIOs
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef GPIO_PARAMS_H
#define GPIO_PARAMS_H
#include "board.h"
#include "saul/periph.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LED configuration
*/
static const saul_gpio_params_t saul_gpio_params[] =
{
{
.name = "LED(red)",
.pin = LED_RED_GPIO,
.dir = GPIO_DIR_OUT,
},
{
.name = "LED(green)",
.pin = LED_GREEN_GPIO,
.dir = GPIO_DIR_OUT,
},
{
.name = "LED(orange)",
.pin = LED_ORANGE_GPIO,
.dir = GPIO_DIR_OUT,
},
};
#ifdef __cplusplus
}
#endif
#endif /* GPIO_PARAMS_H */
/** @} */

57
boards/iotlab-m3/include/isl29020_params.h

@ -0,0 +1,57 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_iotlab-m3
* @{
*
* @file
* @brief ISL29020 board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef ISL29020_PARAMS_H
#define ISL29020_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ISL29020 parameter configuration
*/
static const isl29020_params_t isl29020_params[] =
{
{
.i2c = ISL29020_I2C,
.addr = ISL29020_ADDR,
.range = ISL29020_RANGE_16K,
.mode = ISL29020_MODE_AMBIENT,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t isl29020_saul_info[] =
{
{
.name = "isl29020",
},
};
#ifdef __cplusplus
}
#endif
#endif /* ISL29020_PARAMS_H */
/** @} */

59
boards/iotlab-m3/include/l3g4200d_params.h

@ -0,0 +1,59 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_iotlab-m3
* @{
*
* @file
* @brief L3G4200D board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef L3G4200D_PARAMS_H
#define L3G4200D_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief L3G4200D configuration
*/
static const l3g4200d_params_t l3g4200d_params[] =
{
{
.i2c = L3G4200D_I2C,
.addr = L3G4200D_ADDR,
.int1_pin = L3G4200D_INT,
.int2_pin = L3G4200D_DRDY,
.mode = L3G4200D_MODE_200_25,
.scale = L3G4200D_SCALE_500DPS,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t l3g4200d_saul_info[] =
{
{
.name = "l3g4200d",
},
};
#ifdef __cplusplus
}
#endif
#endif /* L3G4200D_PARAMS_H */
/** @} */

56
boards/iotlab-m3/include/lps331ap_params.h

@ -0,0 +1,56 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_iotlab-m3
* @{
*
* @file
* @brief LPS331AP board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LPS331AP_PARAMS_H
#define LPS331AP_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LPS331AP configuration
*/
static const lps331ap_params_t lps331ap_params[] =
{
{
.i2c = LPS331AP_I2C,
.addr = LPS331AP_ADDR,
.rate = LPS331AP_RATE_7HZ,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t lps331ap_saul_info[] =
{
{
.name = "lps331ap",
},
};
#ifdef __cplusplus
}
#endif
#endif /* LPS331AP_PARAMS_H */
/** @} */

62
boards/iotlab-m3/include/lsm303dlhc_params.h

@ -0,0 +1,62 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 boards_iotlab-m3
* @{
*
* @file
* @brief LSM303DLHC board specific configuration
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef LSM303DLHC_PARAMS_H
#define LSM303DLHC_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LSM303DLHC configuration
*/
static const lsm303dlhc_params_t lsm303dlhc_params[] =
{
{
.i2c = LSM303DLHC_I2C,
.acc_addr = LSM303DLHC_ACC_ADDR,
.acc_pin = LSM303DLHC_INT1,
.acc_rate = LSM303DLHC_ACC_SAMPLE_RATE_10HZ,
.acc_scale = LSM303DLHC_ACC_SCALE_4G,
.mag_addr = LSM303DLHC_MAG_ADDR,
.mag_pin = LSM303DLHC_DRDY,
.mag_rate = LSM303DLHC_MAG_SAMPLE_RATE_15HZ,
.mag_gain = LSM303DLHC_MAG_GAIN_450_400_GAUSS,
},
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t lsm303dlhc_saul_info[] =
{
{
.name = "lsm303dlhc",
},
};
#ifdef __cplusplus
}
#endif
#endif /* LSM303DLHC_PARAMS_H */
/** @} */

1
boards/samr21-xpro/include/board.h

@ -68,6 +68,7 @@ extern "C" {
*/
#define LED_PORT PORT->Group[0]
#define LED_PIN (19)
#define LED_GPIO GPIO_PIN(0, 19)
/** @} */
/**

48
boards/samr21-xpro/include/gpio_params.h

@ -0,0 +1,48 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* 2015 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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 boards_samr21-xpro
* @{
*
* @file
* @brief Board specific configuration of direct mapped GPIOs
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
#ifndef GPIO_PARAMS_H
#define GPIO_PARAMS_H
#include "board.h"
#include "saul/periph.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief GPIO pin configuration
*/
static const saul_gpio_params_t saul_gpio_params[] =
{
{
.name = "LED(orange)",
.pin = LED_GPIO,
.dir = GPIO_DIR_OUT,
},
};
#ifdef __cplusplus
}
#endif
#endif /* GPIO_PARAMS_H */
/** @} */

10
drivers/include/isl29020.h

@ -60,6 +60,16 @@ typedef enum {
ISL29020_RANGE_64K = 3 /**< set range to 0-64000 lux */
} isl29020_range_t;
/**
* @brief Data structure holding the full set of configuration parameters
*/
typedef struct {
i2c_t i2c; /**< I2C bus the device is connected to */
uint8_t addr; /**< address on that bus */
isl29020_range_t range; /**< range setting to use */
isl29020_mode_t mode; /**< measurement mode to use */
} isl29020_params_t;
/**
* @brief Initialize a new ISL29020 device
*

36
drivers/include/l3g4200d.h

@ -37,23 +37,12 @@
*/
#define L3G4200D_DEFAULT_ADDRESS 0x68
/**
* @brief Device descriptor for L3G4200D sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device the sensor is connected to */
uint8_t addr; /**< the sensors slave address on the I2C bus */
gpio_t int1; /**< INT1 pin */
gpio_t int2; /**< INT2 (DRDY) pin */
int32_t scale; /**< scaling factor to normalize results */
} l3g4200d_t;
/**
* @brief Result vector for gyro measurement
*/
typedef struct {
int16_t acc_x; /**< roll rate in dgs (degree per second) */
int16_t acc_y; /**< pitch rate in dgs */
int16_t acc_y; /**< pitch rate in dgs */
int16_t acc_z; /**< yaw rate in dgs */
} l3g4200d_data_t;
@ -86,6 +75,29 @@ typedef enum {
L3G4200D_MODE_800_110 = 0xf /**< data rate: 800Hz, cut-off: 110Hz */
} l3g4200d_mode_t;
/**
* @brief Device descriptor for L3G4200D sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device the sensor is connected to */
uint8_t addr; /**< the sensors slave address on the I2C bus */
gpio_t int1; /**< INT1 pin */
gpio_t int2; /**< INT2 (DRDY) pin */
int32_t scale; /**< scaling factor to normalize results */
} l3g4200d_t;
/**
* @brief Data structure holding the device parameters needed for initialization
*/
typedef struct {
i2c_t i2c; /**< I2C bus the device is connected to */
uint8_t addr; /**< the address on that bus */
gpio_t int1_pin; /**< GPIO pin connected to the INT1 line */
gpio_t int2_pin; /**< GPIO pin connected to the INT2 line */
l3g4200d_mode_t mode; /**< sampling mode to use */
l3g4200d_scale_t scale; /**< scaling to use */
} l3g4200d_params_t;
/**
* @brief Initialize a gyro
*

9
drivers/include/lps331ap.h

@ -53,6 +53,15 @@ typedef enum {
LPS331AP_RATE_25HZ = 7 /**< sample with 25Hz */
} lps331ap_rate_t;
/**
* @brief Struct holding all parameters needed for device initialization
*/
typedef struct {
i2c_t i2c; /**< I2C bus the sensor is connected to */
uint8_t addr; /**< the devices address on the bus */
lps331ap_rate_t rate; /**< tell sensor to sample with this rate */
} lps331ap_params_t;
/**
* @brief Initialize a given LPS331AP pressure sensor
*

55
drivers/include/lsm303dlhc.h

@ -35,26 +35,6 @@ extern "C" {
#define LSM303DLHC_ACC_DEFAULT_ADDRESS (0x19)
#define LSM303DLHC_MAG_DEFAULT_ADDRESS (0x1e)
/**
* @brief 3d data container
*/
typedef struct {
int16_t x_axis;
int16_t y_axis;
int16_t z_axis;
} lsm303dlhc_3d_data_t;
/**
* @brief Device descriptor for LSM303DLHC sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device */
uint8_t acc_address; /**< accelerometer's I2C address */
uint8_t mag_address; /**< magnetometer's I2C address */
gpio_t acc_pin; /**< accelerometer's data ready pin */
gpio_t mag_pin; /**< magnetometer's data ready pin */
} lsm303dlhc_t;
/**
* @brief Possible accelerometer sample rates
*/
@ -108,6 +88,41 @@ typedef enum {
LSM303DLHC_MAG_GAIN_230_205_GAUSS = 0xe0, /**< 230Gauss XYZ 205Gauss Z */
} lsm303dlhc_mag_gain_t;
/**
* @brief 3d data container
*/
typedef struct {
int16_t x_axis;
int16_t y_axis;
int16_t z_axis;
} lsm303dlhc_3d_data_t;
/**
* @brief Device descriptor for LSM303DLHC sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device */
uint8_t acc_address; /**< accelerometer's I2C address */
uint8_t mag_address; /**< magnetometer's I2C address */
gpio_t acc_pin; /**< accelerometer's data ready pin */
gpio_t mag_pin; /**< magnetometer's data ready pin */
} lsm303dlhc_t;
/**
* @brief Data structure holding all the information needed for initialization
*/
typedef struct {
i2c_t i2c; /**< I2C bus used */
uint8_t acc_addr; /**< accelerometer I2C address */
gpio_t acc_pin; /**< accelerometer EXTI pin */
lsm303dlhc_acc_sample_rate_t acc_rate; /**< accelerometer sample rate */
lsm303dlhc_acc_scale_t acc_scale; /**< accelerometer scale factor */
uint8_t mag_addr; /**< magnetometer I2C address */
gpio_t mag_pin; /**< magnetometer EXTI pin */
lsm303dlhc_mag_sample_rate_t mag_rate; /**< magnetometer sample rate */
lsm303dlhc_mag_gain_t mag_gain; /**< magnetometer gain */
} lsm303dlhc_params_t;
/**
* @brief Initialize a new LSM303DLHC device
*

157
drivers/include/saul.h

@ -0,0 +1,157 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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_saul [S]ensor [A]ctuator [U]ber [L]ayer
* @ingroup drivers
* @brief Generic sensor/actuator abstraction layer for RIOT
*
* SAUL is a generic actuator/sensor interface in RIOT. Its purpose is to
* enable unified interaction with a wide range of sensors and actuators through
* a set of defined access functions and a common data structure.
*
* Each device driver implementing this interface has to expose a set of
* predefined functions and it has to register itself to the central SAUL
* registry. From here devices can be found, listed, and accessed.
*
* Each device has further to expose a name and its type. This information can
* be used for automated searching and matching of devices (e.g. connect light
* sensor automatically with the color of an RGB LED...).
*
* The SAUL module enables further the automated initialization of preconfigured
* actuators/sensor via auto_init and the access to all available devices via
* one unified shell command.
*
* @todo So far, the interface only supports simple read and set
* operations. It probably needs to be extended to handling events,
* thresholds, and so on.
*
* @{
*
* @file
* @brief Definition of the generic [S]ensor [A]ctuator [U]ber [L]ayer
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef SAUL_H
#define SAUL_H
#include <stdint.h>
#include "phydat.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Definition of device classes
*
* This list contains a collections of available device classes. Each device
* must be part of one, but can be part of multiple of these classes. When
* belonging to more than one class, a device must however expose one driver
* for each class it belongs to, and it has to register each driver with a
* separate entry at the SAUL registry.
*
* Classes are identified by 8-bit unsigned integers.
*
* For searching and filtering purposes, the device classes are further split
* into two top-level classes: sensors and actuators. For identification, all
* actuator classes start with 0b01xxxxxx, all sensor classes start with
* 0b10xxxxxx.
*
* This list is not exhaustive, extend to your needs!
*/
enum {
SAUL_CLASS_UNDEF = 0x00, /**< device class undefined */
SAUL_ACT_ANY = 0x40, /**< any actuator - wildcard */
SAUL_ACT_LED_RGB = 0x42, /**< actuator: RGB LED */
SAUL_ACT_SERVO = 0x43, /**< actuator: servo motor */
SAUL_ACT_MOTOR = 0x44, /**< actuator: motor */
SAUL_ACT_SWITCH = 0x45, /**< actuator: simple on/off switch */
SAUL_ACT_DIMMER = 0x46, /**< actuator: dimmable switch */
SAUL_SENSE_ANY = 0x80, /**< any sensor - wildcart */
SAUL_SENSE_BTN = 0x81, /**< sensor: simple button */
SAUL_SENSE_TEMP = 0x82, /**< sensor: temperature */
SAUL_SENSE_HUM = 0x83, /**< sensor: humidity */
SAUL_SENSE_LIGHT = 0x84, /**< sensor: light */
SAUL_SENSE_ACCEL = 0x85, /**< sensor: accelerometer */
SAUL_SENSE_MAG = 0x86, /**< sensor: magnetometer */
SAUL_SENSE_GYRO = 0x87, /**< sensor: gyroscope */
SAUL_SENSE_COLOR = 0x88, /**< sensor: (light) color */
SAUL_SENSE_PRESS = 0x89, /**< sensor: pressure */
SAUL_SENSE_ANALOG = 0x8a, /**< sensor: raw analog value */
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
/* extend this list as needed... */
};
/**
* @brief Read a value (a set of values) from a device
*
* Simple sensors, as e.g. a temperature sensor, will return exactly one value
* together with the values scale and unit. Some sensors might return a touple
* or triple of data (e.g. a 3-axis accelerometer).
*
* Actuators can chose to either just return -ENOTSUP or to return their current
* set value (e.g. useful for reading back the current state of a switch)
*
* @param[in] dev device descriptor of the target device
* @param[out] res data read from the device
*
* @return number of values written into to result data structure [1-3]
* @return -ENOTSUP if the device does not support this operation
* @return -ECANCELED on other errors
*/
typedef int(*saul_read_t)(void *dev, phydat_t *res);
/**
* @brief Write a value (a set of values) to a device
*
* Most sensors will probably just return -ENOTSUP, as writing values to a
* sensor is often without purpose. The interface can however be used to
* configure sensors, e.g. to switch a sensor's unit type by writing the
* newly selected type to it.
*
* For actuators this function is used to influence the actuators state, e.g.
* switching a switch or setting the speed of a motor.
*
* @param[in] dev device descriptor of the target device
* @param[in] data data to write to the device
*
* @return number of values actually processed by the device [1-3]
* @return -ENOTSUP if the device does not support this operation
* @return -ECANCELED on other errors
*/
typedef int(*saul_write_t)(void *dev, phydat_t *data);
/**
* @brief Definition of the RIOT actuator/sensor interface
*/
typedef struct {
saul_read_t read; /**< read function pointer */
saul_write_t write; /**< write function pointer */
uint8_t type; /**< device class the device belongs to */
} saul_driver_t;
/**
* @brief Helper function converts a class ID to a string
*
* @param[in] class_id device class ID
*
* @return string representation of the device class
* @return NULL if class ID is not known
*/
const char *saul_class_to_str(uint8_t class_id);
#ifdef __cplusplus
}
#endif
#endif /* SAUL_H */
/** @} */

42
drivers/include/saul/periph.h

@ -0,0 +1,42 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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_saul
* @{
*
* @file
* @brief Parameter definitions for mapping peripherals directly to SAUL
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef SAUL_PERIPH_H
#define SAUL_PERIPH_H
#include "periph/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Direct mapped GPIO configuration values
*/
typedef struct {
const char *name; /**< name of the device connected to this pin */
gpio_t pin; /**< GPIO pin to initialize and expose */
gpio_dir_t dir; /**< use GPIO as input or output */
} saul_gpio_params_t;
#ifdef __cplusplus
}
#endif
#endif /* SAUL_PERIPH_H */
/** @} */

45
drivers/isl29020/isl29020_saul.c

@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 driver_isl29020
* @{
*
* @file
* @brief ISL29020 adaption to the RIOT actuator/sensor interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "isl29020.h"
static int read(void *dev, phydat_t *res)
{
isl29020_t *d = (isl29020_t *)dev;
res->val[0] = (int16_t)isl29020_read(d);
memset(&(res->val[1]), 0, 2 * sizeof(int16_t));
res->unit = UNIT_CD;
res->scale = 0;
return 1;
}
static int write(void *dev, phydat_t *state)
{
return -ENOTSUP;
}
const saul_driver_t isl29020_saul_driver = {
.read = read,
.write = write,
.type = SAUL_SENSE_LIGHT,
};

44
drivers/l3g4200d/l3g4200d_saul.c

@ -0,0 +1,44 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 driver_isl29020
* @{
*
* @file
* @brief L3G4200D adaption to the RIOT actuator/sensor interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "l3g4200d.h"
static int read(void *dev, phydat_t *res)
{
l3g4200d_t *d = (l3g4200d_t *)dev;
l3g4200d_read(d, (l3g4200d_data_t *)res);
res->unit = UNIT_DPS;
res->scale = 0;
return 3;
}
static int write(void *dev, phydat_t *state)
{
return -ENOTSUP;
}
const saul_driver_t l3g4200d_saul_driver = {
.read = read,
.write = write,
.type = SAUL_SENSE_GYRO,
};

45
drivers/lps331ap/lps331ap_saul.c

@ -0,0 +1,45 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 driver_lps331ap
* @{
*
* @file
* @brief LPS331ap adaption to the RIOT actuator/sensor interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "lps331ap.h"
static int read(void *dev, phydat_t *res)
{
lps331ap_t *d = (lps331ap_t *)dev;
res->val[0] = (int16_t)lps331ap_read_pres(d);
memset(&(res->val[1]), 0, 2 * sizeof(int16_t));
res->unit = UNIT_BAR;
res->scale = -3;
return 1;
}
static int write(void *dev, phydat_t *state)
{
return -ENOTSUP;
}
const saul_driver_t lps331ap_saul_driver = {
.read = read,
.write = write,
.type = SAUL_SENSE_PRESS,
};

59
drivers/lsm303dlhc/lsm303dlhc_saul.c

@ -0,0 +1,59 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 driver_lsm303dlhc
* @{
*
* @file
* @brief LSM303DLHC adaption to the RIOT actuator/sensor interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "lsm303dlhc.h"
static int read_acc(void *dev, phydat_t *res)
{
lsm303dlhc_t *d = (lsm303dlhc_t *)dev;
lsm303dlhc_read_acc(d, (lsm303dlhc_3d_data_t *)res);
res->unit = UNIT_G;
res->scale = 0;
return 3;
}
static int read_mag(void *dev, phydat_t *res)
{
lsm303dlhc_t *d = (lsm303dlhc_t *)dev;
lsm303dlhc_read_mag(d, (lsm303dlhc_3d_data_t *)res);
res->unit = UNIT_GS;
res->scale = 0;
return 3;
}
static int write(void *dev, phydat_t *state)
{
return -ENOTSUP;
}
const saul_driver_t lsm303dlhc_saul_acc_driver = {
.read = read_acc,
.write = write,
.type = SAUL_SENSE_ACCEL,
};
const saul_driver_t lsm303dlhc_saul_mag_driver = {
.read = read_mag,
.write = write,
.type = SAUL_SENSE_MAG,
};

7
drivers/saul/Makefile

@ -0,0 +1,7 @@
SRC = saul_str.c
ifneq (,$(filter saul_gpio,$(USEMODULE)))
SRC += gpio_saul.c
endif
include $(RIOTBASE)/Makefile.base

49
drivers/saul/gpio_saul.c

@ -0,0 +1,49 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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_saul
* @{
*
* @file
* @brief SAUL wrapper for direct access to GPIO pins
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "phydat.h"
#include "periph/gpio.h"
static int read(void *dev, phydat_t *res)
{
gpio_t pin = *((gpio_t *)dev);
res->val[0] = (gpio_read(pin)) ? 1 : 0;
memset(&(res->val[1]), 0, 2 * sizeof(int16_t));
res->unit = UNIT_BOOL;
res->scale = 0;
return 1;
}
static int write(void *dev, phydat_t *state)
{
gpio_t pin = *((gpio_t *)dev);
gpio_write(pin, state->val[0]);
return 1;
}
const saul_driver_t gpio_saul_driver = {
.read = read,
.write = write,
.type = SAUL_ACT_SWITCH,
};

52
drivers/saul/saul_str.c

@ -0,0 +1,52 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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_saul
* @{
*
* @file
* @brief SAUL string functions
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdint.h>
#include "saul.h"
/*
* This is surely not the most beautiful implementation of a stringification
* function, but works...
*/
const char *saul_class_to_str(uint8_t class_id)
{
switch (class_id) {
case SAUL_CLASS_UNDEF: return "CLASS_UNDEF";
case SAUL_ACT_ANY: return "ACT_ANY";
case SAUL_ACT_LED_RGB: return "ACT_LED_RGB";
case SAUL_ACT_SERVO: return "ACT_SERVO";
case SAUL_ACT_MOTOR: return "ACT_MOTOR";
case SAUL_ACT_SWITCH: return "ACT_SWITCH";
case SAUL_ACT_DIMMER: return "ACT_DIMMER";
case SAUL_SENSE_ANY: return "SENSE_ANY";
case SAUL_SENSE_BTN: return "SENSE_BTN";
case SAUL_SENSE_TEMP: return "SENSE_TEMP";
case SAUL_SENSE_HUM: return "SENSE_HUM";
case SAUL_SENSE_LIGHT: return "SENSE_LIGHT";
case SAUL_SENSE_ACCEL: return "SENSE_ACCEL";
case SAUL_SENSE_MAG: return "SENSE_MAG";
case SAUL_SENSE_GYRO: return "SENSE_GYRO";
case SAUL_SENSE_COLOR: return "SENSE_COLOR";
case SAUL_SENSE_PRESS: return "SENSE_PRESS";
case SAUL_CLASS_ANY: return "CLASS_ANY";
default: return "CLASS_UNKNOWN";
}
}

16
examples/default/Makefile

@ -28,11 +28,14 @@ CFLAGS += -DDEVELHELP
QUIET ?= 1
# Modules to include:
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += config
# include and auto-initialize all available sensors
USEMODULE += saul_reg
USEMODULE += saul_default
USEMODULE += auto_init_saul
BOARD_PROVIDES_NETIF := airfy-beacon fox iotlab-m3 mulle native nrf51dongle \
nrf6310 pba-d-01-kw2x pca10000 pca10005 saml21-xpro samr21-xpro spark-core \
@ -61,16 +64,5 @@ ifneq (,$(filter msba2,$(BOARD)))
USEMODULE += mci
USEMODULE += random
endif
ifneq (,$(filter iotlab-m3,$(BOARD)))
USEMODULE += isl29020
USEMODULE += lps331ap
USEMODULE += l3g4200d
USEMODULE += lsm303dlhc
endif
ifneq (,$(filter fox,$(BOARD)))
USEMODULE += lps331ap
USEMODULE += l3g4200d
USEMODULE += lsm303dlhc
endif
include $(RIOTBASE)/Makefile.include

4
sys/auto_init/Makefile

@ -4,4 +4,8 @@ ifneq (,$(filter auto_init_gnrc_netif,$(USEMODULE)))
DIRS += netif
endif
ifneq (,$(filter auto_init_saul,$(USEMODULE)))
DIRS += saul
endif
include $(RIOTBASE)/Makefile.base

27
sys/auto_init/auto_init.c

@ -183,4 +183,31 @@ void auto_init(void)
#ifdef MODULE_GNRC_IPV6_NETIF
gnrc_ipv6_netif_init_by_dev();
#endif
/* initialize sensors and actuators */
#ifdef MODULE_AUTO_INIT_SAUL
DEBUG("auto_init SAUL\n");
#ifdef MODULE_SAUL_GPIO
extern void auto_init_gpio(void);
auto_init_gpio();
#endif
#ifdef MODULE_LSM303DLHC
extern void auto_init_lsm303dlhc(void);
auto_init_lsm303dlhc();
#endif
#ifdef MODULE_LPS331AP
extern void auto_init_lps331ap(void);
auto_init_lps331ap();
#endif
#ifdef MODULE_ISL29020
extern void auto_init_isl29020(void);
auto_init_isl29020();
#endif
#ifdef MODULE_L3G4200D
extern void auto_init_l3g4200d(void);
auto_init_l3g4200d();
#endif
#endif /* MODULE_AUTO_INIT_SAUL */
}

3
sys/auto_init/saul/Makefile

@ -0,0 +1,3 @@
MODULE = auto_init_saul
include $(RIOTBASE)/Makefile.base

73
sys/auto_init/saul/auto_init_gpio.c

@ -0,0 +1,73 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 of GPIO pins directly mapped to SAUL reg
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#ifdef MODULE_SAUL_GPIO
#include "saul_reg.h"
#include "saul/periph.h"