arch/arm/stm32h5: Initial Driver for STM32H5 Digital Temperature Sensor (DTS)
Build Documentation / build-html (push) Has been cancelled

- Committing initial code for DTS. Missing ISR. Works for PCLK1. Cannot get to work for LSE.
- Pushing everything. Working with LSE now.
- Many fixes. Fixed interrupt setting. Added data structures.
- Changed interrupt handling. Removed FARs. Added Kconfig options for selecting interrupts.
- Updated info and formatting.
- Formatting fixes.
- Formatting.
- Changed iten to regval.
- Removed Triggger
- Formatting fixes per Pull request.
- Changed private_types to have stm32_ prefix. Used depends on for DTS Kconfig Menu. Fixed formatting per PR.
- Fixed spacing of function prototypes.
- Fixed indent on line
- Added documentation for STM32H5 and Nucleo-H563ZI regarding DTS. Also added GPDMA support to STM32H5 documentation (previous PR). Made stm32_dts.c more modular. stm32_dts_activate is now much more readable. Added comments/descriptions to private functions. Lastly, added a nucleo-h563zi:dts configuration.
This commit is contained in:
kywwilson11
2025-07-17 09:50:55 -05:00
committed by Xiang Xiao
parent b5ef0871d9
commit cbd033ae90
15 changed files with 904 additions and 18 deletions
@@ -145,6 +145,13 @@ usbnsh:
This configuration provides a basic NuttShell through the USB User interface.
dts:
--------
This configuration configures the digital temperature sensor (DTS)
at /dev/uorb/sensor_temp0 and provides the test application
sensortest. E.g. sensortest -n 10 temp0
References
===========
@@ -35,8 +35,10 @@ Peripheral Support Notes
========== ======= =====
ADC Yes
ETH Yes
DTS Yes Software trigger only.
FLASH Yes Hardware defines only.
FDCAN Yes
GPDMA Yes
GPIO Yes
I2C Yes
ICACHE Yes
@@ -59,11 +61,9 @@ DBG No
DCACHE No
DCMI No
DLYB No
DTS No
EXTI No
FMAC No
FSMC No
GPDMA No
GTZC No
HASH No
I3C No
+109
View File
@@ -359,6 +359,14 @@ config STM32H5_DMA2
select STM32H5_DMA
select ARCH_DMA
config STM32H5_DTS
bool "DTS"
default n
---help---
Enable support for the ondie digital temperature sensor (DTS)
built into STM32H5 devices. When enabled, the driver will register
a `/dev/sensor_tempX` device using the common NuttX sensor framework.
config STM32H5_ETHMAC
bool "Ethernet MAC"
default n
@@ -625,6 +633,107 @@ config STM32H5_USBFS
endmenu # STM32H5 Peripheral Selection
menu "DTS Configuration"
depends on STM32H5_DTS
config STM32H5_DTS_REFCLK_LSE
bool "Use LSE (32.768kHz crystal) as DTS reference clock"
default n
---help---
Select the lowspeed 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 APBbus clock (PCLK) as the reference
(REFCLK_SEL=0) and you must supply a valid HSREF_CLK_DIV to keep the
calibration prescaler ≤ 1MHz.
config STM32H5_DTS_SMP_TIME
int "DTS sampling time (TS1_SMP_TIME[3:0])"
default 1
range 1 15
---help---
Number of referenceclock 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
---help---
If nonzero, 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 lowthreshold (°C)"
default 0
---help---
The temperature (in whole °C) below which the DTS window comparator will
assert the lowthreshold flag (TS1_ITLF). To disable, set equal to 0.
config STM32H5_DTS_HIGH_THRESHOLD
int "DTS highthreshold (°C)"
default 100
---help---
The temperature (in whole °C) above which the DTS window comparator will
assert the highthreshold flag (TS1_ITHF). Must be >= LOW_THRESHOLD.
config STM32H5_DTS_ITEN_ITEF
bool "Enable DTS endofmeasurement interrupt (TS1_ITEF)"
default y
---help---
Enable the synchronous “end of measurement” interrupt for the
digital temperature sensor. When set, the driver will attach
and unmask TS1_ITEF and will call your ISR on every fresh sample.
config STM32H5_DTS_ITEN_ITLF
bool "Enable DTS lowthreshold interrupt (TS1_ITLF)"
default n
---help---
Enable the synchronous “low threshold crossed” interrupt for the
digital temperature sensor. When set, the driver will unmask
TS1_ITLF so you can get notified whenever the measured value
drops below your programmed lowthreshold.
config STM32H5_DTS_ITEN_ITHF
bool "Enable DTS highthreshold interrupt (TS1_ITHF)"
default n
---help---
Enable the synchronous “high threshold crossed” interrupt for the
digital temperature sensor. When set, the driver will unmask
TS1_ITHF so you can get notified whenever the measured value
exceeds your programmed highthreshold.
config STM32H5_DTS_AITEN_AITEF
bool "Enable DTS asynchronous endofmeasurement interrupt (TS1_AITEF)"
depends on STM32H5_DTS_REFCLK_LSE
default n
---help---
Enable the asynchronous endofmeasurement interrupt. This will
set TS1_AITEEN in DTS_ITENR and cause an _asynchronous_ wakeup
event when a conversion completes (in Stop/Sleep modes).
config STM32H5_DTS_AITEN_AITLF
bool "Enable DTS asynchronous lowthreshold interrupt (TS1_AITLF)"
depends on STM32H5_DTS_REFCLK_LSE
default n
---help---
Enable the asynchronous lowthreshold comparator interrupt. This
will set TS1_AITLEN in DTS_ITENR and generate a wakeup event
when the measurement drops below your low threshold.
config STM32H5_DTS_AITEN_AITHF
bool "Enable DTS asynchronous highthreshold interrupt (TS1_AITHF)"
depends on STM32H5_DTS_REFCLK_LSE
default n
---help---
Enable the asynchronous highthreshold comparator interrupt. This
will set TS1_AITHEN in DTS_ITENR and generate a wakeup event
when the measurement exceeds your high threshold.
endmenu # DTS Configuration
config STM32H5_FLASH_PREFETCH
bool "Enable FLASH Pre-fetch"
default y
+4
View File
@@ -92,6 +92,10 @@ ifeq ($(CONFIG_STM32H5_DMA),y)
CHIP_CSRCS += stm32_dma.c
endif
ifeq ($(CONFIG_STM32H5_DTS),y)
CHIP_CSRCS += stm32_dts.c
endif
# Required chip type specific files
ifeq ($(CONFIG_STM32H5_STM32H5XXXX),y)
+8 -5
View File
@@ -71,6 +71,8 @@
# define DTS_CFGR1_TS1_INTRIG_SEL_LPTIM2_CH1 (0x2 << DTS_CFGR1_TS1_INTRIG_SEL_SHIFT)
# define DTS_CFGR1_TS1_INTRIG_SEL_LPTIM3_CH1 (0x3 << DTS_CFGR1_TS1_INTRIG_SEL_SHIFT)
# define DTS_CFGR1_TS1_INTRIG_SEL_EXTI13 (0x4 << DTS_CFGR1_TS1_INTRIG_SEL_SHIFT)
#define DTS_CFGR1_TS1_INTRIG(n) \
(((n) << DTS_CFGR1_TS1_INTRIG_SEL_SHIFT) & DTS_CFGR1_TS1_INTRIG_SEL_MASK)
#define DTS_CFGR1_TS1_SMP_TIME_SHIFT (16) /* Bits 16-19: Sampling time */
#define DTS_CFGR1_TS1_SMP_TIME_MASK (0xf << DTS_CFGR1_TS1_SMP_TIME_SHIFT)
@@ -86,26 +88,26 @@
/* Temperature sensor T0 value register 1 */
#define DTS_T0VALR1_TS1_FMT0_SHIFT (0) /* Engineering value for frequency at T0 */
#define DTS_T0VALR1_TS1_FMT0_MASK (0xff << DTS_T0VALR1_TS1_FMT0_SHIFT)
#define DTS_T0VALR1_TS1_FMT0_MASK (0xffff << DTS_T0VALR1_TS1_FMT0_SHIFT)
#define DTS_T0VALR1_TS1_T0_SHIFT (16) /* Engineering value of T0 */
#define DTS_T0VALR1_TS1_T0_MASK (0b11 << DTS_T0VALR1_TS1_T0_SHIFT)
/* Temperature sensor ramp value register */
#define DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT (0) /* Engineering value of ramp coefficient */
#define DTS_RAMPVALR_TS1_RAMP_COEFF_MASK (0xff << DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT)
#define DTS_RAMPVALR_TS1_RAMP_COEFF_MASK (0xffff << DTS_RAMPVALR_TS1_RAMP_COEFF_SHIFT)
/* Temperature sensor interrupt threshold register 1 */
#define DTS_ITR1_TS1_LITTHD_SHIFT (0) /* High interrupt threshold */
#define DTS_ITR1_TS1_LITTHD_MASK (0xff << DTS_ITR1_TS1_LITTHD_SHIFT)
#define DTS_ITR1_TS1_LITTHD_MASK (0xffff << DTS_ITR1_TS1_LITTHD_SHIFT)
#define DTS_ITR1_TS1_HITTHD_SHIFT (16) /* Low interrupt threshold */
#define DTS_ITR1_TS1_HITTHD_MASK (0xff << DTS_ITR1_TS1_HITTHD_SHIFT)
#define DTS_ITR1_TS1_HITTHD_MASK (0xffff << DTS_ITR1_TS1_HITTHD_SHIFT)
/* Temperature sensor data register */
#define DTS_DR_TS1_MFREQ_SHIFT (0)
#define DTS_DR_TS1_MFREQ_MASK (0xff << DTS_DR_TS1_MFREQ_SHIFT)
#define DTS_DR_TS1_MFREQ_MASK (0xffff << DTS_DR_TS1_MFREQ_SHIFT)
/* Temperature sensor status register */
@@ -134,6 +136,7 @@
#define DTS_ICIFR_CAITEF (1 << 4) /* Asynchronous interrupt clear flag: end of measurement */
#define DTS_ICIFR_CAITLF (1 << 5) /* Asynchronous interrupt clear flag: low threshold */
#define DTS_ICIFR_CAITHF (1 << 6) /* Asynchronous interrupt clear flag: high threshold */
#define DTS_ICIFR_ALL (0x77) /* All interrupts */
/* Temperature sensor option register */
@@ -264,13 +264,13 @@
# define RCC_CFGR2_HPRE_SYSCLKd256 (14 << RCC_CFGR2_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */
# define RCC_CFGR2_HPRE_SYSCLKd512 (15 << RCC_CFGR2_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */
#define RCC_CFGR2_PPRE1_SHIFT (0) /* Bits 6-4: PPRE1 Prescaler */
#define RCC_CFGR2_PPRE1_SHIFT (4) /* Bits 6-4: PPRE1 Prescaler */
#define RCC_CFGR2_PPRE1_MASK (0x7 << RCC_CFGR2_PPRE1_SHIFT)
# define RCC_CFGR2_PPRE1_HCLK1 (0 << RCC_CFGR2_PPRE1_SHIFT) /* 0xx: HCLK1 not divided */
# define RCC_CFGR2_PPRE1_HCLK1d2 (4 << RCC_CFGR2_PPRE1_SHIFT) /* 1000: HCLK1 divided by 2 */
# define RCC_CFGR2_PPRE1_HCLK1d4 (5 << RCC_CFGR2_PPRE1_SHIFT) /* 1001: HCLK1 divided by 4 */
# define RCC_CFGR2_PPRE1_HCLK1d8 (6 << RCC_CFGR2_PPRE1_SHIFT) /* 1010: HCLK1 divided by 8 */
# define RCC_CFGR2_PPRE1_HCLK1d16 (7 << RCC_CFGR2_PPRE1_SHIFT) /* 1011: HCLK1 divided by 16 */
# define RCC_CFGR2_PPRE1_HCLK1d2 (4 << RCC_CFGR2_PPRE1_SHIFT) /* 100: HCLK1 divided by 2 */
# define RCC_CFGR2_PPRE1_HCLK1d4 (5 << RCC_CFGR2_PPRE1_SHIFT) /* 101: HCLK1 divided by 4 */
# define RCC_CFGR2_PPRE1_HCLK1d8 (6 << RCC_CFGR2_PPRE1_SHIFT) /* 110: HCLK1 divided by 8 */
# define RCC_CFGR2_PPRE1_HCLK1d16 (7 << RCC_CFGR2_PPRE1_SHIFT) /* 111: HCLK1 divided by 16 */
#define RCC_CFGR2_PPRE2_SHIFT (8) /* Bits 10-8: PPRE2 Prescaler */
#define RCC_CFGR2_PPRE2_MASK (0x7 << RCC_CFGR2_PPRE2_SHIFT)
+1
View File
@@ -39,6 +39,7 @@
#include "chip.h"
#include "stm32_adc.h"
#include "stm32_dbgmcu.h"
#include "stm32_dts.h"
#include "stm32_flash.h"
#include "stm32_gpio.h"
#include "stm32_i2c.h"
File diff suppressed because it is too large Load Diff
+45 -3
View File
@@ -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 */
#endif /* __ARCH_ARM_SRC_STM32H5_STM32_DTS_H */
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Types
****************************************************************************/
struct stm32_dts_cal_s
{
uint16_t fmt0;
uint16_t ramp;
float t0;
};
struct stm32_dts_cfg_s
{
uint8_t samples;
bool lse;
uint32_t clk_frequency;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
int stm32h5_dts_register(int devno);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32H5_STM32_DTS_H */
@@ -0,0 +1,55 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="nucleo-h563zi"
CONFIG_ARCH_BOARD_NUCLEO_H563ZI=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32h5"
CONFIG_ARCH_CHIP_STM32H563ZI=y
CONFIG_ARCH_CHIP_STM32H5=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV8M_STACKCHECK=y
CONFIG_BOARD_LOOPSPERMSEC=9251
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_LINE_MAX=64
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=655360
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SENSORS=y
CONFIG_STACK_COLORATION=y
CONFIG_STM32H5_DTS=y
CONFIG_STM32H5_DTS_SMP_TIME=15
CONFIG_STM32H5_USART3=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SENSORTEST=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_UORB=y
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USENSOR=y
@@ -172,8 +172,8 @@
/* Configure the APB1 prescaler */
#define STM32_RCC_CFGR2_PPRE1 RCC_CFGR2_PPRE1_HCLK1 /* PCLK1 = HCLK / 1 */
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / 1)
#define STM32_RCC_CFGR2_PPRE1 RCC_CFGR2_PPRE1_HCLK1d2 /* PCLK1 = HCLK / 2 */
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
#define STM32_APB1_TIM2_CLKIN (STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM3_CLKIN (STM32_PCLK1_FREQUENCY)
@@ -199,7 +199,7 @@
/* Configure the APB3 prescaler */
#define STM32_RCC_CFGR2_PPRE3 RCC_CFGR2_PPRE3_HCLK1 /* PCLK2 = HCLK / 1 */
#define STM32_RCC_CFGR2_PPRE3 RCC_CFGR2_PPRE3_HCLK1 /* PCLK3 = HCLK / 1 */
#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY / 1)
#define STM32_APB3_LPTIM1_CLKIN (STM32_PCLK3_FREQUENCY)
@@ -43,4 +43,8 @@ ifeq ($(CONFIG_ADC),y)
CSRCS += stm32_adc.c
endif
ifeq ($(CONFIG_STM32H5_DTS),y)
CSRCS += stm32_dts.c
endif
include $(TOPDIR)/boards/Board.mk
@@ -129,5 +129,9 @@ int stm32_bringup(void);
int stm32_adc_setup(void);
#endif
#ifdef CONFIG_STM32H5_DTS
int stm32_dts_setup(int devno);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_STM32H5_NUCLEO_H563ZI_SRC_NUCLEO_H563ZI_H */
@@ -110,6 +110,16 @@ int stm32_bringup(void)
}
#endif /* CONFIG_ADC*/
#ifdef CONFIG_STM32H5_DTS
/* devno == 0 creates /dev/sensor_temp0 */
ret = stm32_dts_setup(0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_adc_setup failed: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}
@@ -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
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_dts_setup
*
* Description:
* Initialize DTS and register the DTS driver.
*
****************************************************************************/
int stm32_dts_setup(int devno)
{
static bool initialized = false;
int ret;
/* Check if we have already initialized */
if (!initialized)
{
/* Register the DTS driver at "/dev/sensor_temp0" */
ret = stm32h5_dts_register(0);
if (ret < 0)
{
aerr("ERROR: dts_register /dev/dts0 failed: %d\n", ret);
return ret;
}
initialized = true;
}
return OK;
}
#endif