This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4060f6ba80b2ad1aa8c8c4f435b97d8b2e03b1c5 Author: Eren Terzioglu <[email protected]> AuthorDate: Fri Oct 4 18:56:36 2024 +0300 esp32[s2|s3]: Add UORB support for internal temperature sensor --- arch/xtensa/src/common/espressif/Kconfig | 13 ++ .../src/common/espressif/esp_temperature_sensor.c | 240 ++++++++++++++++++--- .../configs/temperature_sensor/defconfig | 49 +++++ .../configs/temperature_sensor/defconfig | 51 +++++ 4 files changed, 326 insertions(+), 27 deletions(-) diff --git a/arch/xtensa/src/common/espressif/Kconfig b/arch/xtensa/src/common/espressif/Kconfig index 361f4c221e..ff4e838e0e 100644 --- a/arch/xtensa/src/common/espressif/Kconfig +++ b/arch/xtensa/src/common/espressif/Kconfig @@ -31,10 +31,23 @@ config ESPRESSIF_SPIFLASH menu "Internal Temperature Sensor Configuration" depends on ESPRESSIF_TEMP +config ESPRESSIF_TEMP_UORB + bool "Internal Temperature Sensor UORB Interface" + default n + ---help--- + Enables work with the UORB or Character Device interface. + If not set, the Character Device is used by default. + config ESPRESSIF_TEMP_PATH string "Internal Temperature Sensor Path" + depends on !ESPRESSIF_TEMP_UORB default "dev/temp" +config ESPRESSIF_TEMP_PATH_DEVNO + int "Internal Temperature Sensor Path Device Number" + depends on ESPRESSIF_TEMP_UORB + default 0 + endmenu # ESPRESSIF_TEMP config ESPRESSIF_HAVE_OTA_PARTITION diff --git a/arch/xtensa/src/common/espressif/esp_temperature_sensor.c b/arch/xtensa/src/common/espressif/esp_temperature_sensor.c index 2e05975f85..e07655a84d 100644 --- a/arch/xtensa/src/common/espressif/esp_temperature_sensor.c +++ b/arch/xtensa/src/common/espressif/esp_temperature_sensor.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <nuttx/nuttx.h> #ifdef CONFIG_ESPRESSIF_TEMP #include <stdio.h> @@ -42,6 +43,9 @@ #include <nuttx/can/can.h> #include <nuttx/signal.h> #include <nuttx/arch.h> +#ifdef CONFIG_ESPRESSIF_TEMP_UORB +#include <nuttx/sensors/sensor.h> +#endif #include "xtensa.h" #include "espressif/esp_temperature_sensor.h" @@ -62,6 +66,8 @@ * Pre-processor Definitions ****************************************************************************/ +#define ESP_TEMP_MIN_INTERVAL 30000 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -78,14 +84,19 @@ enum esp_tempstate_e struct esp_temp_priv_s { +#ifndef CONFIG_ESPRESSIF_TEMP_UORB const struct file_operations *ops; /* Standard file operations */ +#endif const temperature_sensor_attribute_t *tsens_attribute; /* Attribute struct of the common layer */ struct esp_temp_sensor_config_t cfg; /* Configuration struct of the common layer */ temperature_sensor_clk_src_t clk_src; /* Clock source to use */ int module; /* Peripheral module */ int refs; /* Reference count */ mutex_t lock; /* Mutual exclusion mutex */ - +#ifdef CONFIG_ESPRESSIF_TEMP_UORB + struct sensor_lowerhalf_s lower; /* Lower half sensor driver. */ + uint32_t interval; /* Sensor acquisition interval. */ +#endif /* Temperature sensor work state (see enum esp_tempstate_e) */ volatile enum esp_tempstate_e tempstate; @@ -109,9 +120,25 @@ static void esp_temp_sensor_register(struct esp_temp_priv_s *priv); static int esp_temperature_sensor_install(struct esp_temp_priv_s *priv, struct esp_temp_sensor_config_t cfg); static void esp_temperature_sensor_uninstall(struct esp_temp_priv_s *priv); -static int esp_temperature_sensor_get_celsius(struct file *filep, - char *buffer, - size_t buflen); +static int esp_temperature_sensor_get_celsius(struct esp_temp_priv_s *priv, + int *buffer); +#ifdef CONFIG_ESPRESSIF_TEMP_UORB +static int esp_temperature_sensor_set_interval( + struct sensor_lowerhalf_s *lower, + struct file *filep, + uint32_t *period_us); +static int esp_temperature_sensor_activate( + struct sensor_lowerhalf_s *lower, + struct file *filep, + bool enable); +static int esp_temperature_sensor_fetch(struct sensor_lowerhalf_s *lower, + struct file *filep, + char *buffer, size_t buflen); +#else +static int esp_temperature_sensor_read(struct file *filep, + char *buffer, + size_t buflen); +#endif /* CONFIG_ESPRESSIF_TEMP_UORB */ /**************************************************************************** * Private Data @@ -119,17 +146,28 @@ static int esp_temperature_sensor_get_celsius(struct file *filep, static float g_delta_t = NAN; +#ifndef CONFIG_ESPRESSIF_TEMP_UORB static const struct file_operations g_esp_temp_sensor_fops = { NULL, /* open */ NULL, /* close */ - esp_temperature_sensor_get_celsius, /* read */ + esp_temperature_sensor_read, /* read */ NULL, /* write */ }; +#else +static const struct sensor_ops_s g_esp_temp_sensor_sops = +{ + .activate = esp_temperature_sensor_activate, /* Enable/disable sensor. */ + .fetch = esp_temperature_sensor_fetch, + .set_interval = esp_temperature_sensor_set_interval, /* Set output data period. */ +}; +#endif /* CONFIG_ESPRESSIF_TEMP_UORB */ struct esp_temp_priv_s esp_temp_priv = { +#ifndef CONFIG_ESPRESSIF_TEMP_UORB .ops = &g_esp_temp_sensor_fops, +#endif .tsens_attribute = NULL, .cfg = { @@ -139,6 +177,13 @@ struct esp_temp_priv_s esp_temp_priv = .module = PERIPH_TEMPSENSOR_MODULE, .refs = 0, .lock = NXMUTEX_INITIALIZER, +#ifdef CONFIG_ESPRESSIF_TEMP_UORB + .lower = + { + 0 + }, + .interval = ESP_TEMP_MIN_INTERVAL, +#endif .tempstate = 0, }; @@ -229,7 +274,7 @@ static int temperature_sensor_choose_best_range(struct esp_temp_priv_s *priv) if (priv->tsens_attribute == NULL) { - syslog(LOG_ERR, "Out of testing range"); + snerr("Out of testing range"); return ERROR; } @@ -255,12 +300,12 @@ static int temperature_sensor_read_delta_t(void) { if (esp_efuse_rtc_calib_get_tsens_val(&g_delta_t) != OK) { - syslog(LOG_WARNING, "Calibration failed"); + snwarn("Calibration failed"); g_delta_t = 0; return ERROR; } - syslog(LOG_INFO, "delta_T = %f", g_delta_t); + sninfo("delta_T = %f", g_delta_t); return OK; } @@ -339,8 +384,7 @@ static void esp_temperature_sensor_disable(struct esp_temp_priv_s *priv) * Name: esp_temp_sensor_register * * Description: - * This function registers the internal temperature sensor to - * /dev/temp driver. + * This function registers the internal temperature sensor. * * Input Parameters: * priv - Pointer to the internal driver state structure. @@ -352,8 +396,12 @@ static void esp_temperature_sensor_disable(struct esp_temp_priv_s *priv) static void esp_temp_sensor_register(struct esp_temp_priv_s *priv) { +#ifndef CONFIG_ESPRESSIF_TEMP_UORB register_driver(CONFIG_ESPRESSIF_TEMP_PATH, &g_esp_temp_sensor_fops, 0666, priv); +#else + sensor_register(&priv->lower, CONFIG_ESPRESSIF_TEMP_PATH_DEVNO); +#endif /* CONFIG_ESPRESSIF_TEMP_UORB */ } /**************************************************************************** @@ -381,7 +429,7 @@ static int esp_temperature_sensor_install(struct esp_temp_priv_s *priv, ret = temperature_sensor_attribute_table_sort(); if (ret < 0) { - syslog(LOG_ERR, "Table sort failed"); + snerr("Table sort failed"); goto err; } @@ -390,7 +438,7 @@ static int esp_temperature_sensor_install(struct esp_temp_priv_s *priv, ret = temperature_sensor_choose_best_range(priv); if (ret < 0) { - syslog(LOG_ERR, "Cannot select the correct range"); + snerr("Cannot select the correct range"); goto err; } @@ -434,40 +482,36 @@ static void esp_temperature_sensor_uninstall(struct esp_temp_priv_s *priv) * Read temperature sensor data that is converted to degrees Celsius. * * Input Parameters: - * filep - The pointer of file, represents each user using the sensor + * priv - Pointer to the internal driver state structure. * buffer - Buffer to save temperature sensor value in degrees Celsius - * buflen - Length of the buffer * * Returned Value: * Returns OK on success; a negated errno value on failure * ****************************************************************************/ -static int esp_temperature_sensor_get_celsius(struct file *filep, - char *buffer, - size_t buflen) +static int esp_temperature_sensor_get_celsius(struct esp_temp_priv_s *priv, + int *buffer) { uint32_t tsens_out; - struct inode *inode = filep->f_inode; - struct esp_temp_priv_s *priv = inode->i_private; - int *out = (int *)buffer; + float *out = (float *)buffer; nxmutex_lock(&priv->lock); if (priv == NULL) { - syslog(LOG_WARNING, "Temperature sensor has not been installed"); + snwarn("Temperature sensor has not been installed"); goto err; } esp_temperature_sensor_enable(priv); if (priv->tempstate != TEMP_SENSOR_ENABLE) { - syslog(LOG_WARNING, "Temperature sensor not enabled"); + snwarn("Temperature sensor not enabled"); goto err; } tsens_out = temperature_sensor_ll_get_raw_value(); - syslog(LOG_INFO, "Temperature sensor raw value: %d", tsens_out); + sninfo("Temperature sensor raw value: %ld", (long int)tsens_out); *out = temperature_sensor_parse_raw_value(tsens_out, priv->tsens_attribute->offset); @@ -476,7 +520,7 @@ static int esp_temperature_sensor_get_celsius(struct file *filep, if (*out < priv->tsens_attribute->range_min || *out > priv->tsens_attribute->range_max) { - syslog(LOG_WARNING, "Temperature sensor value is out of range"); + snwarn("Temperature sensor value is out of range"); goto err; } @@ -488,6 +532,142 @@ err: return ERROR; } +#ifndef CONFIG_ESPRESSIF_TEMP_UORB +/**************************************************************************** + * Name: esp_temperature_sensor_read + * + * Description: + * Read temperature sensor data that is converted to degrees Celsius. + * + * Input Parameters: + * filep - The pointer of file, represents each user using the sensor + * buffer - Buffer to save temperature sensor value in degrees Celsius + * buflen - Length of the buffer + * + * Returned Value: + * Returns OK on success; a negated errno value on failure + * + ****************************************************************************/ + +static int esp_temperature_sensor_read(struct file *filep, + char *buffer, + size_t buflen) +{ + struct inode *inode = filep->f_inode; + struct esp_temp_priv_s *priv = inode->i_private; + + return esp_temperature_sensor_get_celsius(priv, (int *)buffer); +} +#else +static int esp_temperature_sensor_fetch(struct sensor_lowerhalf_s *lower, + struct file *filep, + char *buffer, size_t buflen) +{ + struct esp_temp_priv_s *priv = + container_of (lower, struct esp_temp_priv_s, lower); + + int ret; + struct sensor_temp temp; + float val = 0.0; + + if (buflen != sizeof(temp)) + { + return -EINVAL; + } + + esp_temperature_sensor_get_celsius(priv, (int *)&val); + sninfo("temp = %d\n", (int)val); + + temp.timestamp = sensor_get_timestamp(); + temp.temperature = (int)val; + + memcpy(buffer, &temp, sizeof(temp)); + + return buflen; +} + +/**************************************************************************** + * Name: esp_temperature_sensor_set_interval + * + * Description: + * Set the sensor output data period in microseconds for a given sensor. + * If *period_us < min_delay it will be replaced by min_delay. + * + * Input Parameters: + * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using the sensor. + * period_us - The time between report data, in us. It may by overwrite + * by lower half driver. + * + * Returned Value: + * Return OK(0) if the driver was success; A negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +static int esp_temperature_sensor_set_interval( + struct sensor_lowerhalf_s *lower, + struct file *filep, + uint32_t *period_us) +{ + struct esp_temp_priv_s *priv = (struct esp_temp_priv_s *)lower; + + if (*period_us < ESP_TEMP_MIN_INTERVAL) + { + priv->interval = ESP_TEMP_MIN_INTERVAL; + *period_us = priv->interval; + } + else + { + priv->interval = *period_us; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_temperature_sensor_activate + * + * Description: + * Enable or disable sensor device. when enable sensor, sensor will + * work in current mode(if not set, use default mode). when disable + * sensor, it will disable sense path and stop convert. + * + * Input Parameters: + * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using the sensor. + * enable - true(enable) and false(disable). + * + * Returned Value: + * Return OK(0) if the driver was success; A negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +static int esp_temperature_sensor_activate( + struct sensor_lowerhalf_s *lower, + struct file *filep, + bool enable) +{ + struct esp_temp_priv_s *priv = (struct esp_temp_priv_s *)lower; + + /* Set accel output data rate. */ + + if (enable) + { + esp_temperature_sensor_enable(priv); + } + else + { + /* Set suspend mode to sensors. */ + + esp_temperature_sensor_disable(priv); + } + + return OK; +} +#endif /* CONFIG_ESPRESSIF_TEMP_UORB */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -517,7 +697,7 @@ int esp_temperature_sensor_initialize(struct esp_temp_sensor_config_t cfg) if (priv->refs++ != 0) { nxmutex_unlock(&priv->lock); - syslog(LOG_INFO, "Temperature sensor previously initialized." + sninfo("Temperature sensor previously initialized." "Handler: %p\n", priv); } else @@ -525,16 +705,22 @@ int esp_temperature_sensor_initialize(struct esp_temp_sensor_config_t cfg) ret = esp_temperature_sensor_install(priv, cfg); if (ret != OK) { - syslog(LOG_ERR, "Temperature sensor initialization failed!"); + snerr("Temperature sensor initialization failed!"); nxmutex_unlock(&priv->lock); return ret; } } +#ifdef CONFIG_ESPRESSIF_TEMP_UORB + priv->lower.ops = &g_esp_temp_sensor_sops; + priv->lower.type = SENSOR_TYPE_AMBIENT_TEMPERATURE; + priv->interval = ESP_TEMP_MIN_INTERVAL; +#endif + esp_temp_sensor_register(priv); nxmutex_unlock(&priv->lock); - syslog(LOG_INFO, "Temperature sensor initialized! Handler: %p\n", priv); + sninfo("Temperature sensor initialized! Handler: %p\n", priv); return OK; } diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/temperature_sensor/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/temperature_sensor/defconfig new file mode 100644 index 0000000000..71d3b8df34 --- /dev/null +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/temperature_sensor/defconfig @@ -0,0 +1,49 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s2-saola-1" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S2_SAOLA_1=y +CONFIG_ARCH_CHIP="esp32s2" +CONFIG_ARCH_CHIP_ESP32S2=y +CONFIG_ARCH_CHIP_ESP32S2WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_ESP32S2_UART0=y +CONFIG_ESPRESSIF_TEMP=y +CONFIG_ESPRESSIF_TEMP_UORB=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SENSORS=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_SENSORTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/temperature_sensor/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/temperature_sensor/defconfig new file mode 100644 index 0000000000..c5de3f3e2c --- /dev/null +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/temperature_sensor/defconfig @@ -0,0 +1,51 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32s3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32s3" +CONFIG_ARCH_CHIP_ESP32S3=y +CONFIG_ARCH_CHIP_ESP32S3WROOM1N4=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ESP32S3_UART0=y +CONFIG_ESPRESSIF_TEMP=y +CONFIG_ESPRESSIF_TEMP_UORB=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SENSORS=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_SENSORTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y
