From 8b5a501831c06c6bca74740565b3a9b6efb34c5f Mon Sep 17 00:00:00 2001 From: "Man, Jianting (Meco)" <920369182@qq.com> Date: Sun, 11 Dec 2022 22:45:04 -0500 Subject: [sensor][cmd] add sensor_get_type/vender/unit_name functions (#6727) * [sensor][cmd] add sensor_get_type/vender/unit_name functions * rename sensor folder --- components/drivers/include/drivers/sensor.h | 228 +++++++---- components/drivers/sensor/SConscript | 14 + components/drivers/sensor/sensor.c | 491 ++++++++++++++++++++++++ components/drivers/sensor/sensor_cmd.c | 563 ++++++++++++++++++++++++++++ components/drivers/sensors/SConscript | 14 - components/drivers/sensors/sensor.c | 491 ------------------------ components/drivers/sensors/sensor_cmd.c | 517 ------------------------- 7 files changed, 1220 insertions(+), 1098 deletions(-) create mode 100644 components/drivers/sensor/SConscript create mode 100644 components/drivers/sensor/sensor.c create mode 100644 components/drivers/sensor/sensor_cmd.c delete mode 100644 components/drivers/sensors/SConscript delete mode 100644 components/drivers/sensors/sensor.c delete mode 100755 components/drivers/sensors/sensor_cmd.c (limited to 'components') diff --git a/components/drivers/include/drivers/sensor.h b/components/drivers/include/drivers/sensor.h index a1de110a08..da1567bf2e 100644 --- a/components/drivers/include/drivers/sensor.h +++ b/components/drivers/include/drivers/sensor.h @@ -29,97 +29,172 @@ extern "C" { #define RT_SENSOR_MODULE_MAX (3) /* The maximum number of members of a sensor module */ +#define RT_SENSOR_MACRO_GET_NAME(macro) (macro##_STR) + /* Sensor types */ #define RT_SENSOR_CLASS_NONE (0) -#define RT_SENSOR_CLASS_ACCE (1) /* Accelerometer */ -#define RT_SENSOR_CLASS_GYRO (2) /* Gyroscope */ -#define RT_SENSOR_CLASS_MAG (3) /* Magnetometer */ -#define RT_SENSOR_CLASS_TEMP (4) /* Temperature */ -#define RT_SENSOR_CLASS_HUMI (5) /* Relative Humidity */ -#define RT_SENSOR_CLASS_BARO (6) /* Barometer */ -#define RT_SENSOR_CLASS_LIGHT (7) /* Ambient light */ -#define RT_SENSOR_CLASS_PROXIMITY (8) /* Proximity */ -#define RT_SENSOR_CLASS_HR (9) /* Heart Rate */ -#define RT_SENSOR_CLASS_TVOC (10) /* TVOC Level */ -#define RT_SENSOR_CLASS_NOISE (11) /* Noise Loudness */ -#define RT_SENSOR_CLASS_STEP (12) /* Step sensor */ -#define RT_SENSOR_CLASS_FORCE (13) /* Force sensor */ -#define RT_SENSOR_CLASS_DUST (14) /* Dust sensor */ -#define RT_SENSOR_CLASS_ECO2 (15) /* eCO2 sensor */ -#define RT_SENSOR_CLASS_GNSS (16) /* GPS/GNSS sensor */ -#define RT_SENSOR_CLASS_TOF (17) /* TOF sensor */ -#define RT_SENSOR_CLASS_SPO2 (18) /* SpO2 sensor */ -#define RT_SENSOR_CLASS_IAQ (19) /* IAQ sensor. */ -#define RT_SENSOR_CLASS_ETOH (20) /* EtOH sensor. */ -#define RT_SENSOR_CLASS_BP (21) /* Blood Pressure */ +#define RT_SENSOR_CLASS_NONE_STR "None" +#define RT_SENSOR_CLASS_ACCE (1) +#define RT_SENSOR_CLASS_ACCE_STR "Accelerometer" +#define RT_SENSOR_CLASS_GYRO (2) +#define RT_SENSOR_CLASS_GYRO_STR "Gyroscope" +#define RT_SENSOR_CLASS_MAG (3) +#define RT_SENSOR_CLASS_MAG_STR "Magnetometer" +#define RT_SENSOR_CLASS_TEMP (4) +#define RT_SENSOR_CLASS_TEMP_STR "Temperature" +#define RT_SENSOR_CLASS_HUMI (5) +#define RT_SENSOR_CLASS_HUMI_STR "Relative Humidity" +#define RT_SENSOR_CLASS_BARO (6) +#define RT_SENSOR_CLASS_BARO_STR "Barometer" +#define RT_SENSOR_CLASS_LIGHT (7) +#define RT_SENSOR_CLASS_LIGHT_STR "Ambient light" +#define RT_SENSOR_CLASS_PROXIMITY (8) +#define RT_SENSOR_CLASS_PROXIMITY_STR "Proximity" +#define RT_SENSOR_CLASS_HR (9) +#define RT_SENSOR_CLASS_HR_STR "Heart Rate" +#define RT_SENSOR_CLASS_TVOC (10) +#define RT_SENSOR_CLASS_TVOC_STR "TVOC Level" +#define RT_SENSOR_CLASS_NOISE (11) +#define RT_SENSOR_CLASS_NOISE_STR "Noise Loudness" +#define RT_SENSOR_CLASS_STEP (12) +#define RT_SENSOR_CLASS_STEP_STR "Step" +#define RT_SENSOR_CLASS_FORCE (13) +#define RT_SENSOR_CLASS_FORCE_STR "Force" +#define RT_SENSOR_CLASS_DUST (14) +#define RT_SENSOR_CLASS_DUST_STR "Dust" +#define RT_SENSOR_CLASS_ECO2 (15) +#define RT_SENSOR_CLASS_ECO2_STR "eCO2" +#define RT_SENSOR_CLASS_GNSS (16) +#define RT_SENSOR_CLASS_GNSS_STR "GNSS" +#define RT_SENSOR_CLASS_TOF (17) +#define RT_SENSOR_CLASS_TOF_STR "ToF" +#define RT_SENSOR_CLASS_SPO2 (18) +#define RT_SENSOR_CLASS_SPO2_STR "SpO2" +#define RT_SENSOR_CLASS_IAQ (19) +#define RT_SENSOR_CLASS_IAQ_STR "IAQ" +#define RT_SENSOR_CLASS_ETOH (20) +#define RT_SENSOR_CLASS_ETOH_STR "EtOH" +#define RT_SENSOR_CLASS_BP (21) +#define RT_SENSOR_CLASS_BP_STR "Blood Pressure" /* Sensor vendor types */ #define RT_SENSOR_VENDOR_UNKNOWN (0) -#define RT_SENSOR_VENDOR_STM (1) /* STMicroelectronics */ -#define RT_SENSOR_VENDOR_BOSCH (2) /* Bosch */ -#define RT_SENSOR_VENDOR_INVENSENSE (3) /* Invensense */ -#define RT_SENSOR_VENDOR_SEMTECH (4) /* Semtech */ -#define RT_SENSOR_VENDOR_GOERTEK (5) /* Goertek */ -#define RT_SENSOR_VENDOR_MIRAMEMS (6) /* MiraMEMS */ -#define RT_SENSOR_VENDOR_DALLAS (7) /* Dallas */ -#define RT_SENSOR_VENDOR_ASAIR (8) /* Aosong */ -#define RT_SENSOR_VENDOR_SHARP (9) /* Sharp */ -#define RT_SENSOR_VENDOR_SENSIRION (10) /* Sensirion */ -#define RT_SENSOR_VENDOR_TI (11) /* Texas Instruments */ -#define RT_SENSOR_VENDOR_PLANTOWER (12) /* Plantower */ -#define RT_SENSOR_VENDOR_AMS (13) /* ams AG */ -#define RT_SENSOR_VENDOR_MAXIM (14) /* Maxim Integrated */ -#define RT_SENSOR_VENDOR_MELEXIS (15) /* Melexis */ +#define RT_SENSOR_VENDOR_UNKNOWN_STR "Vendor Unknown" +#define RT_SENSOR_VENDOR_STM (1) +#define RT_SENSOR_VENDOR_STM_STR "STMicroelectronics" +#define RT_SENSOR_VENDOR_BOSCH (2) +#define RT_SENSOR_VENDOR_BOSCH_STR "Bosch" +#define RT_SENSOR_VENDOR_INVENSENSE (3) +#define RT_SENSOR_VENDOR_INVENSENSE_STR "Invensense" +#define RT_SENSOR_VENDOR_SEMTECH (4) +#define RT_SENSOR_VENDOR_SEMTECH_STR "Semtech" +#define RT_SENSOR_VENDOR_GOERTEK (5) +#define RT_SENSOR_VENDOR_GOERTEK_STR "Goertek" +#define RT_SENSOR_VENDOR_MIRAMEMS (6) +#define RT_SENSOR_VENDOR_MIRAMEMS_STR "MiraMEMS" +#define RT_SENSOR_VENDOR_DALLAS (7) +#define RT_SENSOR_VENDOR_DALLAS_STR "Dallas" +#define RT_SENSOR_VENDOR_ASAIR (8) +#define RT_SENSOR_VENDOR_ASAIR_STR "Aosong" +#define RT_SENSOR_VENDOR_SHARP (9) +#define RT_SENSOR_VENDOR_SHARP_STR "Sharp" +#define RT_SENSOR_VENDOR_SENSIRION (10) +#define RT_SENSOR_VENDOR_SENSIRION_STR "Sensirion" +#define RT_SENSOR_VENDOR_TI (11) +#define RT_SENSOR_VENDOR_TI_STR "Texas Instruments" +#define RT_SENSOR_VENDOR_PLANTOWER (12) +#define RT_SENSOR_VENDOR_PLANTOWER_STR "Plantower" +#define RT_SENSOR_VENDOR_AMS (13) +#define RT_SENSOR_VENDOR_AMS_STR "ams-OSRAM AG" +#define RT_SENSOR_VENDOR_MAXIM (14) +#define RT_SENSOR_VENDOR_MAXIM_STR "Maxim Integrated" +#define RT_SENSOR_VENDOR_MELEXIS (15) +#define RT_SENSOR_VENDOR_MELEXIS_STR "Melexis" /* Sensor unit types */ -#define RT_SENSOR_UNIT_NONE (0) -#define RT_SENSOR_UNIT_MG (1) /* Accelerometer unit: mG */ -#define RT_SENSOR_UNIT_MDPS (2) /* Gyroscope unit: mdps */ -#define RT_SENSOR_UNIT_MGAUSS (3) /* Magnetometer unit: mGauss */ -#define RT_SENSOR_UNIT_LUX (4) /* Ambient light unit: lux */ -#define RT_SENSOR_UNIT_CM (5) /* Distance unit: cm */ -#define RT_SENSOR_UNIT_PA (6) /* Barometer unit: pa */ -#define RT_SENSOR_UNIT_PERMILLAGE (7) /* Relative Humidity unit: permillage */ -#define RT_SENSOR_UNIT_DCELSIUS (8) /* Temperature unit: dCelsius */ -#define RT_SENSOR_UNIT_HZ (9) /* Frequency unit: HZ */ -#define RT_SENSOR_UNIT_ONE (10) /* Dimensionless quantity unit: 1 */ -#define RT_SENSOR_UNIT_BPM (11) /* Heart rate unit: bpm */ -#define RT_SENSOR_UNIT_MM (12) /* Distance unit: mm */ -#define RT_SENSOR_UNIT_MN (13) /* Force unit: mN */ -#define RT_SENSOR_UNIT_PPM (14) /* Concentration unit: ppm */ -#define RT_SENSOR_UNIT_PPB (15) /* Concentration unit: ppb */ -#define RT_SENSOR_UNIT_DMS (16) /* Coordinates unit: DMS */ -#define RT_SENSOR_UNIT_DD (17) /* Coordinates unit: DD */ -#define RT_SENSOR_UNIT_MGM3 (18) /* Concentration unit: mg/m3 */ -#define RT_SENSOR_UNIT_MMHG (19) /* Blood Pressure unit: mmHg */ +#define RT_SENSOR_UNIT_NONE (0) /* Dimensionless quantity */ +#define RT_SENSOR_UNIT_NONE_STR "" +#define RT_SENSOR_UNIT_MG (1) /* Accelerometer unit: mG */ +#define RT_SENSOR_UNIT_MG_STR "mG" +#define RT_SENSOR_UNIT_MDPS (2) /* Gyroscope unit: mdps */ +#define RT_SENSOR_UNIT_MDPS_STR "mdps" +#define RT_SENSOR_UNIT_MGAUSS (3) /* Magnetometer unit: mGauss */ +#define RT_SENSOR_UNIT_MGAUSS_STR "mGauss" +#define RT_SENSOR_UNIT_LUX (4) /* Ambient light unit: lux */ +#define RT_SENSOR_UNIT_LUX_STR "lux" +#define RT_SENSOR_UNIT_CM (5) /* Distance unit: cm */ +#define RT_SENSOR_UNIT_CM_STR "cm" +#define RT_SENSOR_UNIT_MM (6) /* Distance unit: mm */ +#define RT_SENSOR_UNIT_MM_STR "mm" +#define RT_SENSOR_UNIT_PA (7) /* Barometer unit: Pa */ +#define RT_SENSOR_UNIT_PA_STR "Pa" +#define RT_SENSOR_UNIT_MMHG (8) /* Blood Pressure unit: mmHg */ +#define RT_SENSOR_UNIT_MMHG_STR "mmHg" +#define RT_SENSOR_UNIT_PERMILLAGE (9) /* Relative Humidity unit: permillage */ +#define RT_SENSOR_UNIT_PERMILLAGE_STR "‰" +#define RT_SENSOR_UNIT_PERCENTAGE (10) /* Relative Humidity unit: percentage */ +#define RT_SENSOR_UNIT_PERCENTAGE_STR "%" +#define RT_SENSOR_UNIT_CELSIUS (11) /* Temperature unit: Celsius ℃ */ +#define RT_SENSOR_UNIT_CELSIUS_STR "℃" +#define RT_SENSOR_UNIT_FAHRENHEIT (12) /* Temperature unit: Fahrenheit ℉ */ +#define RT_SENSOR_UNIT_FAHRENHEIT_STR "℉" +#define RT_SENSOR_UNIT_KELVIN (13) /* Temperature unit: K */ +#define RT_SENSOR_UNIT_KELVIN_STR "K" +#define RT_SENSOR_UNIT_HZ (14) /* Frequency unit: Hz */ +#define RT_SENSOR_UNIT_HZ_STR "Hz" +#define RT_SENSOR_UNIT_BPM (15) /* Heart rate unit: bpm */ +#define RT_SENSOR_UNIT_BPM_STR "bpm" +#define RT_SENSOR_UNIT_MN (16) /* Force unit: mN */ +#define RT_SENSOR_UNIT_MN_STR "mN" +#define RT_SENSOR_UNIT_N (17) /* Force unit: N */ +#define RT_SENSOR_UNIT_N_STR "N" +#define RT_SENSOR_UNIT_PPM (18) /* Concentration unit: ppm */ +#define RT_SENSOR_UNIT_PPM_STR "ppm" +#define RT_SENSOR_UNIT_PPB (19) /* Concentration unit: ppb */ +#define RT_SENSOR_UNIT_PPB_STR "ppb" +#define RT_SENSOR_UNIT_DMS (20) /* Coordinates unit: DMS */ +#define RT_SENSOR_UNIT_DMS_STR "DMS" +#define RT_SENSOR_UNIT_DD (21) /* Coordinates unit: DD */ +#define RT_SENSOR_UNIT_DD_STR "DD" +#define RT_SENSOR_UNIT_MGM3 (22) /* Concentration unit: mg/m3 */ +#define RT_SENSOR_UNIT_MGM3_STR "mg/m3" /* Sensor communication interface types */ -#define RT_SENSOR_INTF_I2C (1 << 0) -#define RT_SENSOR_INTF_SPI (1 << 1) -#define RT_SENSOR_INTF_UART (1 << 2) -#define RT_SENSOR_INTF_ONEWIRE (1 << 3) +#define RT_SENSOR_INTF_I2C (1 << 0) +#define RT_SENSOR_INTF_I2C_STR "I2C" +#define RT_SENSOR_INTF_SPI (1 << 1) +#define RT_SENSOR_INTF_SPI_STR "SPI" +#define RT_SENSOR_INTF_UART (1 << 2) +#define RT_SENSOR_INTF_UART_STR "UART" +#define RT_SENSOR_INTF_ONEWIRE (1 << 3) +#define RT_SENSOR_INTF_ONEWIRE_STR "1-Wire" /* Sensor power mode types */ -#define RT_SENSOR_POWER_NONE (0) -#define RT_SENSOR_POWER_DOWN (1) /* power down mode */ -#define RT_SENSOR_POWER_NORMAL (2) /* normal-power mode */ -#define RT_SENSOR_POWER_LOW (3) /* low-power mode */ -#define RT_SENSOR_POWER_HIGH (4) /* high-power mode */ +#define RT_SENSOR_POWER_NONE (0) +#define RT_SENSOR_POWER_NONE_STR "None" +#define RT_SENSOR_POWER_DOWN (1) /* power down mode */ +#define RT_SENSOR_POWER_DOWN_STR "Down" +#define RT_SENSOR_POWER_NORMAL (2) /* normal-power mode */ +#define RT_SENSOR_POWER_NORMAL_STR "Normal" +#define RT_SENSOR_POWER_LOW (3) /* low-power mode */ +#define RT_SENSOR_POWER_LOW_STR "Low" +#define RT_SENSOR_POWER_HIGH (4) /* high-power mode */ +#define RT_SENSOR_POWER_HIGH_STR "High" /* Sensor work mode types */ -#define RT_SENSOR_MODE_NONE (0) -#define RT_SENSOR_MODE_POLLING (1) /* One shot only read a data */ -#define RT_SENSOR_MODE_INT (2) /* TODO: One shot interrupt only read a data */ -#define RT_SENSOR_MODE_FIFO (3) /* TODO: One shot interrupt read all fifo data */ +#define RT_SENSOR_MODE_NONE (0) +#define RT_SENSOR_MODE_POLLING (1) /* One shot only read a data */ +#define RT_SENSOR_MODE_INT (2) /* TODO: One shot interrupt only read a data */ +#define RT_SENSOR_MODE_FIFO (3) /* TODO: One shot interrupt read all fifo data */ /* Sensor control cmd types */ -#define RT_SENSOR_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Sensor) + 0) /* Get device id */ -#define RT_SENSOR_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Get sensor info */ -#define RT_SENSOR_CTRL_SET_RANGE (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* Set the measure range of sensor. unit is info of sensor */ -#define RT_SENSOR_CTRL_SET_ODR (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* Set output date rate. unit is HZ */ -#define RT_SENSOR_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* Set sensor's work mode. ex. RT_SENSOR_MODE_POLLING,RT_SENSOR_MODE_INT */ -#define RT_SENSOR_CTRL_SET_POWER (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* Set power mode. args type of sensor power mode. ex. RT_SENSOR_POWER_DOWN,RT_SENSOR_POWER_NORMAL */ -#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 6) /* Take a self test */ +#define RT_SENSOR_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Sensor) + 0) /* Get device id */ +#define RT_SENSOR_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Get sensor info */ +#define RT_SENSOR_CTRL_SET_RANGE (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* Set the measure range of sensor. unit is info of sensor */ +#define RT_SENSOR_CTRL_SET_ODR (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* Set output date rate. unit is HZ */ +#define RT_SENSOR_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* Set sensor's work mode. ex. RT_SENSOR_MODE_POLLING,RT_SENSOR_MODE_INT */ +#define RT_SENSOR_CTRL_SET_POWER (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* Set power mode. args type of sensor power mode. ex. RT_SENSOR_POWER_DOWN,RT_SENSOR_POWER_NORMAL */ +#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 6) /* Take a self test */ #define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */ @@ -162,6 +237,7 @@ struct rt_sensor_config typedef struct rt_sensor_device *rt_sensor_t; typedef struct rt_sensor_data *rt_sensor_data_t; +typedef struct rt_sensor_info *rt_sensor_info_t; struct rt_sensor_device { diff --git a/components/drivers/sensor/SConscript b/components/drivers/sensor/SConscript new file mode 100644 index 0000000000..afafc6d2ce --- /dev/null +++ b/components/drivers/sensor/SConscript @@ -0,0 +1,14 @@ +# SConscript for sensor framework + +from building import * + +cwd = GetCurrentDir() +src = ['sensor.c'] +CPPPATH = [cwd, cwd + '/../include'] + +if GetDepend('RT_USING_SENSOR_CMD'): + src += ['sensor_cmd.c'] + +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/sensor/sensor.c b/components/drivers/sensor/sensor.c new file mode 100644 index 0000000000..3a5a0421df --- /dev/null +++ b/components/drivers/sensor/sensor.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-31 flybreak first version + * 2020-02-22 luhuadong support custom commands + */ + +#include + +#define DBG_TAG "sensor" +#define DBG_LVL DBG_INFO +#include + +#include + +static char *const sensor_name_str[] = +{ + "None", + "ac-", /* Accelerometer */ + "gy-", /* Gyroscope */ + "ma-", /* Magnetometer */ + "tm-", /* Temperature */ + "hm-", /* Relative Humidity */ + "br-", /* Barometer */ + "li-", /* Ambient light */ + "pr-", /* Proximity */ + "hr-", /* Heart Rate */ + "tv-", /* TVOC Level */ + "ni-", /* Noise Loudness */ + "st-", /* Step sensor */ + "fr-", /* Force sensor */ + "du-", /* Dust sensor */ + "ec-", /* eCO2 sensor */ + "gn-", /* GPS/GNSS sensor */ + "tf-", /* TOF sensor */ + "sp-", /* SpO2 sensor */ + "ia-", /* IAQ sensor */ + "et-", /* EtOH sensor */ + "bp-" /* Blood Pressure */ +}; + +/* sensor interrupt handler function */ +static void _sensor_cb(rt_sensor_t sen) +{ + if (sen->parent.rx_indicate == RT_NULL) + { + return; + } + + if (sen->irq_handle != RT_NULL) + { + sen->irq_handle(sen); + } + + /* The buffer is not empty. Read the data in the buffer first */ + if (sen->data_len > 0) + { + sen->parent.rx_indicate(&sen->parent, sen->data_len / sizeof(struct rt_sensor_data)); + } + else if (sen->config.mode == RT_SENSOR_MODE_INT) + { + /* The interrupt mode only produces one data at a time */ + sen->parent.rx_indicate(&sen->parent, 1); + } + else if (sen->config.mode == RT_SENSOR_MODE_FIFO) + { + sen->parent.rx_indicate(&sen->parent, sen->info.fifo_max); + } +} + +/* ISR for sensor interrupt */ +static void _irq_callback(void *args) +{ + rt_sensor_t sensor = (rt_sensor_t)args; + rt_uint8_t i; + + if (sensor->module) + { + /* Invoke a callback for all sensors in the module */ + for (i = 0; i < sensor->module->sen_num; i++) + { + _sensor_cb(sensor->module->sen[i]); + } + } + else + { + _sensor_cb(sensor); + } +} + +/* Sensor interrupt initialization function */ +static rt_err_t _sensor_irq_init(rt_sensor_t sensor) +{ + if (sensor->config.irq_pin.pin == RT_PIN_NONE) + { + return -RT_EINVAL; + } + + rt_pin_mode(sensor->config.irq_pin.pin, sensor->config.irq_pin.mode); + + if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN) + { + rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING, _irq_callback, (void *)sensor); + } + else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP) + { + rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, _irq_callback, (void *)sensor); + } + else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT) + { + rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, _irq_callback, (void *)sensor); + } + + rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_TRUE); + + LOG_I("interrupt init success"); + + return 0; +} + +/* sensor local ops */ +static rt_ssize_t _local_fetch_data(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len) +{ + LOG_D("Undefined fetch_data"); + return -RT_EINVAL; +} +static rt_err_t _local_control(rt_sensor_t sensor, int cmd, void *arg) +{ + LOG_D("Undefined control"); + return -RT_EINVAL; +} +static struct rt_sensor_ops local_ops = +{ + .fetch_data = _local_fetch_data, + .control = _local_control +}; + +/* RT-Thread Device Interface */ +static rt_err_t _sensor_open(rt_device_t dev, rt_uint16_t oflag) +{ + rt_sensor_t sensor = (rt_sensor_t)dev; + RT_ASSERT(dev != RT_NULL); + rt_err_t res = RT_EOK; + rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; + + if (sensor->module) + { + /* take the module mutex */ + rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); + } + + if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf == RT_NULL) + { + /* Allocate memory for the sensor buffer */ + sensor->data_buf = rt_malloc(sizeof(struct rt_sensor_data) * sensor->info.fifo_max); + if (sensor->data_buf == RT_NULL) + { + res = -RT_ENOMEM; + goto __exit; + } + } + if (sensor->ops->control != RT_NULL) + { + local_ctrl = sensor->ops->control; + } + + sensor->config.mode = RT_SENSOR_MODE_POLLING; + if (oflag & RT_DEVICE_FLAG_RDONLY && dev->flag & RT_DEVICE_FLAG_RDONLY) + { + /* If polling mode is supported, configure it to polling mode */ + local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_POLLING); + } + else if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* If interrupt mode is supported, configure it to interrupt mode */ + if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_INT) == RT_EOK) + { + /* Initialization sensor interrupt */ + _sensor_irq_init(sensor); + sensor->config.mode = RT_SENSOR_MODE_INT; + } + } + else if (oflag & RT_DEVICE_FLAG_FIFO_RX && dev->flag & RT_DEVICE_FLAG_FIFO_RX) + { + /* If fifo mode is supported, configure it to fifo mode */ + if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_FIFO) == RT_EOK) + { + /* Initialization sensor interrupt */ + _sensor_irq_init(sensor); + sensor->config.mode = RT_SENSOR_MODE_FIFO; + } + } + else + { + res = -RT_EINVAL; + goto __exit; + } + + /* Configure power mode to normal mode */ + if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_NORMAL) == RT_EOK) + { + sensor->config.power = RT_SENSOR_POWER_NORMAL; + } + +__exit: + if (sensor->module) + { + /* release the module mutex */ + rt_mutex_release(sensor->module->lock); + } + + return res; +} + +static rt_err_t _sensor_close(rt_device_t dev) +{ + rt_sensor_t sensor = (rt_sensor_t)dev; + int i; + rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; + + RT_ASSERT(dev != RT_NULL); + + if (sensor->module) + { + rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); + } + if (sensor->ops->control != RT_NULL) + { + local_ctrl = sensor->ops->control; + } + + /* Configure power mode to power down mode */ + if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_DOWN) == RT_EOK) + { + sensor->config.power = RT_SENSOR_POWER_DOWN; + } + + if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL) + { + for (i = 0; i < sensor->module->sen_num; i ++) + { + if (sensor->module->sen[i]->parent.ref_count > 0) + goto __exit; + } + + /* Free memory for the sensor buffer */ + for (i = 0; i < sensor->module->sen_num; i ++) + { + if (sensor->module->sen[i]->data_buf) + { + rt_free(sensor->module->sen[i]->data_buf); + sensor->module->sen[i]->data_buf = RT_NULL; + } + } + } + if (sensor->config.mode != RT_SENSOR_MODE_POLLING) + { + /* Sensor disable interrupt */ + if (sensor->config.irq_pin.pin != RT_PIN_NONE) + { + rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE); + } + } + +__exit: + if (sensor->module) + { + rt_mutex_release(sensor->module->lock); + } + + return RT_EOK; +} + +static rt_size_t _sensor_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len) +{ + rt_sensor_t sensor = (rt_sensor_t)dev; + rt_size_t result = 0; + RT_ASSERT(dev != RT_NULL); + + if (buf == NULL || len == 0) + { + return 0; + } + + if (sensor->module) + { + rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); + } + + /* The buffer is not empty. Read the data in the buffer first */ + if (sensor->data_len > 0) + { + if (len > sensor->data_len / sizeof(struct rt_sensor_data)) + { + len = sensor->data_len / sizeof(struct rt_sensor_data); + } + + rt_memcpy(buf, sensor->data_buf, len * sizeof(struct rt_sensor_data)); + + /* Clear the buffer */ + sensor->data_len = 0; + result = len; + } + else + { + /* If the buffer is empty, read the data */ + if (sensor->ops->fetch_data) + { + result = sensor->ops->fetch_data(sensor, buf, len); + } + } + + if (sensor->module) + { + rt_mutex_release(sensor->module->lock); + } + + return result; +} + +static rt_err_t _sensor_control(rt_device_t dev, int cmd, void *args) +{ + rt_sensor_t sensor = (rt_sensor_t)dev; + rt_err_t result = RT_EOK; + RT_ASSERT(dev != RT_NULL); + rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; + + if (sensor->module) + { + rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); + } + if (sensor->ops->control != RT_NULL) + { + local_ctrl = sensor->ops->control; + } + + switch (cmd) + { + case RT_SENSOR_CTRL_GET_ID: + if (args) + { + result = local_ctrl(sensor, RT_SENSOR_CTRL_GET_ID, args); + } + break; + case RT_SENSOR_CTRL_GET_INFO: + if (args) + { + rt_memcpy(args, &sensor->info, sizeof(struct rt_sensor_info)); + } + break; + case RT_SENSOR_CTRL_SET_RANGE: + /* Configuration measurement range */ + result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_RANGE, args); + if (result == RT_EOK) + { + sensor->config.range = (rt_int32_t)args; + LOG_D("set range %d", sensor->config.range); + } + break; + case RT_SENSOR_CTRL_SET_ODR: + /* Configuration data output rate */ + result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_ODR, args); + if (result == RT_EOK) + { + sensor->config.odr = (rt_uint32_t)args & 0xFFFF; + LOG_D("set odr %d", sensor->config.odr); + } + break; + case RT_SENSOR_CTRL_SET_POWER: + /* Configuration sensor power mode */ + result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, args); + if (result == RT_EOK) + { + sensor->config.power = (rt_uint32_t)args & 0xFF; + LOG_D("set power mode code:", sensor->config.power); + } + break; + case RT_SENSOR_CTRL_SELF_TEST: + /* Device self-test */ + result = local_ctrl(sensor, RT_SENSOR_CTRL_SELF_TEST, args); + break; + default: + + if (cmd > RT_SENSOR_CTRL_USER_CMD_START) + { + /* Custom commands */ + result = local_ctrl(sensor, cmd, args); + } + else + { + result = -RT_ERROR; + } + break; + } + + if (sensor->module) + { + rt_mutex_release(sensor->module->lock); + } + + return result; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rt_sensor_ops = +{ + RT_NULL, + _sensor_open, + _sensor_close, + _sensor_read, + RT_NULL, + _sensor_control +}; +#endif + + +/* + * sensor register + */ +int rt_hw_sensor_register(rt_sensor_t sensor, + const char *name, + rt_uint32_t flag, + void *data) +{ + rt_int8_t result; + rt_device_t device; + RT_ASSERT(sensor != RT_NULL); + + char *sensor_name = RT_NULL, *device_name = RT_NULL; + + if (sensor->ops == RT_NULL) + { + sensor->ops = &local_ops; + } + + /* Add a type name for the sensor device */ + sensor_name = sensor_name_str[sensor->info.type]; + device_name = (char *)rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name)); + if (device_name == RT_NULL) + { + LOG_E("device_name calloc failed!"); + return -RT_ERROR; + } + + rt_memcpy(device_name, sensor_name, rt_strlen(sensor_name) + 1); + strcat(device_name, name); + + if (sensor->module != RT_NULL && sensor->module->lock == RT_NULL) + { + /* Create a mutex lock for the module */ + sensor->module->lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO); + if (sensor->module->lock == RT_NULL) + { + rt_free(device_name); + return -RT_ERROR; + } + } + + device = &sensor->parent; + +#ifdef RT_USING_DEVICE_OPS + device->ops = &rt_sensor_ops; +#else + device->init = RT_NULL; + device->open = _sensor_open; + device->close = _sensor_close; + device->read = _sensor_read; + device->write = RT_NULL; + device->control = _sensor_control; +#endif + device->type = RT_Device_Class_Sensor; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + device->user_data = data; + + result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE); + if (result != RT_EOK) + { + LOG_E("sensor[%s] register err code: %d", device_name, result); + rt_free(device_name); + return result; + } + + LOG_I("sensor[%s] init success", device_name); + rt_free(device_name); + return RT_EOK; +} diff --git a/components/drivers/sensor/sensor_cmd.c b/components/drivers/sensor/sensor_cmd.c new file mode 100644 index 0000000000..7c45c3dac1 --- /dev/null +++ b/components/drivers/sensor/sensor_cmd.c @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-31 flybreak first version + * 2019-07-16 WillianChan Increase the output of sensor information + * 2020-02-22 luhuadong Add vendor info and sensor types for cmd + */ + +#include + +#define DBG_TAG "sensor.cmd" +#define DBG_LVL DBG_INFO +#include + +#include +#include + +static rt_sem_t sensor_rx_sem = RT_NULL; + +static const char *sensor_get_type_name(rt_sensor_info_t info) +{ + switch(info->type) + { + case RT_SENSOR_CLASS_ACCE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_ACCE); + case RT_SENSOR_CLASS_GYRO: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_GYRO); + case RT_SENSOR_CLASS_MAG: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_MAG); + case RT_SENSOR_CLASS_TEMP: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_TEMP); + case RT_SENSOR_CLASS_HUMI: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_HUMI); + case RT_SENSOR_CLASS_BARO: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_BARO); + case RT_SENSOR_CLASS_LIGHT: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_LIGHT); + case RT_SENSOR_CLASS_PROXIMITY: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_PROXIMITY); + case RT_SENSOR_CLASS_HR: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_HR); + case RT_SENSOR_CLASS_TVOC: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_TVOC); + case RT_SENSOR_CLASS_NOISE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_NOISE); + case RT_SENSOR_CLASS_STEP: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_STEP); + case RT_SENSOR_CLASS_FORCE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_FORCE); + case RT_SENSOR_CLASS_DUST: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_DUST); + case RT_SENSOR_CLASS_ECO2: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_ECO2); + case RT_SENSOR_CLASS_GNSS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_GNSS); + case RT_SENSOR_CLASS_TOF: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_TOF); + case RT_SENSOR_CLASS_SPO2: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_SPO2); + case RT_SENSOR_CLASS_IAQ: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_IAQ); + case RT_SENSOR_CLASS_ETOH: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_ETOH); + case RT_SENSOR_CLASS_BP: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_BP); + case RT_SENSOR_CLASS_NONE: + default: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_CLASS_NONE); + } +} + +static const char *sensor_get_vendor_name(rt_sensor_info_t info) +{ + switch(info->vendor) + { + case RT_SENSOR_VENDOR_STM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_STM); + case RT_SENSOR_VENDOR_BOSCH: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_BOSCH); + case RT_SENSOR_VENDOR_INVENSENSE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_INVENSENSE); + case RT_SENSOR_VENDOR_SEMTECH: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_SEMTECH); + case RT_SENSOR_VENDOR_GOERTEK: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_GOERTEK); + case RT_SENSOR_VENDOR_MIRAMEMS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_MIRAMEMS); + case RT_SENSOR_VENDOR_DALLAS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_DALLAS); + case RT_SENSOR_VENDOR_ASAIR: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_ASAIR); + case RT_SENSOR_VENDOR_SHARP: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_SHARP); + case RT_SENSOR_VENDOR_SENSIRION: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_SENSIRION); + case RT_SENSOR_VENDOR_TI: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_TI); + case RT_SENSOR_VENDOR_PLANTOWER: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_PLANTOWER); + case RT_SENSOR_VENDOR_AMS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_AMS); + case RT_SENSOR_VENDOR_MAXIM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_MAXIM); + case RT_SENSOR_VENDOR_MELEXIS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_MELEXIS); + case RT_SENSOR_VENDOR_UNKNOWN: + default: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_VENDOR_UNKNOWN); + } +} + +static const char *sensor_get_unit_name(rt_sensor_info_t info) +{ + switch(info->unit) + { + case RT_SENSOR_UNIT_MG: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MG); + case RT_SENSOR_UNIT_MDPS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MDPS); + case RT_SENSOR_UNIT_MGAUSS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MGAUSS); + case RT_SENSOR_UNIT_LUX: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_LUX); + case RT_SENSOR_UNIT_CM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_CM); + case RT_SENSOR_UNIT_MM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MM); + case RT_SENSOR_UNIT_PA: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_PA); + case RT_SENSOR_UNIT_MMHG: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MMHG); + case RT_SENSOR_UNIT_PERMILLAGE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_PERMILLAGE); + case RT_SENSOR_UNIT_PERCENTAGE: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_PERCENTAGE); + case RT_SENSOR_UNIT_CELSIUS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_CELSIUS); + case RT_SENSOR_UNIT_FAHRENHEIT: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_FAHRENHEIT); + case RT_SENSOR_UNIT_KELVIN: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_KELVIN); + case RT_SENSOR_UNIT_HZ: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_HZ); + case RT_SENSOR_UNIT_BPM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_BPM); + case RT_SENSOR_UNIT_MN: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MN); + case RT_SENSOR_UNIT_N: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_N); + case RT_SENSOR_UNIT_PPM: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_PPM); + case RT_SENSOR_UNIT_PPB: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_PPB); + case RT_SENSOR_UNIT_DMS: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_DMS); + case RT_SENSOR_UNIT_DD: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_DD); + case RT_SENSOR_UNIT_MGM3: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_MGM3); + case RT_SENSOR_UNIT_NONE: + default: + return RT_SENSOR_MACRO_GET_NAME(RT_SENSOR_UNIT_NONE); + } +} + +static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor_data *sensor_data) +{ + const char *unit_name = sensor_get_unit_name(&sensor->info); + switch (sensor->info.type) + { + case RT_SENSOR_CLASS_ACCE: + LOG_I("num:%d, x:%f, y:%f, z:%f %s, timestamp:%u", num, sensor_data->data.acce.x, sensor_data->data.acce.y, sensor_data->data.acce.z, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_GYRO: + LOG_I("num:%d, x:%f, y:%f, z:%f %s, timestamp:%u", num, sensor_data->data.gyro.x, sensor_data->data.gyro.y, sensor_data->data.gyro.z, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_MAG: + LOG_I("num:%d, x:%f, y:%f, z:%f %s, timestamp:%u", num, sensor_data->data.mag.x, sensor_data->data.mag.y, sensor_data->data.mag.z, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_GNSS: + LOG_I("num:%d, lon:%f, lat:%f %s, timestamp:%u", num, sensor_data->data.coord.longitude, sensor_data->data.coord.latitude, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_TEMP: + LOG_I("num:%d, temp:%f%s, timestamp:%u", num, sensor_data->data.temp, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_HUMI: + LOG_I("num:%d, humi:%f%s, timestamp:%u", num, sensor_data->data.humi, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_BARO: + LOG_I("num:%d, press:%f%s, timestamp:%u", num, sensor_data->data.baro, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_LIGHT: + LOG_I("num:%d, light:%f%s, timestamp:%u", num, sensor_data->data.light, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_PROXIMITY: + case RT_SENSOR_CLASS_TOF: + LOG_I("num:%d, distance:%f%s, timestamp:%u", num, sensor_data->data.proximity, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_HR: + LOG_I("num:%d, heart rate:%f%s, timestamp:%u", num, sensor_data->data.hr, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_TVOC: + LOG_I("num:%d, tvoc:%f%s, timestamp:%u", num, sensor_data->data.tvoc, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_NOISE: + LOG_I("num:%d, noise:%f%s, timestamp:%u", num, sensor_data->data.noise, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_STEP: + LOG_I("num:%d, step:%f%s, timestamp:%u", num, sensor_data->data.step, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_FORCE: + LOG_I("num:%d, force:%f%s, timestamp:%u", num, sensor_data->data.force, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_DUST: + LOG_I("num:%d, dust:%f%s, timestamp:%u", num, sensor_data->data.dust, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_ECO2: + LOG_I("num:%d, eco2:%f%s, timestamp:%u", num, sensor_data->data.eco2, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_IAQ: + LOG_I("num:%d, IAQ:%f%s, timestamp:%u", num, sensor_data->data.iaq, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_ETOH: + LOG_I("num:%d, EtOH:%f%s, timestamp:%u", num, sensor_data->data.etoh, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_BP: + LOG_I("num:%d, bp.sbp:%f, bp.dbp:%f %s, timestamp:%u", num, sensor_data->data.bp.sbp, sensor_data->data.bp.dbp, unit_name, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_NONE: + default: + LOG_E("Unknown type of sensor!"); + break; + } +} + +static rt_err_t rx_callback(rt_device_t dev, rt_size_t size) +{ + rt_sem_release(sensor_rx_sem); + return 0; +} + +static void sensor_fifo_rx_entry(void *parameter) +{ + rt_device_t dev = (rt_device_t)parameter; + rt_sensor_t sensor = (rt_sensor_t)parameter; + struct rt_sensor_data *data = RT_NULL; + struct rt_sensor_info info; + rt_size_t res, i; + + rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info); + + data = (struct rt_sensor_data *)rt_malloc(sizeof(struct rt_sensor_data) * info.fifo_max); + if (data == RT_NULL) + { + LOG_E("Memory allocation failed!"); + } + + while (1) + { + rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER); + + res = rt_device_read(dev, 0, data, info.fifo_max); + for (i = 0; i < res; i++) + { + sensor_show_data(i, sensor, &data[i]); + } + } +} + +static void sensor_fifo(int argc, char **argv) +{ + static rt_thread_t tid1 = RT_NULL; + rt_device_t dev = RT_NULL; + rt_sensor_t sensor; + + dev = rt_device_find(argv[1]); + if (dev == RT_NULL) + { + LOG_E("Can't find device:%s", argv[1]); + return; + } + sensor = (rt_sensor_t)dev; + + if (rt_device_open(dev, RT_DEVICE_FLAG_FIFO_RX) != RT_EOK) + { + LOG_E("open device failed!"); + return; + } + + if (sensor_rx_sem == RT_NULL) + { + sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO); + } + else + { + LOG_E("The thread is running, please reboot and try again"); + return; + } + + tid1 = rt_thread_create("sen_rx_thread", + sensor_fifo_rx_entry, sensor, + 1024, + 15, 5); + + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + rt_device_set_rx_indicate(dev, rx_callback); + + rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20); +} +#ifdef RT_USING_FINSH + MSH_CMD_EXPORT(sensor_fifo, Sensor fifo mode test function); +#endif + +static void sensor_irq_rx_entry(void *parameter) +{ + rt_device_t dev = (rt_device_t)parameter; + rt_sensor_t sensor = (rt_sensor_t)parameter; + struct rt_sensor_data data; + rt_size_t res, i = 0; + + while (1) + { + rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER); + + res = rt_device_read(dev, 0, &data, 1); + if (res == 1) + { + sensor_show_data(i++, sensor, &data); + } + } +} + +static void sensor_int(int argc, char **argv) +{ + static rt_thread_t tid1 = RT_NULL; + rt_device_t dev = RT_NULL; + rt_sensor_t sensor; + + dev = rt_device_find(argv[1]); + if (dev == RT_NULL) + { + LOG_E("Can't find device:%s", argv[1]); + return; + } + sensor = (rt_sensor_t)dev; + + if (sensor_rx_sem == RT_NULL) + { + sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO); + } + else + { + LOG_E("The thread is running, please reboot and try again"); + return; + } + + tid1 = rt_thread_create("sen_rx_thread", + sensor_irq_rx_entry, sensor, + 1024, + 15, 5); + + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + rt_device_set_rx_indicate(dev, rx_callback); + + if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK) + { + LOG_E("open device failed!"); + return; + } + rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20); +} +#ifdef RT_USING_FINSH + MSH_CMD_EXPORT(sensor_int, Sensor interrupt mode test function); +#endif + +static void sensor_polling(int argc, char **argv) +{ + rt_uint16_t num = 10; + rt_device_t dev = RT_NULL; + rt_sensor_t sensor; + struct rt_sensor_data data; + rt_size_t res, i; + rt_int32_t delay; + rt_err_t result; + + dev = rt_device_find(argv[1]); + if (dev == RT_NULL) + { + LOG_E("Can't find device:%s", argv[1]); + return; + } + if (argc > 2) + num = atoi(argv[2]); + + sensor = (rt_sensor_t)dev; + delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100; + + result = rt_device_open(dev, RT_DEVICE_FLAG_RDONLY); + if (result != RT_EOK) + { + LOG_E("open device failed! error code : %d", result); + return; + } + rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100); + + for (i = 0; i < num; i++) + { + res = rt_device_read(dev, 0, &data, 1); + if (res != 1) + { + LOG_E("read data failed!size is %d", res); + } + else + { + sensor_show_data(i, sensor, &data); + } + rt_thread_mdelay(delay); + } + rt_device_close(dev); +} +#ifdef RT_USING_FINSH + MSH_CMD_EXPORT(sensor_polling, Sensor polling mode test function); +#endif + +static void sensor(int argc, char **argv) +{ + static rt_device_t dev = RT_NULL; + struct rt_sensor_data data; + rt_sensor_t sensor; + rt_size_t res, i; + rt_int32_t delay; + + /* If the number of arguments less than 2 */ + if (argc < 2) + { + rt_kprintf("\n"); + rt_kprintf("sensor [OPTION] [PARAM]\n"); + rt_kprintf(" probe Probe sensor by given name\n"); + rt_kprintf(" info Get sensor info\n"); + rt_kprintf(" range Set range to var\n"); + rt_kprintf(" mode Set work mode to var\n"); + rt_kprintf(" power Set power mode to var\n"); + rt_kprintf(" rate Set output date rate to var\n"); + rt_kprintf(" read [num] Read [num] times sensor (default 5)\n"); + return ; + } + else if (!strcmp(argv[1], "info")) + { + struct rt_sensor_info info; + if (dev == RT_NULL) + { + LOG_W("Please probe sensor device first!"); + return ; + } + rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info); + rt_kprintf("model :%s\n", info.model); + rt_kprintf("type: :%s\n", sensor_get_type_name(&info)); + rt_kprintf("vendor :%s\n", sensor_get_vendor_name(&info)); + rt_kprintf("unit :%s\n", sensor_get_unit_name(&info)); + rt_kprintf("range_max :%d\n", info.range_max); + rt_kprintf("range_min :%d\n", info.range_min); + rt_kprintf("period_min:%dms\n", info.period_min); + rt_kprintf("fifo_max :%d\n", info.fifo_max); + } + else if (!strcmp(argv[1], "read")) + { + rt_uint16_t num = 5; + + if (dev == RT_NULL) + { + LOG_W("Please probe sensor device first!"); + return ; + } + if (argc == 3) + { + num = atoi(argv[2]); + } + + sensor = (rt_sensor_t)dev; + delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100; + + for (i = 0; i < num; i++) + { + res = rt_device_read(dev, 0, &data, 1); + if (res != 1) + { + LOG_E("read data failed!size is %d", res); + } + else + { + sensor_show_data(i, sensor, &data); + } + rt_thread_mdelay(delay); + } + } + else if (argc == 3) + { + if (!strcmp(argv[1], "probe")) + { + rt_uint8_t reg = 0xFF; + rt_device_t new_dev; + + new_dev = rt_device_find(argv[2]); + if (new_dev == RT_NULL) + { + LOG_E("Can't find device:%s", argv[2]); + return; + } + if (rt_device_open(new_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) + { + LOG_E("open device failed!"); + return; + } + rt_device_control(new_dev, RT_SENSOR_CTRL_GET_ID, ®); + LOG_I("device id: 0x%x!", reg); + if (dev) + { + rt_device_close(dev); + } + dev = new_dev; + } + else if (dev == RT_NULL) + { + LOG_W("Please probe sensor first!"); + return ; + } + else if (!strcmp(argv[1], "range")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_RANGE, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "mode")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_MODE, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "power")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_POWER, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "rate")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)atoi(argv[2])); + } + else + { + LOG_W("Unknown command, please enter 'sensor' get help information!"); + } + } + else + { + LOG_W("Unknown command, please enter 'sensor' get help information!"); + } +} +#ifdef RT_USING_FINSH + MSH_CMD_EXPORT(sensor, sensor test function); +#endif diff --git a/components/drivers/sensors/SConscript b/components/drivers/sensors/SConscript deleted file mode 100644 index afafc6d2ce..0000000000 --- a/components/drivers/sensors/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -# SConscript for sensor framework - -from building import * - -cwd = GetCurrentDir() -src = ['sensor.c'] -CPPPATH = [cwd, cwd + '/../include'] - -if GetDepend('RT_USING_SENSOR_CMD'): - src += ['sensor_cmd.c'] - -group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/drivers/sensors/sensor.c b/components/drivers/sensors/sensor.c deleted file mode 100644 index 3a5a0421df..0000000000 --- a/components/drivers/sensors/sensor.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-01-31 flybreak first version - * 2020-02-22 luhuadong support custom commands - */ - -#include - -#define DBG_TAG "sensor" -#define DBG_LVL DBG_INFO -#include - -#include - -static char *const sensor_name_str[] = -{ - "None", - "ac-", /* Accelerometer */ - "gy-", /* Gyroscope */ - "ma-", /* Magnetometer */ - "tm-", /* Temperature */ - "hm-", /* Relative Humidity */ - "br-", /* Barometer */ - "li-", /* Ambient light */ - "pr-", /* Proximity */ - "hr-", /* Heart Rate */ - "tv-", /* TVOC Level */ - "ni-", /* Noise Loudness */ - "st-", /* Step sensor */ - "fr-", /* Force sensor */ - "du-", /* Dust sensor */ - "ec-", /* eCO2 sensor */ - "gn-", /* GPS/GNSS sensor */ - "tf-", /* TOF sensor */ - "sp-", /* SpO2 sensor */ - "ia-", /* IAQ sensor */ - "et-", /* EtOH sensor */ - "bp-" /* Blood Pressure */ -}; - -/* sensor interrupt handler function */ -static void _sensor_cb(rt_sensor_t sen) -{ - if (sen->parent.rx_indicate == RT_NULL) - { - return; - } - - if (sen->irq_handle != RT_NULL) - { - sen->irq_handle(sen); - } - - /* The buffer is not empty. Read the data in the buffer first */ - if (sen->data_len > 0) - { - sen->parent.rx_indicate(&sen->parent, sen->data_len / sizeof(struct rt_sensor_data)); - } - else if (sen->config.mode == RT_SENSOR_MODE_INT) - { - /* The interrupt mode only produces one data at a time */ - sen->parent.rx_indicate(&sen->parent, 1); - } - else if (sen->config.mode == RT_SENSOR_MODE_FIFO) - { - sen->parent.rx_indicate(&sen->parent, sen->info.fifo_max); - } -} - -/* ISR for sensor interrupt */ -static void _irq_callback(void *args) -{ - rt_sensor_t sensor = (rt_sensor_t)args; - rt_uint8_t i; - - if (sensor->module) - { - /* Invoke a callback for all sensors in the module */ - for (i = 0; i < sensor->module->sen_num; i++) - { - _sensor_cb(sensor->module->sen[i]); - } - } - else - { - _sensor_cb(sensor); - } -} - -/* Sensor interrupt initialization function */ -static rt_err_t _sensor_irq_init(rt_sensor_t sensor) -{ - if (sensor->config.irq_pin.pin == RT_PIN_NONE) - { - return -RT_EINVAL; - } - - rt_pin_mode(sensor->config.irq_pin.pin, sensor->config.irq_pin.mode); - - if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN) - { - rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING, _irq_callback, (void *)sensor); - } - else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP) - { - rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, _irq_callback, (void *)sensor); - } - else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT) - { - rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, _irq_callback, (void *)sensor); - } - - rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_TRUE); - - LOG_I("interrupt init success"); - - return 0; -} - -/* sensor local ops */ -static rt_ssize_t _local_fetch_data(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len) -{ - LOG_D("Undefined fetch_data"); - return -RT_EINVAL; -} -static rt_err_t _local_control(rt_sensor_t sensor, int cmd, void *arg) -{ - LOG_D("Undefined control"); - return -RT_EINVAL; -} -static struct rt_sensor_ops local_ops = -{ - .fetch_data = _local_fetch_data, - .control = _local_control -}; - -/* RT-Thread Device Interface */ -static rt_err_t _sensor_open(rt_device_t dev, rt_uint16_t oflag) -{ - rt_sensor_t sensor = (rt_sensor_t)dev; - RT_ASSERT(dev != RT_NULL); - rt_err_t res = RT_EOK; - rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; - - if (sensor->module) - { - /* take the module mutex */ - rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); - } - - if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf == RT_NULL) - { - /* Allocate memory for the sensor buffer */ - sensor->data_buf = rt_malloc(sizeof(struct rt_sensor_data) * sensor->info.fifo_max); - if (sensor->data_buf == RT_NULL) - { - res = -RT_ENOMEM; - goto __exit; - } - } - if (sensor->ops->control != RT_NULL) - { - local_ctrl = sensor->ops->control; - } - - sensor->config.mode = RT_SENSOR_MODE_POLLING; - if (oflag & RT_DEVICE_FLAG_RDONLY && dev->flag & RT_DEVICE_FLAG_RDONLY) - { - /* If polling mode is supported, configure it to polling mode */ - local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_POLLING); - } - else if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* If interrupt mode is supported, configure it to interrupt mode */ - if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_INT) == RT_EOK) - { - /* Initialization sensor interrupt */ - _sensor_irq_init(sensor); - sensor->config.mode = RT_SENSOR_MODE_INT; - } - } - else if (oflag & RT_DEVICE_FLAG_FIFO_RX && dev->flag & RT_DEVICE_FLAG_FIFO_RX) - { - /* If fifo mode is supported, configure it to fifo mode */ - if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_FIFO) == RT_EOK) - { - /* Initialization sensor interrupt */ - _sensor_irq_init(sensor); - sensor->config.mode = RT_SENSOR_MODE_FIFO; - } - } - else - { - res = -RT_EINVAL; - goto __exit; - } - - /* Configure power mode to normal mode */ - if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_NORMAL) == RT_EOK) - { - sensor->config.power = RT_SENSOR_POWER_NORMAL; - } - -__exit: - if (sensor->module) - { - /* release the module mutex */ - rt_mutex_release(sensor->module->lock); - } - - return res; -} - -static rt_err_t _sensor_close(rt_device_t dev) -{ - rt_sensor_t sensor = (rt_sensor_t)dev; - int i; - rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; - - RT_ASSERT(dev != RT_NULL); - - if (sensor->module) - { - rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); - } - if (sensor->ops->control != RT_NULL) - { - local_ctrl = sensor->ops->control; - } - - /* Configure power mode to power down mode */ - if (local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_DOWN) == RT_EOK) - { - sensor->config.power = RT_SENSOR_POWER_DOWN; - } - - if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL) - { - for (i = 0; i < sensor->module->sen_num; i ++) - { - if (sensor->module->sen[i]->parent.ref_count > 0) - goto __exit; - } - - /* Free memory for the sensor buffer */ - for (i = 0; i < sensor->module->sen_num; i ++) - { - if (sensor->module->sen[i]->data_buf) - { - rt_free(sensor->module->sen[i]->data_buf); - sensor->module->sen[i]->data_buf = RT_NULL; - } - } - } - if (sensor->config.mode != RT_SENSOR_MODE_POLLING) - { - /* Sensor disable interrupt */ - if (sensor->config.irq_pin.pin != RT_PIN_NONE) - { - rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE); - } - } - -__exit: - if (sensor->module) - { - rt_mutex_release(sensor->module->lock); - } - - return RT_EOK; -} - -static rt_size_t _sensor_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len) -{ - rt_sensor_t sensor = (rt_sensor_t)dev; - rt_size_t result = 0; - RT_ASSERT(dev != RT_NULL); - - if (buf == NULL || len == 0) - { - return 0; - } - - if (sensor->module) - { - rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); - } - - /* The buffer is not empty. Read the data in the buffer first */ - if (sensor->data_len > 0) - { - if (len > sensor->data_len / sizeof(struct rt_sensor_data)) - { - len = sensor->data_len / sizeof(struct rt_sensor_data); - } - - rt_memcpy(buf, sensor->data_buf, len * sizeof(struct rt_sensor_data)); - - /* Clear the buffer */ - sensor->data_len = 0; - result = len; - } - else - { - /* If the buffer is empty, read the data */ - if (sensor->ops->fetch_data) - { - result = sensor->ops->fetch_data(sensor, buf, len); - } - } - - if (sensor->module) - { - rt_mutex_release(sensor->module->lock); - } - - return result; -} - -static rt_err_t _sensor_control(rt_device_t dev, int cmd, void *args) -{ - rt_sensor_t sensor = (rt_sensor_t)dev; - rt_err_t result = RT_EOK; - RT_ASSERT(dev != RT_NULL); - rt_err_t (*local_ctrl)(rt_sensor_t sensor, int cmd, void *arg) = _local_control; - - if (sensor->module) - { - rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER); - } - if (sensor->ops->control != RT_NULL) - { - local_ctrl = sensor->ops->control; - } - - switch (cmd) - { - case RT_SENSOR_CTRL_GET_ID: - if (args) - { - result = local_ctrl(sensor, RT_SENSOR_CTRL_GET_ID, args); - } - break; - case RT_SENSOR_CTRL_GET_INFO: - if (args) - { - rt_memcpy(args, &sensor->info, sizeof(struct rt_sensor_info)); - } - break; - case RT_SENSOR_CTRL_SET_RANGE: - /* Configuration measurement range */ - result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_RANGE, args); - if (result == RT_EOK) - { - sensor->config.range = (rt_int32_t)args; - LOG_D("set range %d", sensor->config.range); - } - break; - case RT_SENSOR_CTRL_SET_ODR: - /* Configuration data output rate */ - result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_ODR, args); - if (result == RT_EOK) - { - sensor->config.odr = (rt_uint32_t)args & 0xFFFF; - LOG_D("set odr %d", sensor->config.odr); - } - break; - case RT_SENSOR_CTRL_SET_POWER: - /* Configuration sensor power mode */ - result = local_ctrl(sensor, RT_SENSOR_CTRL_SET_POWER, args); - if (result == RT_EOK) - { - sensor->config.power = (rt_uint32_t)args & 0xFF; - LOG_D("set power mode code:", sensor->config.power); - } - break; - case RT_SENSOR_CTRL_SELF_TEST: - /* Device self-test */ - result = local_ctrl(sensor, RT_SENSOR_CTRL_SELF_TEST, args); - break; - default: - - if (cmd > RT_SENSOR_CTRL_USER_CMD_START) - { - /* Custom commands */ - result = local_ctrl(sensor, cmd, args); - } - else - { - result = -RT_ERROR; - } - break; - } - - if (sensor->module) - { - rt_mutex_release(sensor->module->lock); - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rt_sensor_ops = -{ - RT_NULL, - _sensor_open, - _sensor_close, - _sensor_read, - RT_NULL, - _sensor_control -}; -#endif - - -/* - * sensor register - */ -int rt_hw_sensor_register(rt_sensor_t sensor, - const char *name, - rt_uint32_t flag, - void *data) -{ - rt_int8_t result; - rt_device_t device; - RT_ASSERT(sensor != RT_NULL); - - char *sensor_name = RT_NULL, *device_name = RT_NULL; - - if (sensor->ops == RT_NULL) - { - sensor->ops = &local_ops; - } - - /* Add a type name for the sensor device */ - sensor_name = sensor_name_str[sensor->info.type]; - device_name = (char *)rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name)); - if (device_name == RT_NULL) - { - LOG_E("device_name calloc failed!"); - return -RT_ERROR; - } - - rt_memcpy(device_name, sensor_name, rt_strlen(sensor_name) + 1); - strcat(device_name, name); - - if (sensor->module != RT_NULL && sensor->module->lock == RT_NULL) - { - /* Create a mutex lock for the module */ - sensor->module->lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO); - if (sensor->module->lock == RT_NULL) - { - rt_free(device_name); - return -RT_ERROR; - } - } - - device = &sensor->parent; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &rt_sensor_ops; -#else - device->init = RT_NULL; - device->open = _sensor_open; - device->close = _sensor_close; - device->read = _sensor_read; - device->write = RT_NULL; - device->control = _sensor_control; -#endif - device->type = RT_Device_Class_Sensor; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - device->user_data = data; - - result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE); - if (result != RT_EOK) - { - LOG_E("sensor[%s] register err code: %d", device_name, result); - rt_free(device_name); - return result; - } - - LOG_I("sensor[%s] init success", device_name); - rt_free(device_name); - return RT_EOK; -} diff --git a/components/drivers/sensors/sensor_cmd.c b/components/drivers/sensors/sensor_cmd.c deleted file mode 100755 index 71446c8c58..0000000000 --- a/components/drivers/sensors/sensor_cmd.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-01-31 flybreak first version - * 2019-07-16 WillianChan Increase the output of sensor information - * 2020-02-22 luhuadong Add vendor info and sensor types for cmd - */ - -#include - -#define DBG_TAG "sensor.cmd" -#define DBG_LVL DBG_INFO -#include - -#include -#include - -static rt_sem_t sensor_rx_sem = RT_NULL; - -static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor_data *sensor_data) -{ - switch (sensor->info.type) - { - case RT_SENSOR_CLASS_ACCE: - LOG_I("num:%d, x:%f, y:%f, z:%f mg, timestamp:%u", num, sensor_data->data.acce.x, sensor_data->data.acce.y, sensor_data->data.acce.z, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_GYRO: - LOG_I("num:%d, x:%f, y:%f, z:%f dps, timestamp:%u", num, sensor_data->data.gyro.x, sensor_data->data.gyro.y, sensor_data->data.gyro.z, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_MAG: - LOG_I("num:%d, x:%f, y:%f, z:%f mGauss, timestamp:%u", num, sensor_data->data.mag.x, sensor_data->data.mag.y, sensor_data->data.mag.z, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_GNSS: - LOG_I("num:%d, lon:%f, lat:%f, timestamp:%u", num, sensor_data->data.coord.longitude, sensor_data->data.coord.latitude, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_TEMP: - LOG_I("num:%d, temp:%f C, timestamp:%u", num, sensor_data->data.temp, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_HUMI: - LOG_I("num:%d, humi:%f%%, timestamp:%u", num, sensor_data->data.humi, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_BARO: - LOG_I("num:%d, press:%f pa, timestamp:%u", num, sensor_data->data.baro, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_LIGHT: - LOG_I("num:%d, light:%f lux, timestamp:%u", num, sensor_data->data.light, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_PROXIMITY: - case RT_SENSOR_CLASS_TOF: - LOG_I("num:%d, distance:%f, timestamp:%u", num, sensor_data->data.proximity, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_HR: - LOG_I("num:%d, heart rate:%f bpm, timestamp:%u", num, sensor_data->data.hr, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_TVOC: - LOG_I("num:%d, tvoc:%f ppb, timestamp:%u", num, sensor_data->data.tvoc, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_NOISE: - LOG_I("num:%d, noise:%f, timestamp:%u", num, sensor_data->data.noise, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_STEP: - LOG_I("num:%d, step:%f, timestamp:%u", num, sensor_data->data.step, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_FORCE: - LOG_I("num:%d, force:%f, timestamp:%u", num, sensor_data->data.force, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_DUST: - LOG_I("num:%d, dust:%f ug/m3, timestamp:%u", num, sensor_data->data.dust, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_ECO2: - LOG_I("num:%d, eco2:%f ppm, timestamp:%u", num, sensor_data->data.eco2, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_IAQ: - LOG_I("num:%d, IAQ:%f, timestamp:%u", num, sensor_data->data.iaq, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_ETOH: - LOG_I("num:%d, EtOH:%f ppm, timestamp:%u", num, sensor_data->data.etoh, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_BP: - LOG_I("num:%d, bp.sbp:%f mmHg, bp.dbp:%f mmHg, timestamp:%u", num, sensor_data->data.bp.sbp, sensor_data->data.bp.dbp, sensor_data->timestamp); - break; - default: - LOG_E("Unknown type of sensor!"); - break; - } -} - -static rt_err_t rx_callback(rt_device_t dev, rt_size_t size) -{ - rt_sem_release(sensor_rx_sem); - return 0; -} - -static void sensor_fifo_rx_entry(void *parameter) -{ - rt_device_t dev = (rt_device_t)parameter; - rt_sensor_t sensor = (rt_sensor_t)parameter; - struct rt_sensor_data *data = RT_NULL; - struct rt_sensor_info info; - rt_size_t res, i; - - rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info); - - data = (struct rt_sensor_data *)rt_malloc(sizeof(struct rt_sensor_data) * info.fifo_max); - if (data == RT_NULL) - { - LOG_E("Memory allocation failed!"); - } - - while (1) - { - rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER); - - res = rt_device_read(dev, 0, data, info.fifo_max); - for (i = 0; i < res; i++) - { - sensor_show_data(i, sensor, &data[i]); - } - } -} - -static void sensor_fifo(int argc, char **argv) -{ - static rt_thread_t tid1 = RT_NULL; - rt_device_t dev = RT_NULL; - rt_sensor_t sensor; - - dev = rt_device_find(argv[1]); - if (dev == RT_NULL) - { - LOG_E("Can't find device:%s", argv[1]); - return; - } - sensor = (rt_sensor_t)dev; - - if (rt_device_open(dev, RT_DEVICE_FLAG_FIFO_RX) != RT_EOK) - { - LOG_E("open device failed!"); - return; - } - - if (sensor_rx_sem == RT_NULL) - { - sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO); - } - else - { - LOG_E("The thread is running, please reboot and try again"); - return; - } - - tid1 = rt_thread_create("sen_rx_thread", - sensor_fifo_rx_entry, sensor, - 1024, - 15, 5); - - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - - rt_device_set_rx_indicate(dev, rx_callback); - - rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20); -} -#ifdef RT_USING_FINSH - MSH_CMD_EXPORT(sensor_fifo, Sensor fifo mode test function); -#endif - -static void sensor_irq_rx_entry(void *parameter) -{ - rt_device_t dev = (rt_device_t)parameter; - rt_sensor_t sensor = (rt_sensor_t)parameter; - struct rt_sensor_data data; - rt_size_t res, i = 0; - - while (1) - { - rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER); - - res = rt_device_read(dev, 0, &data, 1); - if (res == 1) - { - sensor_show_data(i++, sensor, &data); - } - } -} - -static void sensor_int(int argc, char **argv) -{ - static rt_thread_t tid1 = RT_NULL; - rt_device_t dev = RT_NULL; - rt_sensor_t sensor; - - dev = rt_device_find(argv[1]); - if (dev == RT_NULL) - { - LOG_E("Can't find device:%s", argv[1]); - return; - } - sensor = (rt_sensor_t)dev; - - if (sensor_rx_sem == RT_NULL) - { - sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO); - } - else - { - LOG_E("The thread is running, please reboot and try again"); - return; - } - - tid1 = rt_thread_create("sen_rx_thread", - sensor_irq_rx_entry, sensor, - 1024, - 15, 5); - - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - - rt_device_set_rx_indicate(dev, rx_callback); - - if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK) - { - LOG_E("open device failed!"); - return; - } - rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20); -} -#ifdef RT_USING_FINSH - MSH_CMD_EXPORT(sensor_int, Sensor interrupt mode test function); -#endif - -static void sensor_polling(int argc, char **argv) -{ - rt_uint16_t num = 10; - rt_device_t dev = RT_NULL; - rt_sensor_t sensor; - struct rt_sensor_data data; - rt_size_t res, i; - rt_int32_t delay; - rt_err_t result; - - dev = rt_device_find(argv[1]); - if (dev == RT_NULL) - { - LOG_E("Can't find device:%s", argv[1]); - return; - } - if (argc > 2) - num = atoi(argv[2]); - - sensor = (rt_sensor_t)dev; - delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100; - - result = rt_device_open(dev, RT_DEVICE_FLAG_RDONLY); - if (result != RT_EOK) - { - LOG_E("open device failed! error code : %d", result); - return; - } - rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100); - - for (i = 0; i < num; i++) - { - res = rt_device_read(dev, 0, &data, 1); - if (res != 1) - { - LOG_E("read data failed!size is %d", res); - } - else - { - sensor_show_data(i, sensor, &data); - } - rt_thread_mdelay(delay); - } - rt_device_close(dev); -} -#ifdef RT_USING_FINSH - MSH_CMD_EXPORT(sensor_polling, Sensor polling mode test function); -#endif - -static void sensor(int argc, char **argv) -{ - static rt_device_t dev = RT_NULL; - struct rt_sensor_data data; - rt_sensor_t sensor; - rt_size_t res, i; - rt_int32_t delay; - - /* If the number of arguments less than 2 */ - if (argc < 2) - { - rt_kprintf("\n"); - rt_kprintf("sensor [OPTION] [PARAM]\n"); - rt_kprintf(" probe Probe sensor by given name\n"); - rt_kprintf(" info Get sensor info\n"); - rt_kprintf(" range Set range to var\n"); - rt_kprintf(" mode Set work mode to var\n"); - rt_kprintf(" power Set power mode to var\n"); - rt_kprintf(" rate Set output date rate to var\n"); - rt_kprintf(" read [num] Read [num] times sensor (default 5)\n"); - return ; - } - else if (!strcmp(argv[1], "info")) - { - struct rt_sensor_info info; - if (dev == RT_NULL) - { - LOG_W("Please probe sensor device first!"); - return ; - } - rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info); - switch (info.vendor) - { - case RT_SENSOR_VENDOR_UNKNOWN: - rt_kprintf("vendor :unknown vendor\n"); - break; - case RT_SENSOR_VENDOR_STM: - rt_kprintf("vendor :STMicroelectronics\n"); - break; - case RT_SENSOR_VENDOR_BOSCH: - rt_kprintf("vendor :Bosch\n"); - break; - case RT_SENSOR_VENDOR_INVENSENSE: - rt_kprintf("vendor :Invensense\n"); - break; - case RT_SENSOR_VENDOR_SEMTECH: - rt_kprintf("vendor :Semtech\n"); - break; - case RT_SENSOR_VENDOR_GOERTEK: - rt_kprintf("vendor :Goertek\n"); - break; - case RT_SENSOR_VENDOR_MIRAMEMS: - rt_kprintf("vendor :MiraMEMS\n"); - break; - case RT_SENSOR_VENDOR_DALLAS: - rt_kprintf("vendor :Dallas\n"); - break; - case RT_SENSOR_VENDOR_ASAIR: - rt_kprintf("vendor :Asair\n"); - break; - case RT_SENSOR_VENDOR_SHARP: - rt_kprintf("vendor :Sharp\n"); - break; - case RT_SENSOR_VENDOR_SENSIRION: - rt_kprintf("vendor :Sensirion\n"); - break; - case RT_SENSOR_VENDOR_TI: - rt_kprintf("vendor :Texas Instruments\n"); - break; - case RT_SENSOR_VENDOR_PLANTOWER: - rt_kprintf("vendor :Plantower\n"); - break; - case RT_SENSOR_VENDOR_AMS: - rt_kprintf("vendor :AMS\n"); - break; - case RT_SENSOR_VENDOR_MAXIM: - rt_kprintf("vendor :Maxim Integrated\n"); - break; - case RT_SENSOR_VENDOR_MELEXIS: - rt_kprintf("vendor :Melexis\n"); - break; - } - rt_kprintf("model :%s\n", info.model); - switch (info.unit) - { - case RT_SENSOR_UNIT_NONE: - rt_kprintf("unit :none\n"); - break; - case RT_SENSOR_UNIT_MG: - rt_kprintf("unit :mG\n"); - break; - case RT_SENSOR_UNIT_MDPS: - rt_kprintf("unit :mdps\n"); - break; - case RT_SENSOR_UNIT_MGAUSS: - rt_kprintf("unit :mGauss\n"); - break; - case RT_SENSOR_UNIT_LUX: - rt_kprintf("unit :lux\n"); - break; - case RT_SENSOR_UNIT_CM: - rt_kprintf("unit :cm\n"); - break; - case RT_SENSOR_UNIT_PA: - rt_kprintf("unit :pa\n"); - break; - case RT_SENSOR_UNIT_PERMILLAGE: - rt_kprintf("unit :permillage\n"); - break; - case RT_SENSOR_UNIT_DCELSIUS: - rt_kprintf("unit :Celsius\n"); - break; - case RT_SENSOR_UNIT_HZ: - rt_kprintf("unit :HZ\n"); - break; - case RT_SENSOR_UNIT_ONE: - rt_kprintf("unit :1\n"); - break; - case RT_SENSOR_UNIT_BPM: - rt_kprintf("unit :bpm\n"); - break; - case RT_SENSOR_UNIT_MM: - rt_kprintf("unit :mm\n"); - break; - case RT_SENSOR_UNIT_MN: - rt_kprintf("unit :mN\n"); - break; - case RT_SENSOR_UNIT_PPM: - rt_kprintf("unit :ppm\n"); - break; - case RT_SENSOR_UNIT_PPB: - rt_kprintf("unit :ppb\n"); - break; - case RT_SENSOR_UNIT_MMHG: - rt_kprintf("unit :mmHg\n"); - break; - } - rt_kprintf("range_max :%d\n", info.range_max); - rt_kprintf("range_min :%d\n", info.range_min); - rt_kprintf("period_min:%dms\n", info.period_min); - rt_kprintf("fifo_max :%d\n", info.fifo_max); - } - else if (!strcmp(argv[1], "read")) - { - rt_uint16_t num = 5; - - if (dev == RT_NULL) - { - LOG_W("Please probe sensor device first!"); - return ; - } - if (argc == 3) - { - num = atoi(argv[2]); - } - - sensor = (rt_sensor_t)dev; - delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100; - - for (i = 0; i < num; i++) - { - res = rt_device_read(dev, 0, &data, 1); - if (res != 1) - { - LOG_E("read data failed!size is %d", res); - } - else - { - sensor_show_data(i, sensor, &data); - } - rt_thread_mdelay(delay); - } - } - else if (argc == 3) - { - if (!strcmp(argv[1], "probe")) - { - rt_uint8_t reg = 0xFF; - rt_device_t new_dev; - - new_dev = rt_device_find(argv[2]); - if (new_dev == RT_NULL) - { - LOG_E("Can't find device:%s", argv[2]); - return; - } - if (rt_device_open(new_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) - { - LOG_E("open device failed!"); - return; - } - rt_device_control(new_dev, RT_SENSOR_CTRL_GET_ID, ®); - LOG_I("device id: 0x%x!", reg); - if (dev) - { - rt_device_close(dev); - } - dev = new_dev; - } - else if (dev == RT_NULL) - { - LOG_W("Please probe sensor first!"); - return ; - } - else if (!strcmp(argv[1], "range")) - { - rt_device_control(dev, RT_SENSOR_CTRL_SET_RANGE, (void *)atoi(argv[2])); - } - else if (!strcmp(argv[1], "mode")) - { - rt_device_control(dev, RT_SENSOR_CTRL_SET_MODE, (void *)atoi(argv[2])); - } - else if (!strcmp(argv[1], "power")) - { - rt_device_control(dev, RT_SENSOR_CTRL_SET_POWER, (void *)atoi(argv[2])); - } - else if (!strcmp(argv[1], "rate")) - { - rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)atoi(argv[2])); - } - else - { - LOG_W("Unknown command, please enter 'sensor' get help information!"); - } - } - else - { - LOG_W("Unknown command, please enter 'sensor' get help information!"); - } -} -#ifdef RT_USING_FINSH - MSH_CMD_EXPORT(sensor, sensor test function); -#endif -- cgit v1.3.1