From 704554f1f9966ee830907c7674a676e2ea94a29c Mon Sep 17 00:00:00 2001 From: "Man, Jianting (Meco)" <920369182@qq.com> Date: Sun, 18 Jun 2023 22:36:53 -0400 Subject: [PATCH] =?UTF-8?q?[sensor-v2]=E5=B0=86=E5=BD=93=E5=89=8Dsensor?= =?UTF-8?q?=E6=A1=86=E6=9E=B6revert=E5=9B=9Ev1=E7=89=88=E6=9C=AC=E5=B9=B6?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E4=B8=BAv2=20(#7698)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/nuvoton/libraries/nu_packages/Kconfig | 3 + components/drivers/Kconfig | 6 +- components/drivers/include/drivers/sensor.h | 406 +++++--------- .../drivers/include/drivers/sensor_v2.h | 406 ++++++++++++++ components/drivers/include/rtdevice.h | 4 + components/drivers/sensor/SConscript | 17 +- components/drivers/sensor/v1/SConscript | 12 + components/drivers/sensor/v1/sensor.c | 495 +++++++++++++++++ components/drivers/sensor/v1/sensor_cmd.c | 516 ++++++++++++++++++ components/drivers/sensor/v2/SConscript | 12 + .../drivers/sensor/{ => v2}/sensor_cmd.c | 4 +- .../sensor/{sensor.c => v2/sensor_v2.c} | 4 +- 12 files changed, 1593 insertions(+), 292 deletions(-) create mode 100644 components/drivers/include/drivers/sensor_v2.h create mode 100644 components/drivers/sensor/v1/SConscript create mode 100644 components/drivers/sensor/v1/sensor.c create mode 100644 components/drivers/sensor/v1/sensor_cmd.c create mode 100644 components/drivers/sensor/v2/SConscript rename components/drivers/sensor/{ => v2}/sensor_cmd.c (99%) rename components/drivers/sensor/{sensor.c => v2/sensor_v2.c} (99%) diff --git a/bsp/nuvoton/libraries/nu_packages/Kconfig b/bsp/nuvoton/libraries/nu_packages/Kconfig index 98f95f7e3d..2f4f387d91 100644 --- a/bsp/nuvoton/libraries/nu_packages/Kconfig +++ b/bsp/nuvoton/libraries/nu_packages/Kconfig @@ -11,18 +11,21 @@ menu "Nuvoton Packages Config" bool "BMX055 9-axis sensor." select RT_USING_I2C select RT_USING_SENSOR + select RT_USING_SENSOR_V2 default n config NU_PKG_USING_MAX31875 bool "MAX31875 Temperature sensor." select RT_USING_I2C select RT_USING_SENSOR + select RT_USING_SENSOR_V2 default n config NU_PKG_USING_NCT7717U bool "NCT7717U Temperature sensor." select RT_USING_I2C select RT_USING_SENSOR + select RT_USING_SENSOR_V2 default n config NU_PKG_USING_NAU88L25 diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 1b6fc17ebf..92a7dbf6ff 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -370,9 +370,13 @@ config RT_USING_SENSOR default n if RT_USING_SENSOR + config RT_USING_SENSOR_V2 + bool "Enable Sensor Framework v2" + default n + config RT_USING_SENSOR_CMD bool "Using Sensor cmd" - select PKG_USING_RT_VSNPRINTF_FULL + select PKG_USING_RT_VSNPRINTF_FULL if RT_USING_SENSOR_V2 default y endif diff --git a/components/drivers/include/drivers/sensor.h b/components/drivers/include/drivers/sensor.h index 72044a3ee2..e09d8d8c94 100644 --- a/components/drivers/include/drivers/sensor.h +++ b/components/drivers/include/drivers/sensor.h @@ -1,12 +1,11 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * 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 - * 2022-12-17 Meco Man re-implement sensor framework */ #ifndef __SENSOR_H__ @@ -25,293 +24,142 @@ extern "C" { #define rt_sensor_get_ts() rt_tick_get() /* API for the sensor to get the timestamp */ #endif +#define RT_PIN_NONE 0xFFFF /* RT PIN NONE */ #define RT_DEVICE_FLAG_FIFO_RX 0x200 /* Flag to use when the sensor is open by fifo mode */ #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_TYPE_NONE (0) -#define RT_SENSOR_TYPE_NONE_STR "None" -#define RT_SENSOR_TYPE_ACCE (1) -#define RT_SENSOR_TYPE_ACCE_STR "Accelerometer" -#define RT_SENSOR_TYPE_GYRO (2) -#define RT_SENSOR_TYPE_GYRO_STR "Gyroscope" -#define RT_SENSOR_TYPE_MAG (3) -#define RT_SENSOR_TYPE_MAG_STR "Magnetometer" -#define RT_SENSOR_TYPE_TEMP (4) -#define RT_SENSOR_TYPE_TEMP_STR "Temperature" -#define RT_SENSOR_TYPE_HUMI (5) -#define RT_SENSOR_TYPE_HUMI_STR "Relative Humidity" -#define RT_SENSOR_TYPE_BARO (6) -#define RT_SENSOR_TYPE_BARO_STR "Barometer" -#define RT_SENSOR_TYPE_LIGHT (7) -#define RT_SENSOR_TYPE_LIGHT_STR "Ambient Light" -#define RT_SENSOR_TYPE_PROXIMITY (8) -#define RT_SENSOR_TYPE_PROXIMITY_STR "Proximity" -#define RT_SENSOR_TYPE_HR (9) -#define RT_SENSOR_TYPE_HR_STR "Heart Rate" -#define RT_SENSOR_TYPE_TVOC (10) -#define RT_SENSOR_TYPE_TVOC_STR "TVOC Level" -#define RT_SENSOR_TYPE_NOISE (11) -#define RT_SENSOR_TYPE_NOISE_STR "Noise Loudness" -#define RT_SENSOR_TYPE_STEP (12) -#define RT_SENSOR_TYPE_STEP_STR "Step" -#define RT_SENSOR_TYPE_FORCE (13) -#define RT_SENSOR_TYPE_FORCE_STR "Force" -#define RT_SENSOR_TYPE_DUST (14) -#define RT_SENSOR_TYPE_DUST_STR "Dust" -#define RT_SENSOR_TYPE_ECO2 (15) -#define RT_SENSOR_TYPE_ECO2_STR "eCO2" -#define RT_SENSOR_TYPE_GNSS (16) -#define RT_SENSOR_TYPE_GNSS_STR "GNSS" -#define RT_SENSOR_TYPE_TOF (17) -#define RT_SENSOR_TYPE_TOF_STR "ToF" -#define RT_SENSOR_TYPE_SPO2 (18) -#define RT_SENSOR_TYPE_SPO2_STR "SpO2" -#define RT_SENSOR_TYPE_IAQ (19) -#define RT_SENSOR_TYPE_IAQ_STR "IAQ" -#define RT_SENSOR_TYPE_ETOH (20) -#define RT_SENSOR_TYPE_ETOH_STR "EtOH" -#define RT_SENSOR_TYPE_BP (21) -#define RT_SENSOR_TYPE_BP_STR "Blood Pressure" -#define RT_SENSOR_TYPE_VOLTAGE (22) -#define RT_SENSOR_TYPE_VOLTAGE_STR "Voltage" -#define RT_SENSOR_TYPE_CURRENT (23) -#define RT_SENSOR_TYPE_CURRENT_STR "Current" + +#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 */ /* Sensor vendor types */ + #define RT_SENSOR_VENDOR_UNKNOWN (0) -#define RT_SENSOR_VENDOR_UNKNOWN_STR "Unknown" -#define RT_SENSOR_VENDOR_VIRTUAL (1) -#define RT_SENSOR_VENDOR_VIRTUAL_STR "Virtual Sensor" -#define RT_SENSOR_VENDOR_ONCHIP (2) -#define RT_SENSOR_VENDOR_ONCHIP_STR "OnChip" -#define RT_SENSOR_VENDOR_STM (3) -#define RT_SENSOR_VENDOR_STM_STR "STMicroelectronics" -#define RT_SENSOR_VENDOR_BOSCH (4) -#define RT_SENSOR_VENDOR_BOSCH_STR "Bosch" -#define RT_SENSOR_VENDOR_INVENSENSE (5) -#define RT_SENSOR_VENDOR_INVENSENSE_STR "Invensense" -#define RT_SENSOR_VENDOR_SEMTECH (6) -#define RT_SENSOR_VENDOR_SEMTECH_STR "Semtech" -#define RT_SENSOR_VENDOR_GOERTEK (7) -#define RT_SENSOR_VENDOR_GOERTEK_STR "Goertek" -#define RT_SENSOR_VENDOR_MIRAMEMS (8) -#define RT_SENSOR_VENDOR_MIRAMEMS_STR "MiraMEMS" -#define RT_SENSOR_VENDOR_DALLAS (9) -#define RT_SENSOR_VENDOR_DALLAS_STR "Dallas" -#define RT_SENSOR_VENDOR_ASAIR (10) -#define RT_SENSOR_VENDOR_ASAIR_STR "Aosong" -#define RT_SENSOR_VENDOR_SHARP (11) -#define RT_SENSOR_VENDOR_SHARP_STR "Sharp" -#define RT_SENSOR_VENDOR_SENSIRION (12) -#define RT_SENSOR_VENDOR_SENSIRION_STR "Sensirion" -#define RT_SENSOR_VENDOR_TI (13) -#define RT_SENSOR_VENDOR_TI_STR "Texas Instruments" -#define RT_SENSOR_VENDOR_PLANTOWER (14) -#define RT_SENSOR_VENDOR_PLANTOWER_STR "Plantower" -#define RT_SENSOR_VENDOR_AMS (15) -#define RT_SENSOR_VENDOR_AMS_STR "ams-OSRAM AG" -#define RT_SENSOR_VENDOR_MAXIM (16) -#define RT_SENSOR_VENDOR_MAXIM_STR "Maxim Integrated" -#define RT_SENSOR_VENDOR_MELEXIS (17) -#define RT_SENSOR_VENDOR_MELEXIS_STR "Melexis" -#define RT_SENSOR_VENDOR_LSC (18) -#define RT_SENSOR_VENDOR_LSC_STR "Lite On" +#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 */ /* Sensor unit types */ -#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_M (5) /* Distance unit: m */ -#define RT_SENSOR_UNIT_M_STR "m" -#define RT_SENSOR_UNIT_CM (6) /* Distance unit: cm */ -#define RT_SENSOR_UNIT_CM_STR "cm" -#define RT_SENSOR_UNIT_MM (7) /* Distance unit: mm */ -#define RT_SENSOR_UNIT_MM_STR "mm" -#define RT_SENSOR_UNIT_PA (8) /* Barometer unit: Pa */ -#define RT_SENSOR_UNIT_PA_STR "Pa" -#define RT_SENSOR_UNIT_MMHG (9) /* Blood Pressure unit: mmHg */ -#define RT_SENSOR_UNIT_MMHG_STR "mmHg" -#define RT_SENSOR_UNIT_PERCENTAGE (10) /* Relative Humidity unit: percentage */ -#define RT_SENSOR_UNIT_PERCENTAGE_STR "%" -#define RT_SENSOR_UNIT_PERMILLAGE (11) /* Relative Humidity unit: permillage */ -#define RT_SENSOR_UNIT_PERMILLAGE_STR "‰" -#define RT_SENSOR_UNIT_CELSIUS (12) /* Temperature unit: Celsius ℃ */ -#define RT_SENSOR_UNIT_CELSIUS_STR "℃" -#define RT_SENSOR_UNIT_FAHRENHEIT (13) /* Temperature unit: Fahrenheit ℉ */ -#define RT_SENSOR_UNIT_FAHRENHEIT_STR "℉" -#define RT_SENSOR_UNIT_KELVIN (14) /* Temperature unit: Kelvin K */ -#define RT_SENSOR_UNIT_KELVIN_STR "K" -#define RT_SENSOR_UNIT_HZ (15) /* Frequency unit: Hz */ -#define RT_SENSOR_UNIT_HZ_STR "Hz" -#define RT_SENSOR_UNIT_V (16) /* Voltage unit: V */ -#define RT_SENSOR_UNIT_V_STR "V" -#define RT_SENSOR_UNIT_MV (17) /* Voltage unit: mV */ -#define RT_SENSOR_UNIT_MV_STR "mV" -#define RT_SENSOR_UNIT_A (18) /* Current unit: A */ -#define RT_SENSOR_UNIT_A_STR "A" -#define RT_SENSOR_UNIT_MA (19) /* Current unit: mA */ -#define RT_SENSOR_UNIT_MA_STR "mA" -#define RT_SENSOR_UNIT_N (20) /* Force unit: N */ -#define RT_SENSOR_UNIT_N_STR "N" -#define RT_SENSOR_UNIT_MN (21) /* Force unit: mN */ -#define RT_SENSOR_UNIT_MN_STR "mN" -#define RT_SENSOR_UNIT_BPM (22) /* Heart rate unit: bpm */ -#define RT_SENSOR_UNIT_BPM_STR "bpm" -#define RT_SENSOR_UNIT_PPM (23) /* Concentration unit: ppm */ -#define RT_SENSOR_UNIT_PPM_STR "ppm" -#define RT_SENSOR_UNIT_PPB (24) /* Concentration unit: ppb */ -#define RT_SENSOR_UNIT_PPB_STR "ppb" -#define RT_SENSOR_UNIT_DMS (25) /* Coordinates unit: DMS */ -#define RT_SENSOR_UNIT_DMS_STR "DMS" -#define RT_SENSOR_UNIT_DD (26) /* Coordinates unit: DD */ -#define RT_SENSOR_UNIT_DD_STR "DD" -#define RT_SENSOR_UNIT_MGM3 (27) /* Concentration unit: mg/m3 */ -#define RT_SENSOR_UNIT_MGM3_STR "mg/m3" +#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 */ /* Sensor communication interface types */ -#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" -#define RT_SENSOR_INTF_CAN (1 << 4) -#define RT_SENSOR_INTF_CAN_STR "CAN" -#define RT_SENSOR_INTF_MODBUS (1 << 5) -#define RT_SENSOR_INTF_MODBUS_STR "Modbus" -/** - * Sensor mode - * rt_uint16_t mode - * 0000 | 0000 | 0000 | 0000 - * unused accuracy power fetch data - */ -#define RT_SENSOR_MODE_ACCURACY_BIT_OFFSET (8) -#define RT_SENSOR_MODE_POWER_BIT_OFFSET (4) -#define RT_SENSOR_MODE_FETCH_BIT_OFFSET (0) +#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_MODE_GET_ACCURACY(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_ACCURACY_BIT_OFFSET) & 0x0F) -#define RT_SENSOR_MODE_GET_POWER(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_POWER_BIT_OFFSET) & 0x0F) -#define RT_SENSOR_MODE_GET_FETCH(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_FETCH_BIT_OFFSET) & 0x0F) +/* Sensor power mode types */ -#define RT_SENSOR_MODE_CLEAR_ACCURACY(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET))) -#define RT_SENSOR_MODE_CLEAR_POWER(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_POWER_BIT_OFFSET))) -#define RT_SENSOR_MODE_CLEAR_FETCH(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_FETCH_BIT_OFFSET))) +#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_MODE_SET_ACCURACY(mode, accuracy_mode) RT_SENSOR_MODE_CLEAR_ACCURACY(mode); (mode |= (accuracy_mode << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET)) -#define RT_SENSOR_MODE_SET_POWER(mode, power_mode) RT_SENSOR_MODE_CLEAR_POWER(mode); (mode |= (power_mode << RT_SENSOR_MODE_POWER_BIT_OFFSET)) -#define RT_SENSOR_MODE_SET_FETCH(mode, fetch_mode) RT_SENSOR_MODE_CLEAR_FETCH(mode); (mode |= (fetch_mode << RT_SENSOR_MODE_FETCH_BIT_OFFSET)) +/* Sensor work mode types */ -/* Sensor mode: accuracy */ -#define RT_SENSOR_MODE_ACCURACY_HIGHEST (0) -#define RT_SENSOR_MODE_ACCURACY_HIGHEST_STR "Accuracy Highest" -#define RT_SENSOR_MODE_ACCURACY_HIGH (1) -#define RT_SENSOR_MODE_ACCURACY_HIGH_STR "Accuracy High" -#define RT_SENSOR_MODE_ACCURACY_MEDIUM (2) -#define RT_SENSOR_MODE_ACCURACY_MEDIUM_STR "Accuracy Medium" -#define RT_SENSOR_MODE_ACCURACY_LOW (3) -#define RT_SENSOR_MODE_ACCURACY_LOW_STR "Accuracy Low" -#define RT_SENSOR_MODE_ACCURACY_LOWEST (4) -#define RT_SENSOR_MODE_ACCURACY_LOWEST_STR "Accuracy Lowest" -#define RT_SENSOR_MODE_ACCURACY_NOTRUST (5) -#define RT_SENSOR_MODE_ACCURACY_NOTRUST_STR "Accuracy No Trust" - -/* Sensor mode: power */ -#define RT_SENSOR_MODE_POWER_HIGHEST (0) -#define RT_SENSOR_MODE_POWER_HIGHEST_STR "Power Highest" -#define RT_SENSOR_MODE_POWER_HIGH (1) -#define RT_SENSOR_MODE_POWER_HIGH_STR "Power High" -#define RT_SENSOR_MODE_POWER_MEDIUM (2) -#define RT_SENSOR_MODE_POWER_MEDIUM_STR "Power Medium" -#define RT_SENSOR_MODE_POWER_LOW (3) -#define RT_SENSOR_MODE_POWER_LOW_STR "Power Low" -#define RT_SENSOR_MODE_POWER_LOWEST (4) -#define RT_SENSOR_MODE_POWER_LOWEST_STR "Power Lowest" -#define RT_SENSOR_MODE_POWER_DOWN (5) -#define RT_SENSOR_MODE_POWER_DOWN_STR "Power Down" - -/* Sensor mode: fetch data */ -#define RT_SENSOR_MODE_FETCH_POLLING (0) /* One shot only read a data */ -#define RT_SENSOR_MODE_FETCH_POLLING_STR "Polling Mode" -#define RT_SENSOR_MODE_FETCH_INT (1) /* TODO: One shot interrupt only read a data */ -#define RT_SENSOR_MODE_FETCH_INT_STR "Interrupt Mode" -#define RT_SENSOR_MODE_FETCH_FIFO (2) /* TODO: One shot interrupt read all fifo data */ -#define RT_SENSOR_MODE_FETCH_FIFO_STR "FIFO Mode" +#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_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Take a self test */ -#define RT_SENSOR_CTRL_SOFT_RESET (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* soft reset sensor */ -#define RT_SENSOR_CTRL_SET_FETCH_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* set fetch data mode */ -#define RT_SENSOR_CTRL_SET_POWER_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* set power mode */ -#define RT_SENSOR_CTRL_SET_ACCURACY_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* set accuracy mode */ + +#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 */ -/* sensor floating data type */ -#ifdef RT_USING_SENSOR_DOUBLE_FLOAT -typedef double rt_sensor_float_t; -#else -typedef float rt_sensor_float_t; -#endif /* RT_USING_SENSOR_DOUBLE_FLOAT */ - -struct rt_sensor_accuracy -{ - rt_sensor_float_t resolution; /* resolution of sesnor measurement */ - rt_sensor_float_t error; /* error of sesnor measurement */ -}; - -struct rt_sensor_scale -{ - rt_sensor_float_t range_max; /* maximum range of this sensor's value. unit is 'unit' */ - rt_sensor_float_t range_min; /* minimum range of this sensor's value. unit is 'unit' */ -}; - struct rt_sensor_info { - rt_uint8_t type; /* sensor type */ - rt_uint8_t vendor; /* sensors vendor */ - const char *name; /* name of sensor */ + rt_uint8_t type; /* The sensor type */ + rt_uint8_t vendor; /* Vendor of sensors */ + const char *model; /* model name of sensor */ rt_uint8_t unit; /* unit of measurement */ - rt_uint8_t intf_type; /* communication interface type */ - rt_uint16_t mode; /* sensor work mode */ + rt_uint8_t intf_type; /* Communication interface type */ + rt_int32_t range_max; /* maximum range of this sensor's value. unit is 'unit' */ + rt_int32_t range_min; /* minimum range of this sensor's value. unit is 'unit' */ + rt_uint32_t period_min; /* Minimum measurement period,unit:ms. zero = not a constant rate */ rt_uint8_t fifo_max; - rt_sensor_float_t acquire_min; /* minimum acquirement period, unit:ms. zero = not a constant rate */ - struct rt_sensor_accuracy accuracy; /* sensor current measure accuracy */ - struct rt_sensor_scale scale; /* sensor current scale range */ }; struct rt_sensor_intf { - char *dev_name; /* The name of the communication device */ - rt_uint8_t type; /* Communication interface type */ - void *arg; /* Interface argument for the sensor. ex. i2c addr,spi cs,control I/O */ + char *dev_name; /* The name of the communication device */ + rt_uint8_t type; /* Communication interface type */ + void *user_data; /* Private data for the sensor. ex. i2c addr,spi cs,control I/O */ }; struct rt_sensor_config { struct rt_sensor_intf intf; /* sensor interface config */ struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */ + rt_uint8_t mode; /* sensor work mode */ + rt_uint8_t power; /* sensor power mode */ + rt_uint16_t odr; /* sensor out data rate */ + rt_int32_t range; /* sensor range of measurement */ }; 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; -typedef struct rt_sensor_accuracy *rt_sensor_accuracy_t; -typedef struct rt_sensor_scale *rt_sensor_scale_t; struct rt_sensor_device { @@ -320,7 +168,7 @@ struct rt_sensor_device struct rt_sensor_info info; /* The sensor info data */ struct rt_sensor_config config; /* The sensor config data */ - rt_sensor_data_t data_buf; /* The buf of the data received */ + void *data_buf; /* The buf of the data received */ rt_size_t data_len; /* The size of the data received */ const struct rt_sensor_ops *ops; /* The sensor ops */ @@ -341,22 +189,22 @@ struct rt_sensor_module /* 3-axis Data Type */ struct sensor_3_axis { - rt_sensor_float_t x; - rt_sensor_float_t y; - rt_sensor_float_t z; + rt_int32_t x; + rt_int32_t y; + rt_int32_t z; }; /* Blood Pressure Data Type */ struct sensor_bp { - rt_sensor_float_t sbp; /* SBP : systolic pressure */ - rt_sensor_float_t dbp; /* DBP : diastolic pressure */ + rt_int32_t sbp; /* SBP : systolic pressure */ + rt_int32_t dbp; /* DBP : diastolic pressure */ }; struct coordinates { - rt_sensor_float_t longitude; - rt_sensor_float_t latitude; + double longitude; + double latitude; }; struct rt_sensor_data @@ -369,35 +217,35 @@ struct rt_sensor_data struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */ struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */ struct coordinates coord; /* Coordinates unit: degrees */ + rt_int32_t temp; /* Temperature. unit: dCelsius */ + rt_int32_t humi; /* Relative humidity. unit: permillage */ + rt_int32_t baro; /* Pressure. unit: pascal (Pa) */ + rt_int32_t light; /* Light. unit: lux */ + rt_int32_t proximity; /* Distance. unit: centimeters */ + rt_int32_t hr; /* Heart rate. unit: bpm */ + rt_int32_t tvoc; /* TVOC. unit: permillage */ + rt_int32_t noise; /* Noise Loudness. unit: HZ */ + rt_uint32_t step; /* Step sensor. unit: 1 */ + rt_int32_t force; /* Force sensor. unit: mN */ + rt_uint32_t dust; /* Dust sensor. unit: ug/m3 */ + rt_uint32_t eco2; /* eCO2 sensor. unit: ppm */ + rt_uint32_t spo2; /* SpO2 sensor. unit: permillage */ + rt_uint32_t iaq; /* IAQ sensor. unit: 1 */ + rt_uint32_t etoh; /* EtOH sensor. unit: ppm */ struct sensor_bp bp; /* BloodPressure. unit: mmHg */ - rt_sensor_float_t temp; /* Temperature. unit: dCelsius */ - rt_sensor_float_t humi; /* Relative humidity. unit: permillage */ - rt_sensor_float_t baro; /* Pressure. unit: pascal (Pa) */ - rt_sensor_float_t light; /* Light. unit: lux */ - rt_sensor_float_t proximity; /* Distance. unit: centimeters */ - rt_sensor_float_t hr; /* Heart rate. unit: bpm */ - rt_sensor_float_t tvoc; /* TVOC. unit: permillage */ - rt_sensor_float_t noise; /* Noise Loudness. unit: HZ */ - rt_sensor_float_t step; /* Step sensor. unit: 1 */ - rt_sensor_float_t force; /* Force sensor. unit: mN */ - rt_sensor_float_t dust; /* Dust sensor. unit: ug/m3 */ - rt_sensor_float_t eco2; /* eCO2 sensor. unit: ppm */ - rt_sensor_float_t spo2; /* SpO2 sensor. unit: permillage */ - rt_sensor_float_t iaq; /* IAQ sensor. unit: 1 */ - rt_sensor_float_t etoh; /* EtOH sensor. unit: ppm */ } data; }; struct rt_sensor_ops { - rt_ssize_t (*fetch_data)(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len); - rt_err_t (*control)(rt_sensor_t sensor, int cmd, void *arg); + rt_size_t (*fetch_data)(struct rt_sensor_device *sensor, void *buf, rt_size_t len); + rt_err_t (*control)(struct rt_sensor_device *sensor, int cmd, void *arg); }; -int rt_hw_sensor_register(rt_sensor_t sensor, - const char *name, - rt_uint32_t flag, - void *data); +int rt_hw_sensor_register(rt_sensor_t sensor, + const char *name, + rt_uint32_t flag, + void *data); #ifdef __cplusplus } diff --git a/components/drivers/include/drivers/sensor_v2.h b/components/drivers/include/drivers/sensor_v2.h new file mode 100644 index 0000000000..72044a3ee2 --- /dev/null +++ b/components/drivers/include/drivers/sensor_v2.h @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-01-31 flybreak first version + * 2022-12-17 Meco Man re-implement sensor framework + */ + +#ifndef __SENSOR_H__ +#define __SENSOR_H__ + +#include +#include "pin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef RT_USING_RTC +#define rt_sensor_get_ts() time(RT_NULL) /* API for the sensor to get the timestamp */ +#else +#define rt_sensor_get_ts() rt_tick_get() /* API for the sensor to get the timestamp */ +#endif + +#define RT_DEVICE_FLAG_FIFO_RX 0x200 /* Flag to use when the sensor is open by fifo mode */ + +#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_TYPE_NONE (0) +#define RT_SENSOR_TYPE_NONE_STR "None" +#define RT_SENSOR_TYPE_ACCE (1) +#define RT_SENSOR_TYPE_ACCE_STR "Accelerometer" +#define RT_SENSOR_TYPE_GYRO (2) +#define RT_SENSOR_TYPE_GYRO_STR "Gyroscope" +#define RT_SENSOR_TYPE_MAG (3) +#define RT_SENSOR_TYPE_MAG_STR "Magnetometer" +#define RT_SENSOR_TYPE_TEMP (4) +#define RT_SENSOR_TYPE_TEMP_STR "Temperature" +#define RT_SENSOR_TYPE_HUMI (5) +#define RT_SENSOR_TYPE_HUMI_STR "Relative Humidity" +#define RT_SENSOR_TYPE_BARO (6) +#define RT_SENSOR_TYPE_BARO_STR "Barometer" +#define RT_SENSOR_TYPE_LIGHT (7) +#define RT_SENSOR_TYPE_LIGHT_STR "Ambient Light" +#define RT_SENSOR_TYPE_PROXIMITY (8) +#define RT_SENSOR_TYPE_PROXIMITY_STR "Proximity" +#define RT_SENSOR_TYPE_HR (9) +#define RT_SENSOR_TYPE_HR_STR "Heart Rate" +#define RT_SENSOR_TYPE_TVOC (10) +#define RT_SENSOR_TYPE_TVOC_STR "TVOC Level" +#define RT_SENSOR_TYPE_NOISE (11) +#define RT_SENSOR_TYPE_NOISE_STR "Noise Loudness" +#define RT_SENSOR_TYPE_STEP (12) +#define RT_SENSOR_TYPE_STEP_STR "Step" +#define RT_SENSOR_TYPE_FORCE (13) +#define RT_SENSOR_TYPE_FORCE_STR "Force" +#define RT_SENSOR_TYPE_DUST (14) +#define RT_SENSOR_TYPE_DUST_STR "Dust" +#define RT_SENSOR_TYPE_ECO2 (15) +#define RT_SENSOR_TYPE_ECO2_STR "eCO2" +#define RT_SENSOR_TYPE_GNSS (16) +#define RT_SENSOR_TYPE_GNSS_STR "GNSS" +#define RT_SENSOR_TYPE_TOF (17) +#define RT_SENSOR_TYPE_TOF_STR "ToF" +#define RT_SENSOR_TYPE_SPO2 (18) +#define RT_SENSOR_TYPE_SPO2_STR "SpO2" +#define RT_SENSOR_TYPE_IAQ (19) +#define RT_SENSOR_TYPE_IAQ_STR "IAQ" +#define RT_SENSOR_TYPE_ETOH (20) +#define RT_SENSOR_TYPE_ETOH_STR "EtOH" +#define RT_SENSOR_TYPE_BP (21) +#define RT_SENSOR_TYPE_BP_STR "Blood Pressure" +#define RT_SENSOR_TYPE_VOLTAGE (22) +#define RT_SENSOR_TYPE_VOLTAGE_STR "Voltage" +#define RT_SENSOR_TYPE_CURRENT (23) +#define RT_SENSOR_TYPE_CURRENT_STR "Current" + +/* Sensor vendor types */ +#define RT_SENSOR_VENDOR_UNKNOWN (0) +#define RT_SENSOR_VENDOR_UNKNOWN_STR "Unknown" +#define RT_SENSOR_VENDOR_VIRTUAL (1) +#define RT_SENSOR_VENDOR_VIRTUAL_STR "Virtual Sensor" +#define RT_SENSOR_VENDOR_ONCHIP (2) +#define RT_SENSOR_VENDOR_ONCHIP_STR "OnChip" +#define RT_SENSOR_VENDOR_STM (3) +#define RT_SENSOR_VENDOR_STM_STR "STMicroelectronics" +#define RT_SENSOR_VENDOR_BOSCH (4) +#define RT_SENSOR_VENDOR_BOSCH_STR "Bosch" +#define RT_SENSOR_VENDOR_INVENSENSE (5) +#define RT_SENSOR_VENDOR_INVENSENSE_STR "Invensense" +#define RT_SENSOR_VENDOR_SEMTECH (6) +#define RT_SENSOR_VENDOR_SEMTECH_STR "Semtech" +#define RT_SENSOR_VENDOR_GOERTEK (7) +#define RT_SENSOR_VENDOR_GOERTEK_STR "Goertek" +#define RT_SENSOR_VENDOR_MIRAMEMS (8) +#define RT_SENSOR_VENDOR_MIRAMEMS_STR "MiraMEMS" +#define RT_SENSOR_VENDOR_DALLAS (9) +#define RT_SENSOR_VENDOR_DALLAS_STR "Dallas" +#define RT_SENSOR_VENDOR_ASAIR (10) +#define RT_SENSOR_VENDOR_ASAIR_STR "Aosong" +#define RT_SENSOR_VENDOR_SHARP (11) +#define RT_SENSOR_VENDOR_SHARP_STR "Sharp" +#define RT_SENSOR_VENDOR_SENSIRION (12) +#define RT_SENSOR_VENDOR_SENSIRION_STR "Sensirion" +#define RT_SENSOR_VENDOR_TI (13) +#define RT_SENSOR_VENDOR_TI_STR "Texas Instruments" +#define RT_SENSOR_VENDOR_PLANTOWER (14) +#define RT_SENSOR_VENDOR_PLANTOWER_STR "Plantower" +#define RT_SENSOR_VENDOR_AMS (15) +#define RT_SENSOR_VENDOR_AMS_STR "ams-OSRAM AG" +#define RT_SENSOR_VENDOR_MAXIM (16) +#define RT_SENSOR_VENDOR_MAXIM_STR "Maxim Integrated" +#define RT_SENSOR_VENDOR_MELEXIS (17) +#define RT_SENSOR_VENDOR_MELEXIS_STR "Melexis" +#define RT_SENSOR_VENDOR_LSC (18) +#define RT_SENSOR_VENDOR_LSC_STR "Lite On" + +/* Sensor unit types */ +#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_M (5) /* Distance unit: m */ +#define RT_SENSOR_UNIT_M_STR "m" +#define RT_SENSOR_UNIT_CM (6) /* Distance unit: cm */ +#define RT_SENSOR_UNIT_CM_STR "cm" +#define RT_SENSOR_UNIT_MM (7) /* Distance unit: mm */ +#define RT_SENSOR_UNIT_MM_STR "mm" +#define RT_SENSOR_UNIT_PA (8) /* Barometer unit: Pa */ +#define RT_SENSOR_UNIT_PA_STR "Pa" +#define RT_SENSOR_UNIT_MMHG (9) /* Blood Pressure unit: mmHg */ +#define RT_SENSOR_UNIT_MMHG_STR "mmHg" +#define RT_SENSOR_UNIT_PERCENTAGE (10) /* Relative Humidity unit: percentage */ +#define RT_SENSOR_UNIT_PERCENTAGE_STR "%" +#define RT_SENSOR_UNIT_PERMILLAGE (11) /* Relative Humidity unit: permillage */ +#define RT_SENSOR_UNIT_PERMILLAGE_STR "‰" +#define RT_SENSOR_UNIT_CELSIUS (12) /* Temperature unit: Celsius ℃ */ +#define RT_SENSOR_UNIT_CELSIUS_STR "℃" +#define RT_SENSOR_UNIT_FAHRENHEIT (13) /* Temperature unit: Fahrenheit ℉ */ +#define RT_SENSOR_UNIT_FAHRENHEIT_STR "℉" +#define RT_SENSOR_UNIT_KELVIN (14) /* Temperature unit: Kelvin K */ +#define RT_SENSOR_UNIT_KELVIN_STR "K" +#define RT_SENSOR_UNIT_HZ (15) /* Frequency unit: Hz */ +#define RT_SENSOR_UNIT_HZ_STR "Hz" +#define RT_SENSOR_UNIT_V (16) /* Voltage unit: V */ +#define RT_SENSOR_UNIT_V_STR "V" +#define RT_SENSOR_UNIT_MV (17) /* Voltage unit: mV */ +#define RT_SENSOR_UNIT_MV_STR "mV" +#define RT_SENSOR_UNIT_A (18) /* Current unit: A */ +#define RT_SENSOR_UNIT_A_STR "A" +#define RT_SENSOR_UNIT_MA (19) /* Current unit: mA */ +#define RT_SENSOR_UNIT_MA_STR "mA" +#define RT_SENSOR_UNIT_N (20) /* Force unit: N */ +#define RT_SENSOR_UNIT_N_STR "N" +#define RT_SENSOR_UNIT_MN (21) /* Force unit: mN */ +#define RT_SENSOR_UNIT_MN_STR "mN" +#define RT_SENSOR_UNIT_BPM (22) /* Heart rate unit: bpm */ +#define RT_SENSOR_UNIT_BPM_STR "bpm" +#define RT_SENSOR_UNIT_PPM (23) /* Concentration unit: ppm */ +#define RT_SENSOR_UNIT_PPM_STR "ppm" +#define RT_SENSOR_UNIT_PPB (24) /* Concentration unit: ppb */ +#define RT_SENSOR_UNIT_PPB_STR "ppb" +#define RT_SENSOR_UNIT_DMS (25) /* Coordinates unit: DMS */ +#define RT_SENSOR_UNIT_DMS_STR "DMS" +#define RT_SENSOR_UNIT_DD (26) /* Coordinates unit: DD */ +#define RT_SENSOR_UNIT_DD_STR "DD" +#define RT_SENSOR_UNIT_MGM3 (27) /* 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_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" +#define RT_SENSOR_INTF_CAN (1 << 4) +#define RT_SENSOR_INTF_CAN_STR "CAN" +#define RT_SENSOR_INTF_MODBUS (1 << 5) +#define RT_SENSOR_INTF_MODBUS_STR "Modbus" + +/** + * Sensor mode + * rt_uint16_t mode + * 0000 | 0000 | 0000 | 0000 + * unused accuracy power fetch data + */ +#define RT_SENSOR_MODE_ACCURACY_BIT_OFFSET (8) +#define RT_SENSOR_MODE_POWER_BIT_OFFSET (4) +#define RT_SENSOR_MODE_FETCH_BIT_OFFSET (0) + +#define RT_SENSOR_MODE_GET_ACCURACY(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_ACCURACY_BIT_OFFSET) & 0x0F) +#define RT_SENSOR_MODE_GET_POWER(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_POWER_BIT_OFFSET) & 0x0F) +#define RT_SENSOR_MODE_GET_FETCH(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_FETCH_BIT_OFFSET) & 0x0F) + +#define RT_SENSOR_MODE_CLEAR_ACCURACY(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET))) +#define RT_SENSOR_MODE_CLEAR_POWER(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_POWER_BIT_OFFSET))) +#define RT_SENSOR_MODE_CLEAR_FETCH(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_FETCH_BIT_OFFSET))) + +#define RT_SENSOR_MODE_SET_ACCURACY(mode, accuracy_mode) RT_SENSOR_MODE_CLEAR_ACCURACY(mode); (mode |= (accuracy_mode << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET)) +#define RT_SENSOR_MODE_SET_POWER(mode, power_mode) RT_SENSOR_MODE_CLEAR_POWER(mode); (mode |= (power_mode << RT_SENSOR_MODE_POWER_BIT_OFFSET)) +#define RT_SENSOR_MODE_SET_FETCH(mode, fetch_mode) RT_SENSOR_MODE_CLEAR_FETCH(mode); (mode |= (fetch_mode << RT_SENSOR_MODE_FETCH_BIT_OFFSET)) + +/* Sensor mode: accuracy */ +#define RT_SENSOR_MODE_ACCURACY_HIGHEST (0) +#define RT_SENSOR_MODE_ACCURACY_HIGHEST_STR "Accuracy Highest" +#define RT_SENSOR_MODE_ACCURACY_HIGH (1) +#define RT_SENSOR_MODE_ACCURACY_HIGH_STR "Accuracy High" +#define RT_SENSOR_MODE_ACCURACY_MEDIUM (2) +#define RT_SENSOR_MODE_ACCURACY_MEDIUM_STR "Accuracy Medium" +#define RT_SENSOR_MODE_ACCURACY_LOW (3) +#define RT_SENSOR_MODE_ACCURACY_LOW_STR "Accuracy Low" +#define RT_SENSOR_MODE_ACCURACY_LOWEST (4) +#define RT_SENSOR_MODE_ACCURACY_LOWEST_STR "Accuracy Lowest" +#define RT_SENSOR_MODE_ACCURACY_NOTRUST (5) +#define RT_SENSOR_MODE_ACCURACY_NOTRUST_STR "Accuracy No Trust" + +/* Sensor mode: power */ +#define RT_SENSOR_MODE_POWER_HIGHEST (0) +#define RT_SENSOR_MODE_POWER_HIGHEST_STR "Power Highest" +#define RT_SENSOR_MODE_POWER_HIGH (1) +#define RT_SENSOR_MODE_POWER_HIGH_STR "Power High" +#define RT_SENSOR_MODE_POWER_MEDIUM (2) +#define RT_SENSOR_MODE_POWER_MEDIUM_STR "Power Medium" +#define RT_SENSOR_MODE_POWER_LOW (3) +#define RT_SENSOR_MODE_POWER_LOW_STR "Power Low" +#define RT_SENSOR_MODE_POWER_LOWEST (4) +#define RT_SENSOR_MODE_POWER_LOWEST_STR "Power Lowest" +#define RT_SENSOR_MODE_POWER_DOWN (5) +#define RT_SENSOR_MODE_POWER_DOWN_STR "Power Down" + +/* Sensor mode: fetch data */ +#define RT_SENSOR_MODE_FETCH_POLLING (0) /* One shot only read a data */ +#define RT_SENSOR_MODE_FETCH_POLLING_STR "Polling Mode" +#define RT_SENSOR_MODE_FETCH_INT (1) /* TODO: One shot interrupt only read a data */ +#define RT_SENSOR_MODE_FETCH_INT_STR "Interrupt Mode" +#define RT_SENSOR_MODE_FETCH_FIFO (2) /* TODO: One shot interrupt read all fifo data */ +#define RT_SENSOR_MODE_FETCH_FIFO_STR "FIFO Mode" + +/* Sensor control cmd types */ +#define RT_SENSOR_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Sensor) + 0) /* Get device id */ +#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Take a self test */ +#define RT_SENSOR_CTRL_SOFT_RESET (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* soft reset sensor */ +#define RT_SENSOR_CTRL_SET_FETCH_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* set fetch data mode */ +#define RT_SENSOR_CTRL_SET_POWER_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* set power mode */ +#define RT_SENSOR_CTRL_SET_ACCURACY_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* set accuracy mode */ + +#define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */ + +/* sensor floating data type */ +#ifdef RT_USING_SENSOR_DOUBLE_FLOAT +typedef double rt_sensor_float_t; +#else +typedef float rt_sensor_float_t; +#endif /* RT_USING_SENSOR_DOUBLE_FLOAT */ + +struct rt_sensor_accuracy +{ + rt_sensor_float_t resolution; /* resolution of sesnor measurement */ + rt_sensor_float_t error; /* error of sesnor measurement */ +}; + +struct rt_sensor_scale +{ + rt_sensor_float_t range_max; /* maximum range of this sensor's value. unit is 'unit' */ + rt_sensor_float_t range_min; /* minimum range of this sensor's value. unit is 'unit' */ +}; + +struct rt_sensor_info +{ + rt_uint8_t type; /* sensor type */ + rt_uint8_t vendor; /* sensors vendor */ + const char *name; /* name of sensor */ + rt_uint8_t unit; /* unit of measurement */ + rt_uint8_t intf_type; /* communication interface type */ + rt_uint16_t mode; /* sensor work mode */ + rt_uint8_t fifo_max; + rt_sensor_float_t acquire_min; /* minimum acquirement period, unit:ms. zero = not a constant rate */ + struct rt_sensor_accuracy accuracy; /* sensor current measure accuracy */ + struct rt_sensor_scale scale; /* sensor current scale range */ +}; + +struct rt_sensor_intf +{ + char *dev_name; /* The name of the communication device */ + rt_uint8_t type; /* Communication interface type */ + void *arg; /* Interface argument for the sensor. ex. i2c addr,spi cs,control I/O */ +}; + +struct rt_sensor_config +{ + struct rt_sensor_intf intf; /* sensor interface config */ + struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */ +}; + +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; +typedef struct rt_sensor_accuracy *rt_sensor_accuracy_t; +typedef struct rt_sensor_scale *rt_sensor_scale_t; + +struct rt_sensor_device +{ + struct rt_device parent; /* The standard device */ + + struct rt_sensor_info info; /* The sensor info data */ + struct rt_sensor_config config; /* The sensor config data */ + + rt_sensor_data_t data_buf; /* The buf of the data received */ + rt_size_t data_len; /* The size of the data received */ + + const struct rt_sensor_ops *ops; /* The sensor ops */ + + struct rt_sensor_module *module; /* The sensor module */ + + rt_err_t (*irq_handle)(rt_sensor_t sensor); /* Called when an interrupt is generated, registered by the driver */ +}; + +struct rt_sensor_module +{ + rt_mutex_t lock; /* The module lock */ + + rt_sensor_t sen[RT_SENSOR_MODULE_MAX]; /* The module contains a list of sensors */ + rt_uint8_t sen_num; /* Number of sensors contained in the module */ +}; + +/* 3-axis Data Type */ +struct sensor_3_axis +{ + rt_sensor_float_t x; + rt_sensor_float_t y; + rt_sensor_float_t z; +}; + +/* Blood Pressure Data Type */ +struct sensor_bp +{ + rt_sensor_float_t sbp; /* SBP : systolic pressure */ + rt_sensor_float_t dbp; /* DBP : diastolic pressure */ +}; + +struct coordinates +{ + rt_sensor_float_t longitude; + rt_sensor_float_t latitude; +}; + +struct rt_sensor_data +{ + rt_uint32_t timestamp; /* The timestamp when the data was received */ + rt_uint8_t type; /* The sensor type of the data */ + union + { + struct sensor_3_axis acce; /* Accelerometer. unit: mG */ + struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */ + struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */ + struct coordinates coord; /* Coordinates unit: degrees */ + struct sensor_bp bp; /* BloodPressure. unit: mmHg */ + rt_sensor_float_t temp; /* Temperature. unit: dCelsius */ + rt_sensor_float_t humi; /* Relative humidity. unit: permillage */ + rt_sensor_float_t baro; /* Pressure. unit: pascal (Pa) */ + rt_sensor_float_t light; /* Light. unit: lux */ + rt_sensor_float_t proximity; /* Distance. unit: centimeters */ + rt_sensor_float_t hr; /* Heart rate. unit: bpm */ + rt_sensor_float_t tvoc; /* TVOC. unit: permillage */ + rt_sensor_float_t noise; /* Noise Loudness. unit: HZ */ + rt_sensor_float_t step; /* Step sensor. unit: 1 */ + rt_sensor_float_t force; /* Force sensor. unit: mN */ + rt_sensor_float_t dust; /* Dust sensor. unit: ug/m3 */ + rt_sensor_float_t eco2; /* eCO2 sensor. unit: ppm */ + rt_sensor_float_t spo2; /* SpO2 sensor. unit: permillage */ + rt_sensor_float_t iaq; /* IAQ sensor. unit: 1 */ + rt_sensor_float_t etoh; /* EtOH sensor. unit: ppm */ + } data; +}; + +struct rt_sensor_ops +{ + rt_ssize_t (*fetch_data)(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len); + rt_err_t (*control)(rt_sensor_t sensor, int cmd, void *arg); +}; + +int rt_hw_sensor_register(rt_sensor_t sensor, + const char *name, + rt_uint32_t flag, + void *data); + +#ifdef __cplusplus +} +#endif + +#endif /* __SENSOR_H__ */ diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index 47a26238fa..afce028b0e 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -94,7 +94,11 @@ extern "C" { #endif /* RT_USING_PIN */ #ifdef RT_USING_SENSOR +#ifdef RT_USING_SENSOR_V2 +#include "drivers/sensor_v2.h" +#else #include "drivers/sensor.h" +#endif /* RT_USING_SENSOR_V2 */ #endif /* RT_USING_SENSOR */ #ifdef RT_USING_CAN diff --git a/components/drivers/sensor/SConscript b/components/drivers/sensor/SConscript index c25e2fe4b0..4c815c49b8 100644 --- a/components/drivers/sensor/SConscript +++ b/components/drivers/sensor/SConscript @@ -1,14 +1,15 @@ -# SConscript for sensor framework +# RT-Thread building script for bridge +import os from building import * cwd = GetCurrentDir() -src = ['sensor.c'] -CPPPATH = [cwd, cwd + '/../include'] +objs = [] +list = os.listdir(cwd) -if GetDepend('RT_USING_SENSOR_CMD'): - src += ['sensor_cmd.c'] +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) -group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH) - -Return('group') +Return('objs') diff --git a/components/drivers/sensor/v1/SConscript b/components/drivers/sensor/v1/SConscript new file mode 100644 index 0000000000..1aa7831ffe --- /dev/null +++ b/components/drivers/sensor/v1/SConscript @@ -0,0 +1,12 @@ +# SConscript for sensor framework + +from building import * + +src = ['sensor.c'] + +if GetDepend('RT_USING_SENSOR_CMD'): + src += ['sensor_cmd.c'] + +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SENSOR']) + +Return('group') diff --git a/components/drivers/sensor/v1/sensor.c b/components/drivers/sensor/v1/sensor.c new file mode 100644 index 0000000000..cbd149317e --- /dev/null +++ b/components/drivers/sensor/v1/sensor.c @@ -0,0 +1,495 @@ +/* + * 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", + "acce_", /* Accelerometer */ + "gyro_", /* Gyroscope */ + "mag_", /* Magnetometer */ + "temp_", /* Temperature */ + "humi_", /* Relative Humidity */ + "baro_", /* Barometer */ + "li_", /* Ambient light */ + "pr_", /* Proximity */ + "hr_", /* Heart Rate */ + "tvoc_", /* TVOC Level */ + "noi_", /* Noise Loudness */ + "step_", /* Step sensor */ + "forc_", /* Force sensor */ + "dust_", /* Dust sensor */ + "eco2_", /* eCO2 sensor */ + "gnss_", /* GPS/GNSS sensor */ + "tof_", /* TOF sensor */ + "spo2_", /* SpO2 sensor */ + "iaq_", /* IAQ sensor */ + "etoh_", /* EtOH sensor */ + "bp_" /* Blood Pressure */ +}; + +/* Sensor interrupt correlation function */ +/* + * Sensor interrupt handler function + */ +void rt_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++) + { + rt_sensor_cb(sensor->module->sen[i]); + } + } + else + { + rt_sensor_cb(sensor); + } +} + +/* Sensor interrupt initialization function */ +static rt_err_t rt_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; +} + +// local rt_sensor_ops + +static rt_size_t local_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len) +{ + LOG_D("Undefined fetch_data"); + return 0; +} +static rt_err_t local_control(struct rt_sensor_device *sensor, int cmd, void *arg) +{ + LOG_D("Undefined control"); + return RT_ERROR; +} +static struct rt_sensor_ops local_ops = +{ + .fetch_data = local_fetch_data, + .control = local_control +}; + +/* RT-Thread Device Interface */ +static rt_err_t rt_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)(struct rt_sensor_device * 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 */ + rt_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 */ + rt_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 rt_sensor_close(rt_device_t dev) +{ + rt_sensor_t sensor = (rt_sensor_t)dev; + int i; + rt_err_t (*local_ctrl)(struct rt_sensor_device * 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_NULL) + { + 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 rt_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 != RT_NULL) + { + result = sensor->ops->fetch_data(sensor, buf, len); + } + } + + if (sensor->module) + { + rt_mutex_release(sensor->module->lock); + } + + return result; +} + +static rt_err_t rt_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)(struct rt_sensor_device * 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, + rt_sensor_open, + rt_sensor_close, + rt_sensor_read, + RT_NULL, + rt_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 = rt_sensor_open; + device->close = rt_sensor_close; + device->read = rt_sensor_read; + device->write = RT_NULL; + device->control = rt_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("rt_sensor[%s] register err code: %d", device_name, result); + rt_free(device_name); + return result; + } + + LOG_I("rt_sensor[%s] init success", device_name); + rt_free(device_name); + return RT_EOK; +} diff --git a/components/drivers/sensor/v1/sensor_cmd.c b/components/drivers/sensor/v1/sensor_cmd.c new file mode 100644 index 0000000000..0410af4853 --- /dev/null +++ b/components/drivers/sensor/v1/sensor_cmd.c @@ -0,0 +1,516 @@ +/* + * 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:%3d, x:%5d, y:%5d, z:%5d mg, timestamp:%5d", 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:%3d, x:%8d, y:%8d, z:%8d dps, timestamp:%5d", num, sensor_data->data.gyro.x / 1000, sensor_data->data.gyro.y / 1000, sensor_data->data.gyro.z / 1000, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_MAG: + LOG_I("num:%3d, x:%5d, y:%5d, z:%5d mGauss, timestamp:%5d", 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:%3d, lon:%5d, lat:%5d, timestamp:%5d", num, sensor_data->data.coord.longitude, sensor_data->data.coord.latitude, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_TEMP: + LOG_I("num:%3d, temp:%3d.%d C, timestamp:%5d", num, sensor_data->data.temp / 10, (rt_uint32_t)sensor_data->data.temp % 10, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_HUMI: + LOG_I("num:%3d, humi:%3d.%d%%, timestamp:%5d", num, sensor_data->data.humi / 10, sensor_data->data.humi % 10, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_BARO: + LOG_I("num:%3d, press:%5d pa, timestamp:%5d", num, sensor_data->data.baro, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_LIGHT: + LOG_I("num:%3d, light:%5d lux, timestamp:%5d", num, sensor_data->data.light, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_PROXIMITY: + case RT_SENSOR_CLASS_TOF: + LOG_I("num:%3d, distance:%5d, timestamp:%5d", num, sensor_data->data.proximity, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_HR: + LOG_I("num:%3d, heart rate:%5d bpm, timestamp:%5d", num, sensor_data->data.hr, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_TVOC: + LOG_I("num:%3d, tvoc:%5d ppb, timestamp:%5d", num, sensor_data->data.tvoc, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_NOISE: + LOG_I("num:%3d, noise:%5d, timestamp:%5d", num, sensor_data->data.noise, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_STEP: + LOG_I("num:%3d, step:%5d, timestamp:%5d", num, sensor_data->data.step, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_FORCE: + LOG_I("num:%3d, force:%5d, timestamp:%5d", num, sensor_data->data.force, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_DUST: + LOG_I("num:%3d, dust:%5d ug/m3, timestamp:%5d", num, sensor_data->data.dust, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_ECO2: + LOG_I("num:%3d, eco2:%5d ppm, timestamp:%5d", num, sensor_data->data.eco2, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_IAQ: + LOG_I("num:%3d, IAQ:%5d.%d , timestamp:%5d", num, sensor_data->data.iaq / 10, sensor_data->data.iaq % 10, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_ETOH: + LOG_I("num:%3d, EtOH:%5d.%03d ppm, timestamp:%5d", num, sensor_data->data.etoh / 1000, sensor_data->data.etoh % 1000, sensor_data->timestamp); + break; + case RT_SENSOR_CLASS_BP: + LOG_I("num:%3d, bp.sbp:%5d mmHg, bp.dbp:%5d mmHg, timestamp:%5d", num, sensor_data->data.bp.sbp, sensor_data->data.bp.dbp, sensor_data->timestamp); + break; + default: + 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(" sr Set range to var\n"); + rt_kprintf(" sm Set work mode to var\n"); + rt_kprintf(" sp Set power mode to var\n"); + rt_kprintf(" sodr Set output date rate to var\n"); + rt_kprintf(" read [num] Read [num] times sensor\n"); + rt_kprintf(" num 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; + if (dev) + { + rt_device_close(dev); + } + + dev = rt_device_find(argv[2]); + if (dev == RT_NULL) + { + LOG_E("Can't find device:%s", argv[2]); + return; + } + if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) + { + LOG_E("open device failed!"); + return; + } + rt_device_control(dev, RT_SENSOR_CTRL_GET_ID, ®); + LOG_I("device id: 0x%x!", reg); + + } + else if (dev == RT_NULL) + { + LOG_W("Please probe sensor first!"); + return ; + } + else if (!strcmp(argv[1], "sr")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_RANGE, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "sm")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_MODE, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "sp")) + { + rt_device_control(dev, RT_SENSOR_CTRL_SET_POWER, (void *)atoi(argv[2])); + } + else if (!strcmp(argv[1], "sodr")) + { + 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/sensor/v2/SConscript b/components/drivers/sensor/v2/SConscript new file mode 100644 index 0000000000..872b2cebaf --- /dev/null +++ b/components/drivers/sensor/v2/SConscript @@ -0,0 +1,12 @@ +# SConscript for sensor framework + +from building import * + +src = ['sensor_v2.c'] + +if GetDepend('RT_USING_SENSOR_CMD'): + src += ['sensor_cmd.c'] + +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SENSOR_V2']) + +Return('group') diff --git a/components/drivers/sensor/sensor_cmd.c b/components/drivers/sensor/v2/sensor_cmd.c similarity index 99% rename from components/drivers/sensor/sensor_cmd.c rename to components/drivers/sensor/v2/sensor_cmd.c index 4b094fb18d..e278f349de 100644 --- a/components/drivers/sensor/sensor_cmd.c +++ b/components/drivers/sensor/v2/sensor_cmd.c @@ -11,9 +11,9 @@ * 2022-12-17 Meco Man re-implement sensor framework */ -#include +#include -#define DBG_TAG "sensor.cmd" +#define DBG_TAG "sensor_v2.cmd" #define DBG_LVL DBG_INFO #include diff --git a/components/drivers/sensor/sensor.c b/components/drivers/sensor/v2/sensor_v2.c similarity index 99% rename from components/drivers/sensor/sensor.c rename to components/drivers/sensor/v2/sensor_v2.c index e100cc27c3..a35089ad34 100644 --- a/components/drivers/sensor/sensor.c +++ b/components/drivers/sensor/v2/sensor_v2.c @@ -10,9 +10,9 @@ * 2022-12-17 Meco Man re-implement sensor framework */ -#include +#include -#define DBG_TAG "sensor" +#define DBG_TAG "sensor_v2" #define DBG_LVL DBG_INFO #include