You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "kywwilson11 (via GitHub)" <gi...@apache.org> on 2025/07/18 12:57:49 UTC
[PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS). Missing HW Trigger Support (No LP Timer Support) [nuttx]
kywwilson11 opened a new pull request, #16746:
URL: https://github.com/apache/nuttx/pull/16746
## Summary
This commit adds full support for the on‑die digital temperature sensor (DTS) in the STM32H5 family:
- **Driver**: Implements `stm32h5_dts` low‑level driver (`chip/stm32_dts.[ch]`) with:
- Software trigger, CFGR1 configuration (sample time, reference clock, trigger source)
- Raw → frequency → °C conversion using factory calibration registers
- Interrupt support for end‑of‑measurement, high/low threshold (both synchronous and LSE‑only asynchronous wakeup)
- `get_info()` updated with realistic sensor parameters
- Currently no support for HW Triggers. set_interval not developed. Need LP Timer support first.
- **Kconfig**: New options under `Drivers → Sensors → STM32H5 DTS`:
- `CONFIG_STM32H5_DTS` to enable the driver
- `CONFIG_STM32H5_DTS_REFCLK_LSE` to select LSE vs PCLK
- `CONFIG_STM32H5_DTS_SMP_TIME` for TS1_SMP_TIME
- Interrupt‑enable flags for ITEF/ITLF/ITHF and AITEF/AITLF/AITHF
- **Build**: Updated `Kconfig` and `Make.defs` so the peripheral clock (APB1HENR DTSEN) and driver files are included when enabled
- **uORB**: Exposes `/dev/uorb/sensor_tempN` via the NuttX sensors framework
## Impact
- **New functionality**: Enables temperature sensing on with DTS STM32H5‑based boards (e.g., NUCLEO‑H563ZI)
- **Build-time**: Zero impact unless `CONFIG_STM32H5_DTS=y`
- **Runtime**: Negligible idle overhead; active only during measurements or threshold events
- **Compatibility**: No changes to other families; coexists with existing sensors drivers
## Testing
Modes: PCLK and LSE
Interupts: Did not test hardware trigger mode. But enabled interrupts while in SW trigger mode. isr was accessed and fetch was not affected.
Samples: Tested number of samples. Verified with debugger.
Wrote a very simple external app to test. See below.
Not shown here but I heated and cooled the chip and watched changes. Below output is with 125MHz PCLK1.
Example Output:
```console
NuttShell (NSH) NuttX-12.10.0
nsh> dts
Time: 2550000 µs Temp: 29.39 °C
nsh> dts
Time: 3840000 µs Temp: 29.39 °C
nsh> dts
Time: 4950000 µs Temp: 29.39 °C
nsh> dts
Time: 6060000 µs Temp: 29.26 °C
nsh> dts
Time: 7740000 µs Temp: 29.39 °C
nsh>
```
Kconfig options:
<img width="723" height="318" alt="dts_kconfig" src="https://github.com/user-attachments/assets/3c91eb84-5c2c-476a-95e3-e1a3b6635590" />
External Test Application:
```
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <nuttx/sensors/ioctl.h>
#include <nuttx/sensors/sensor.h>
#include <nuttx/uorb.h>
int main(void)
{
int usfd = open("/dev/usensor", O_RDWR);
if (usfd < 0)
{
perror("open /dev/usensor");
return 1;
}
struct sensor_reginfo_s reginfo =
{
.path = "/dev/uorb/sensor_temp", /* note: no trailing ‘0’ */
.esize = sizeof(struct sensor_temp),
.nbuffer= 1
};
if (ioctl(usfd, SNIOC_REGISTER, (unsigned long)®info) < 0)
{
}
close(usfd);
int fd = open("/dev/uorb/sensor_temp0", O_RDONLY | O_NONBLOCK);
if (fd < 0) { perror("open"); return 1; }
struct sensor_temp report;
for (int i = 0; i < 1; i++)
{
if (read(fd, &report, sizeof(report)) != sizeof(report))
{
perror("read");
break;
}
printf("Time: %llu µs Temp: %.2f °C\n",
(unsigned long long)report.timestamp,
report.temperature);
}
close(fd);
return 0;
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "raiden00pl (via GitHub)" <gi...@apache.org>.
raiden00pl commented on code in PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#discussion_r2217220869
##########
arch/arm/src/stm32h5/stm32_dts.h:
##########
@@ -28,7 +28,49 @@
****************************************************************************/
#include <nuttx/config.h>
-#include "chip.h"
-#include "hardware/stm32_dts.h"
+#include <nuttx/sensors/sensor.h> /* For struct sensor_lowerhalf_s */
+#include <nuttx/sensors/ioctl.h> /* SNIOC_* if needed */
+#include <nuttx/uorb.h> /* SENSOR_TYPE_AMBIENT_TEMPERATURE */
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct dts_cal_s
+{
+ uint16_t fmt0;
+ uint16_t ramp;
+ float t0;
+};
+
+struct dts_cfg_s
Review Comment:
```suggestion
struct stm32_dts_cfg_s
```
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
Review Comment:
```suggestion
* calibration to complete (TS1_RDY = 1).
*
****************************************************************************/
```
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,115 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+menu "DTS Configuration"
+ depends on STM32H5_DTS
Review Comment:
`depends on` under menu is common in stm32 ports. What's the point of changing this?
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,108 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+if STM32H5_DTS
+menu "DTS Configuration"
+
Review Comment:
```suggestion
menu "DTS Configuration"
depends on STM32H5_DTS
```
stm32 ports always use `depends on` under `menu`
##########
boards/arm/stm32h5/nucleo-h563zi/src/stm32_dts.c:
##########
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * boards/arm/stm32h5/nucleo-h563zi/src/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "stm32.h"
+
+#if defined(CONFIG_STM32H5_DTS)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
Review Comment:
can we remove all empty sections?
##########
boards/arm/stm32h5/nucleo-h563zi/src/stm32_dts.c:
##########
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * boards/arm/stm32h5/nucleo-h563zi/src/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "stm32.h"
+
+#if defined(CONFIG_STM32H5_DTS)
Review Comment:
dont need this. The build system will take care of it
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ g_dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ g_dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ g_dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ g_dts_cfg.lse = true;
+#else
+ g_dts_cfg.lse = false;
+#endif
+ g_dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ g_dts_cfg.samples = (g_dts_cfg.samples == 0) ? 1 : g_dts_cfg.samples;
+
+ g_dts_cfg.clk_frequency = (g_dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen)
+{
+ struct sensor_temp report;
+ uint32_t raw;
+ float fmeas;
+
+ /* Wait for sensor to be ready before starting */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 1 to initiate one measurement */
+
+ modifyreg32(STM32_DTS_CFGR1, 0, DTS_CFGR1_TS1_START);
+
+ /* Wait for TS1_RDY → 1: conversion complete */
Review Comment:
```suggestion
/* Wait for TS1_RDY -> 1: conversion complete */
```
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -359,6 +359,14 @@ config STM32H5_DMA2
select STM32H5_DMA
select ARCH_DMA
+config STM32H5_DTS
+ bool "DTS"
+ default n
+ help
Review Comment:
```suggestion
---help---
```
##########
arch/arm/src/stm32h5/stm32_dts.h:
##########
@@ -28,7 +28,49 @@
****************************************************************************/
#include <nuttx/config.h>
-#include "chip.h"
-#include "hardware/stm32_dts.h"
+#include <nuttx/sensors/sensor.h> /* For struct sensor_lowerhalf_s */
+#include <nuttx/sensors/ioctl.h> /* SNIOC_* if needed */
+#include <nuttx/uorb.h> /* SENSOR_TYPE_AMBIENT_TEMPERATURE */
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct dts_cal_s
Review Comment:
```suggestion
struct stm32_dts_cal_s
```
stm32 private types always use `stm32_` prefix so it would be good to do the same here
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ g_dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ g_dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ g_dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ g_dts_cfg.lse = true;
+#else
+ g_dts_cfg.lse = false;
+#endif
+ g_dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ g_dts_cfg.samples = (g_dts_cfg.samples == 0) ? 1 : g_dts_cfg.samples;
+
+ g_dts_cfg.clk_frequency = (g_dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
Review Comment:
```suggestion
* Perform one software‐triggered temperature measurement
*
****************************************************************************/
```
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ g_dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ g_dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ g_dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ g_dts_cfg.lse = true;
+#else
+ g_dts_cfg.lse = false;
+#endif
+ g_dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ g_dts_cfg.samples = (g_dts_cfg.samples == 0) ? 1 : g_dts_cfg.samples;
+
+ g_dts_cfg.clk_frequency = (g_dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen)
+{
+ struct sensor_temp report;
+ uint32_t raw;
+ float fmeas;
+
+ /* Wait for sensor to be ready before starting */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 1 to initiate one measurement */
+
+ modifyreg32(STM32_DTS_CFGR1, 0, DTS_CFGR1_TS1_START);
+
+ /* Wait for TS1_RDY → 1: conversion complete */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 0 to stop measurements */
+
+ modifyreg32(STM32_DTS_CFGR1, DTS_CFGR1_TS1_START, 0);
+
+ raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+
+ /* Convert raw → frequency */
Review Comment:
```suggestion
/* Convert raw -> frequency */
```
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ g_dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ g_dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ g_dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ g_dts_cfg.lse = true;
+#else
+ g_dts_cfg.lse = false;
+#endif
+ g_dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ g_dts_cfg.samples = (g_dts_cfg.samples == 0) ? 1 : g_dts_cfg.samples;
+
+ g_dts_cfg.clk_frequency = (g_dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen)
+{
+ struct sensor_temp report;
+ uint32_t raw;
+ float fmeas;
+
+ /* Wait for sensor to be ready before starting */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 1 to initiate one measurement */
+
+ modifyreg32(STM32_DTS_CFGR1, 0, DTS_CFGR1_TS1_START);
+
+ /* Wait for TS1_RDY → 1: conversion complete */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 0 to stop measurements */
+
+ modifyreg32(STM32_DTS_CFGR1, DTS_CFGR1_TS1_START, 0);
+
+ raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+
+ /* Convert raw → frequency */
+
+ if (g_dts_cfg.lse)
+ {
+ /* (LSE) mode: count FM pulses in (samp) LSE cycles */
+
+ fmeas = (float)raw * (float)STM32_LSE_FREQUENCY
+ / (float)(g_dts_cfg.samples);
+ }
+ else
+ {
+ /* (PCLK) mode: count PCLK ticks in (samp) FM(T) cycles */
+
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(g_dts_cfg.samples)
+ / (float)raw;
+ }
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = g_dts_cal.t0 +
+ ((fmeas - ((float)g_dts_cal.fmt0 * 100.0f)) /
+ (float)g_dts_cal.ramp);
+
+ if (buflen < sizeof(report))
+ {
+ return -EINVAL;
+ }
+
+ memcpy(buffer, &report, sizeof(report));
+ return sizeof(report);
+}
+#endif
+
+static void stm32_dts_handle_result(struct sensor_lowerhalf_s *lower)
+{
+ struct sensor_temp report;
+ uint32_t raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+ float fmeas;
+
+ /* Convert raw ==> freq */
+
+ if (g_dts_cfg.lse)
+ {
+ fmeas = (float)raw * STM32_LSE_FREQUENCY / (float)(g_dts_cfg.samples);
+ }
+ else
+ {
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(g_dts_cfg.samples)
+ / (float)raw;
+ }
+
+ /* Build the report */
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = g_dts_cal.t0 +
+ ((fmeas - ((float)g_dts_cal.fmt0 * 100.0f)) /
+ (float)g_dts_cal.ramp);
+
+ /* Push into NuttX sensor framework */
+
+ lower->push_event(lower->priv, &report, sizeof(report));
+}
+
+/****************************************************************************
+ * Name: stm32_dts_set_interval
+ ****************************************************************************/
+
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_get_info
+ ****************************************************************************/
+
+static int stm32_dts_get_info(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info)
+{
+ /* One factory‐calibrated internal sensor on the STM32H5:
+ *
+ * Power: ≈0.5 mW typical when measuring (≈150 uA@3.3 V)
+ * Max range: –40 C…+125 C
+ * Resolution: ≈0.15 C => approximation with 15 samples at 125 MHz
+ * Min delay: ≈200 us per conversion (default sample time)
+ * Max delay: 0 (one‑shot, not batched)
+ * FIFO events 1 (no hardware FIFO)
+ */
+
+ DEBUGASSERT(info);
+ info->version = 1;
+ info->power = 0.5f;
+ info->max_range = 165.0f;
+ info->resolution = 0.15f;
+ info->min_delay = 200;
+ info->max_delay = 0;
+ info->fifo_reserved_event_count = 1;
+ info->fifo_max_event_count = 1;
+ strlcpy(info->name, "STM32H5 DTS", SENSOR_INFO_NAME_SIZE);
+ strlcpy(info->vendor, "STMicro", SENSOR_INFO_NAME_SIZE);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_isr
+ *
+ * Description:
+ ****************************************************************************/
+
+static int stm32_dts_isr(int irq, void *context, void *arg)
+{
+ struct sensor_lowerhalf_s *lower = (struct sensor_lowerhalf_s *)arg;
+ uint32_t sr = getreg32(STM32_DTS_SR);
+ bool pushed = false;
+
+ /* End‑of‑measurement interrupt? */
+
+ if (sr & DTS_SR_TS1_ITEF)
+ {
+ putreg32(DTS_ICIFR_CITEF, STM32_DTS_ICIFR);
+ stm32_dts_handle_result(lower);
+ pushed = true;
+ }
+
+ /* Low‑threshold crossed? */
+
+ if (sr & DTS_SR_TS1_ITLF)
+ {
+ putreg32(DTS_ICIFR_CITLF, STM32_DTS_ICIFR);
+ if (!pushed)
+ {
+ stm32_dts_handle_result(lower);
+ }
+
+ pushed = true;
+ }
+
+ /* High‑threshold crossed? */
+
+ if (sr & DTS_SR_TS1_ITHF)
+ {
+ putreg32(DTS_ICIFR_CITHF, STM32_DTS_ICIFR);
+ if (!pushed)
+ {
+ stm32_dts_handle_result(lower);
+ }
+ }
+
+ lower->notify_event(lower->priv);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_register
+ *
+ ****************************************************************************/
Review Comment:
```suggestion
****************************************************************************/
```
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s g_dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s g_dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ g_dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ g_dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ g_dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ g_dts_cfg.lse = true;
+#else
+ g_dts_cfg.lse = false;
+#endif
+ g_dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ g_dts_cfg.samples = (g_dts_cfg.samples == 0) ? 1 : g_dts_cfg.samples;
+
+ g_dts_cfg.clk_frequency = (g_dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen)
+{
+ struct sensor_temp report;
+ uint32_t raw;
+ float fmeas;
+
+ /* Wait for sensor to be ready before starting */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 1 to initiate one measurement */
+
+ modifyreg32(STM32_DTS_CFGR1, 0, DTS_CFGR1_TS1_START);
+
+ /* Wait for TS1_RDY → 1: conversion complete */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 0 to stop measurements */
+
+ modifyreg32(STM32_DTS_CFGR1, DTS_CFGR1_TS1_START, 0);
+
+ raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+
+ /* Convert raw → frequency */
+
+ if (g_dts_cfg.lse)
+ {
+ /* (LSE) mode: count FM pulses in (samp) LSE cycles */
+
+ fmeas = (float)raw * (float)STM32_LSE_FREQUENCY
+ / (float)(g_dts_cfg.samples);
+ }
+ else
+ {
+ /* (PCLK) mode: count PCLK ticks in (samp) FM(T) cycles */
+
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(g_dts_cfg.samples)
+ / (float)raw;
+ }
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = g_dts_cal.t0 +
+ ((fmeas - ((float)g_dts_cal.fmt0 * 100.0f)) /
+ (float)g_dts_cal.ramp);
+
+ if (buflen < sizeof(report))
+ {
+ return -EINVAL;
+ }
+
+ memcpy(buffer, &report, sizeof(report));
+ return sizeof(report);
+}
+#endif
+
+static void stm32_dts_handle_result(struct sensor_lowerhalf_s *lower)
+{
+ struct sensor_temp report;
+ uint32_t raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+ float fmeas;
+
+ /* Convert raw ==> freq */
+
+ if (g_dts_cfg.lse)
+ {
+ fmeas = (float)raw * STM32_LSE_FREQUENCY / (float)(g_dts_cfg.samples);
+ }
+ else
+ {
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(g_dts_cfg.samples)
+ / (float)raw;
+ }
+
+ /* Build the report */
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = g_dts_cal.t0 +
+ ((fmeas - ((float)g_dts_cal.fmt0 * 100.0f)) /
+ (float)g_dts_cal.ramp);
+
+ /* Push into NuttX sensor framework */
+
+ lower->push_event(lower->priv, &report, sizeof(report));
+}
+
+/****************************************************************************
+ * Name: stm32_dts_set_interval
+ ****************************************************************************/
+
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_get_info
+ ****************************************************************************/
+
+static int stm32_dts_get_info(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info)
+{
+ /* One factory‐calibrated internal sensor on the STM32H5:
+ *
+ * Power: ≈0.5 mW typical when measuring (≈150 uA@3.3 V)
+ * Max range: –40 C…+125 C
+ * Resolution: ≈0.15 C => approximation with 15 samples at 125 MHz
+ * Min delay: ≈200 us per conversion (default sample time)
+ * Max delay: 0 (one‑shot, not batched)
+ * FIFO events 1 (no hardware FIFO)
+ */
+
+ DEBUGASSERT(info);
+ info->version = 1;
+ info->power = 0.5f;
+ info->max_range = 165.0f;
+ info->resolution = 0.15f;
+ info->min_delay = 200;
+ info->max_delay = 0;
+ info->fifo_reserved_event_count = 1;
+ info->fifo_max_event_count = 1;
+ strlcpy(info->name, "STM32H5 DTS", SENSOR_INFO_NAME_SIZE);
+ strlcpy(info->vendor, "STMicro", SENSOR_INFO_NAME_SIZE);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_isr
+ *
+ * Description:
+ ****************************************************************************/
Review Comment:
```suggestion
****************************************************************************/
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 merged PR #16746:
URL: https://github.com/apache/nuttx/pull/16746
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#discussion_r2216169173
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,115 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+menu "DTS Configuration"
+ depends on STM32H5_DTS
Review Comment:
change to
```
if STM32H5_DTS
menu "DTS Configuration"
...
endif
```
and remove ALL `depends on STM32H5_DTS`.
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,115 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+menu "DTS Configuration"
+ depends on STM32H5_DTS
+
+config STM32H5_DTS_REFCLK_LSE
+ bool "Use LSE (32.768 kHz crystal) as DTS reference clock"
+ depends on STM32H5_DTS
+ default n
+ help
+ Select the low‑speed external (LSE) oscillator as the reference clock
+ for the DTS. When enabled, DTS_CFGR1.REFCLK_SEL=1 and the driver will
+ measure FM(T) pulses over N LSE cycles.
+
+ If disabled, the DTS will use the APB‑bus clock (PCLK) as the reference
+ (REFCLK_SEL=0) and you must supply a valid HSREF_CLK_DIV to keep the
+ calibration prescaler ≤ 1 MHz.
+
+config STM32H5_DTS_SMP_TIME
+ int "DTS sampling time (TS1_SMP_TIME[3:0])"
+ default 1
+ range 1 15
+ depends on STM32H5_DTS
+ help
+ Number of reference‑clock cycles (PCLK or LSE) counted per
+ DTS measurement. Valid range 1 (1 cycle) through 15 (15 cycles).
+
+config STM32H5_DTS_TRIGGER
+ int "DTS hardware trigger source (TS1_INTRIG_SEL[3:0])"
+ default 0
+ depends on STM32H5_DTS
+ help
+ If non‑zero, DTS will start measurements on the rising edge of
+ the selected hardware line. Values match RM0481 Table 275:
+ 0=Software Trigger, 1=LPTIM1_CH1,
+ 2=LPTIM2_CH1, 3=LPTIM3_CH1, 4=EXTI13, 5-15 are reserved.
+
+config STM32H5_DTS_LOW_THRESHOLD
+ int "DTS low‑threshold (°C)"
+ default 0
+ depends on STM32H5_DTS
+ help
+ The temperature (in whole °C) below which the DTS window comparator will
+ assert the low‑threshold flag (TS1_ITLF). To disable, set equal to 0.
+
+config STM32H5_DTS_HIGH_THRESHOLD
+ int "DTS high‑threshold (°C)"
+ default 100
+ depends on STM32H5_DTS
+ help
+ The temperature (in whole °C) above which the DTS window comparator will
+ assert the high‑threshold flag (TS1_ITHF). Must be >= LOW_THRESHOLD.
+
+config STM32H5_DTS_ITEN_ITEF
+ bool "Enable DTS end‑of‑measurement interrupt (TS1_ITEF)"
Review Comment:
please change ALL indent from space tab
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
Review Comment:
align
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ dts_cfg.lse = true;
+#else
+ dts_cfg.lse = false;
+#endif
+ dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ dts_cfg.samples = (dts_cfg.samples == 0) ? 1 : dts_cfg.samples;
+
+ dts_cfg.clk_frequency = (dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, (void *)lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen)
+{
+ struct sensor_temp report;
+ uint32_t raw;
+ float fmeas;
+
+ /* Wait for sensor to be ready before starting */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 1 to initiate one measurement */
+
+ modifyreg32(STM32_DTS_CFGR1, 0, DTS_CFGR1_TS1_START);
+
+ /* Wait for TS1_RDY → 1: conversion complete */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ /* Set START = 0 to stop measurements */
+
+ modifyreg32(STM32_DTS_CFGR1, DTS_CFGR1_TS1_START, 0);
+
+ raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+
+ /* Convert raw → frequency */
+
+ if (dts_cfg.lse)
+ {
+ /* (LSE) mode: count FM pulses in (samp) LSE cycles */
+
+ fmeas = (float)raw * (float)STM32_LSE_FREQUENCY
+ / (float)(dts_cfg.samples);
+ }
+ else
+ {
+ /* (PCLK) mode: count PCLK ticks in (samp) FM(T) cycles */
+
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(dts_cfg.samples)
+ / (float)raw;
+ }
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = dts_cal.t0 +
+ ((fmeas - ((float)dts_cal.fmt0 * 100.0f)) /
+ (float)dts_cal.ramp);
+
+ if (buflen < sizeof(report))
+ {
+ return -EINVAL;
+ }
+
+ memcpy(buffer, &report, sizeof(report));
+ return sizeof(report);
+}
+#endif
+
+static void stm32_dts_handle_result(struct sensor_lowerhalf_s *lower)
+{
+ struct sensor_temp report;
+ uint32_t raw = getreg32(STM32_DTS_DR) & DTS_DR_TS1_MFREQ_MASK;
+ float fmeas;
+
+ /* Convert raw ==> freq */
+
+ if (dts_cfg.lse)
+ {
+ fmeas = (float)raw * STM32_LSE_FREQUENCY / (float)(dts_cfg.samples);
+ }
+ else
+ {
+ fmeas = (float)STM32_PCLK1_FREQUENCY * (float)(dts_cfg.samples)
+ / (float)raw;
+ }
+
+ /* Build the report */
+
+ report.timestamp = sensor_get_timestamp();
+ report.temperature = dts_cal.t0 +
+ ((fmeas - ((float)dts_cal.fmt0 * 100.0f)) /
+ (float)dts_cal.ramp);
+
+ /* Push into NuttX sensor framework */
+
+ lower->push_event(lower->priv, &report, sizeof(report));
+}
+
+/****************************************************************************
+ * Name: stm32_dts_set_interval
+ ****************************************************************************/
+
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dts_get_info
+ ****************************************************************************/
+
+static int stm32_dts_get_info(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info)
+{
+ /* One factory‐calibrated internal sensor on the STM32H5:
+ *
+ * Power: ≈0.5 mW typical when measuring (≈150 uA@3.3 V)
+ * Max range: –40 C…+125 C
+ * Resolution: ≈0.15 C => approximation with 15 samples at 125 MHz
+ * Min delay: ≈200 us per conversion (default sample time)
+ * Max delay: 0 (one‑shot, not batched)
+ * FIFO events 1 (no hardware FIFO)
+ */
+
+ DEBUGASSERT(info);
+ info->version = 1;
+ info->power = 0.5f;
+ info->max_range = 165.0f;
+ info->resolution = 0.15f;
+ info->min_delay = 200;
+ info->max_delay = 0;
+ info->fifo_reserved_event_count = 1;
+ info->fifo_max_event_count = 1;
+ strlcpy(info->name, "STM32H5 DTS", SENSOR_INFO_NAME_SIZE);
Review Comment:
```suggestion
strlcpy(info->name, "STM32H5 DTS", SENSOR_INFO_NAME_SIZE);
```
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ dts_cfg.lse = true;
+#else
+ dts_cfg.lse = false;
+#endif
+ dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ dts_cfg.samples = (dts_cfg.samples == 0) ? 1 : dts_cfg.samples;
+
+ dts_cfg.clk_frequency = (dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, (void *)lower);
+ up_enable_irq(STM32_IRQ_DTS);
+ }
+ else
+ {
+ /* Disable block‑level IRQ, NVIC, clock */
+
+ putreg32(0, STM32_DTS_ITENR);
+ up_disable_irq(STM32_IRQ_DTS);
+ modifyreg32(STM32_RCC_APB1HENR, RCC_APB1HENR_DTSEN, 0);
+ }
+
+ return OK;
+}
+
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+/****************************************************************************
+ * Name: stm32_dts_fetch
+ *
+ * Description:
+ * Perform one software‐triggered temperature measurement
+ ****************************************************************************/
+
+static ssize_t stm32_dts_fetch(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
Review Comment:
align too
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s dts_cal =
Review Comment:
add g_ prefix for ALL global variables
##########
arch/arm/src/stm32h5/stm32_dts.c:
##########
@@ -0,0 +1,424 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_dts.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/sensors/sensor.h>
+#include <nuttx/uorb.h>
+#include <arch/board/board.h>
+
+#include "stm32_rcc.h"
+#include "hardware/stm32_dts.h"
+#include "stm32_dts.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_dts_activate (struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable);
+static int stm32_dts_set_interval(struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ uint32_t *period_us);
+static ssize_t stm32_dts_fetch (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ char *buffer, size_t buflen);
+static int stm32_dts_get_info (struct sensor_lowerhalf_s *lower,
+ struct file *filep,
+ struct sensor_device_info_s *info);
+static int stm32_dts_isr (int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_STM32H5_DTS_TRIGGER != 0
+# error "Hardware triggers not implemented. Need LP Timers first."
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct dts_cal_s dts_cal =
+{
+ .fmt0 = 0,
+ .ramp = 0,
+ .t0 = 0.0,
+};
+
+static struct dts_cfg_s dts_cfg =
+{
+ .samples = 1,
+ .lse = false,
+ .clk_frequency = 0,
+};
+
+static struct sensor_lowerhalf_s g_dts_lower =
+{
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .nbuffer = 1,
+ .ops = NULL, /* bound in register() */
+ .persist = false,
+};
+
+static const struct sensor_ops_s g_dts_ops =
+{
+ .open = NULL, /* no per‑open activation */
+ .close = NULL,
+ .activate = stm32_dts_activate,
+ .set_interval = stm32_dts_set_interval,
+ .batch = NULL,
+#if CONFIG_STM32H5_DTS_TRIGGER == 0
+ .fetch = stm32_dts_fetch,
+#else
+ .fetch = NULL,
+#endif
+ .selftest = NULL,
+ .set_calibvalue = NULL,
+ .calibrate = NULL,
+ .get_info = stm32_dts_get_info,
+ .control = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dts_activate
+ *
+ * Description:
+ * Enable or disable the DTS block and its clock. Configure CFGR1 for
+ * sample time, reference clock, and trigger mode. Wait for the initial
+ * calibration to complete (TS1_RDY = 1).
+ ****************************************************************************/
+
+static int stm32_dts_activate(struct sensor_lowerhalf_s *lower,
+ struct file *filep, bool enable)
+{
+ uint32_t t0valr1;
+ uint8_t t0valr1_t0;
+ uint32_t regval = 0;
+
+ if (enable)
+ {
+ modifyreg32(STM32_RCC_APB1HENR, 0, RCC_APB1HENR_DTSEN);
+
+ /* Compute PCLK prescaler ≤ 1MHz */
+
+ uint32_t div = (STM32_PCLK1_FREQUENCY + 1000000 - 1) / 1000000;
+ if (div > 127) div = 127;
+ else if (div == 0) div = 1;
+
+ /* Configure CFGR1: enable block, sample time, ref‑clk */
+
+ uint32_t cfgr1 =
+ DTS_CFGR1_TS1_EN
+ | DTS_CFGR1_TS1_SMP_TIME(CONFIG_STM32H5_DTS_SMP_TIME)
+#if !defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ | DTS_CFGR1_HSREF_CLK_DIV_RATIO(div)
+#else
+ | DTS_CFGR1_REFCLK_SEL
+#endif
+ | DTS_CFGR1_TS1_INTRIG(CONFIG_STM32H5_DTS_TRIGGER);
+
+ putreg32(cfgr1, STM32_DTS_CFGR1);
+
+ /* Wait for initial calibration (TS1_RDY=1) */
+
+ while (!(getreg32(STM32_DTS_SR) & DTS_SR_TS1_RDY));
+
+ t0valr1 = getreg32(STM32_DTS_T0VALR1);
+ dts_cal.fmt0 = (t0valr1
+ & DTS_T0VALR1_TS1_FMT0_MASK) >> DTS_T0VALR1_TS1_FMT0_SHIFT;
+ dts_cal.ramp = (getreg32(STM32_DTS_RAMPVALR)
+ & DTS_RAMPVALR_TS1_RAMP_COEFF_MASK)
+ >> DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT;
+ t0valr1_t0 = (t0valr1
+ & DTS_T0VALR1_TS1_T0_MASK) >> DTS_T0VALR1_TS1_T0_SHIFT;
+
+ dts_cal.t0 = (t0valr1_t0 == 0) ? 30.0f : 130.0f;
+
+#if defined(CONFIG_STM32H5_DTS_REFCLK_LSE)
+ dts_cfg.lse = true;
+#else
+ dts_cfg.lse = false;
+#endif
+ dts_cfg.samples = ((cfgr1 & DTS_CFGR1_TS1_SMP_TIME_MASK) >>
+ DTS_CFGR1_TS1_SMP_TIME_SHIFT);
+ dts_cfg.samples = (dts_cfg.samples == 0) ? 1 : dts_cfg.samples;
+
+ dts_cfg.clk_frequency = (dts_cfg.lse) ? STM32_LSE_FREQUENCY :
+ STM32_PCLK1_FREQUENCY;
+
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITEF
+ regval |= DTS_ITENR_ITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITLF
+ regval |= DTS_ITENR_ITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_ITEN_ITHF
+ regval |= DTS_ITENR_ITHEN;
+#endif
+
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITEF
+ regval |= DTS_ITENR_AITEEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITLF
+ regval |= DTS_ITENR_AITLEN;
+#endif
+#ifdef CONFIG_STM32H5_DTS_AITEN_AITHF
+ regval |= DTS_ITENR_AITHEN;
+#endif
+ putreg32(regval, STM32_DTS_ITENR);
+ irq_attach(STM32_IRQ_DTS, stm32_dts_isr, (void *)lower);
Review Comment:
```suggestion
irq_attach(STM32_IRQ_DTS, stm32_dts_isr, lower);
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "kywwilson11 (via GitHub)" <gi...@apache.org>.
kywwilson11 commented on PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#issuecomment-3090011023
> @kywwilson11 please follow the PR standard to make it easier to categorize it in the next release: arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS)
>
> Is it possible to use the existing test sensor application (nuttx-apps/system/sensortest) ?
>
> If sensortest doesn't work with it, please include this example application for testing to avoid hidden feature. Please also update the STM32H5 Documentation/ to include this feature.
My apologies. I will review the PR guidelines before my next pull request.
I also tried sensortest and it worked. Added output to the pull request. I was initially using the type sensor_type_ambient_temperature, which isn't supported by sensortest (I don't think). But sensor_type_temperature is actually more appropriate, so sensortest works. Thanks for the suggestion.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#discussion_r2219902284
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,115 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+menu "DTS Configuration"
+ depends on STM32H5_DTS
Review Comment:
since every option add the dependence on STM32H5_DTS, one pair of if/endif could guard all related options
##########
arch/arm/src/stm32h5/Kconfig:
##########
@@ -625,6 +633,115 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
+menu "DTS Configuration"
+ depends on STM32H5_DTS
Review Comment:
since every option add the dependence on STM32H5_DTS, but one pair of if/endif could guard all related options
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "acassis (via GitHub)" <gi...@apache.org>.
acassis commented on PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#issuecomment-3089791591
@kywwilson11 please follow the PR standard to make it easier to categorize it in the next release:
arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS)
Is it possible to use the existing test sensor application (nuttx-apps/system/sensortest) ?
If sensortest doesn't work with it, please include this example application for testing to avoid hidden feature. Please also update the STM32H5 Documentation/ to include this feature.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#issuecomment-3090008909
@kywwilson11 please squash your change into one patch.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#issuecomment-3090061184
> > @kywwilson11 please follow the PR standard to make it easier to categorize it in the next release: arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS)
> > Is it possible to use the existing test sensor application (nuttx-apps/system/sensortest) ?
> > If sensortest doesn't work with it, please include this example application for testing to avoid hidden feature. Please also update the STM32H5 Documentation/ to include this feature.
>
> My apologies. I will review the PR guidelines before my next pull request.
>
> I also tried sensortest and it worked. Added output to the pull request. I was initially using the type sensor_type_ambient_temperature, which isn't supported by sensortest (I don't think). But sensor_type_temperature is actually more appropriate, so sensortest works. Thanks for the suggestion.
sensortest may need update since many physical sensor types were added recently.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS) [nuttx]
Posted by "kywwilson11 (via GitHub)" <gi...@apache.org>.
kywwilson11 commented on PR #16746:
URL: https://github.com/apache/nuttx/pull/16746#issuecomment-3104943119
@acassis - I updated the documentation for the STM32H5 to add support for the DTS and for the Nucleo-H563ZI to add info about a new config, dts (nucleo-h563zi:dts). The new config sets up the dts and includes sensortest. The documentation gives an example command line.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org