You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/05/05 17:54:07 UTC
[incubator-nuttx] branch master updated (1ef0fe3 -> 8d763d3)
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.
from 1ef0fe3 stm32f103-minimum/src/stm32_tone: fix style issues
new d96565a arch/arm/src/stm32h7: add support for oneshot timer
new 8d763d3 arch/arm/src/stm32h7/stm32_oneshot: fix style issues
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/arm/src/stm32h7/Kconfig | 18 +++
arch/arm/src/stm32h7/Make.defs | 4 +
arch/arm/src/{stm32 => stm32h7}/stm32_oneshot.c | 129 +++++----------------
arch/arm/src/{stm32 => stm32h7}/stm32_oneshot.h | 69 +++++------
.../{stm32 => stm32h7}/stm32_oneshot_lowerhalf.c | 44 +++----
5 files changed, 94 insertions(+), 170 deletions(-)
copy arch/arm/src/{stm32 => stm32h7}/stm32_oneshot.c (72%)
copy arch/arm/src/{stm32 => stm32h7}/stm32_oneshot.h (74%)
copy arch/arm/src/{stm32 => stm32h7}/stm32_oneshot_lowerhalf.c (85%)
[incubator-nuttx] 02/02: arch/arm/src/stm32h7/stm32_oneshot: fix
style issues
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 8d763d37abdc432314c3cffe7cfd36165eedd5a4
Author: Pierre-Olivier Vauboin <po...@lambdaconcept.com>
AuthorDate: Tue May 5 17:48:54 2020 +0200
arch/arm/src/stm32h7/stm32_oneshot: fix style issues
---
arch/arm/src/stm32h7/stm32_oneshot.c | 10 ++++++----
arch/arm/src/stm32h7/stm32_oneshot.h | 2 +-
arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c | 3 ++-
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm/src/stm32h7/stm32_oneshot.c b/arch/arm/src/stm32h7/stm32_oneshot.c
index 6d8d71e..ec6cda5 100644
--- a/arch/arm/src/stm32h7/stm32_oneshot.c
+++ b/arch/arm/src/stm32h7/stm32_oneshot.c
@@ -185,7 +185,8 @@ int stm32_oneshot_initialize(struct stm32_oneshot_s *oneshot, int chan,
{
uint32_t frequency;
- tmrinfo("chan=%d resolution=%d usec, USEC_PER_SEC:%d\n", chan, resolution, USEC_PER_SEC);
+ tmrinfo("chan=%d resolution=%d usec, USEC_PER_SEC:%d\n", chan, resolution,
+ USEC_PER_SEC);
DEBUGASSERT(oneshot && resolution > 0);
/* Get the TC frequency the corresponds to the requested resolution */
@@ -227,7 +228,8 @@ int stm32_oneshot_max_delay(struct stm32_oneshot_s *oneshot, uint64_t *usec)
{
DEBUGASSERT(oneshot != NULL && usec != NULL);
- tmrinfo("frequency: %d, USEC_PER_SEC: %d\n", oneshot->frequency, USEC_PER_SEC);
+ tmrinfo("frequency: %d, USEC_PER_SEC: %d\n", oneshot->frequency,
+ USEC_PER_SEC);
*usec = (uint64_t)(UINT32_MAX / oneshot->frequency) *
(uint64_t)USEC_PER_SEC;
return OK;
@@ -261,8 +263,8 @@ int stm32_oneshot_start(struct stm32_oneshot_s *oneshot,
uint64_t period;
irqstate_t flags;
- tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
- handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+ tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n", handler, arg,
+ (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
DEBUGASSERT(oneshot && handler && ts);
DEBUGASSERT(oneshot->tch);
diff --git a/arch/arm/src/stm32h7/stm32_oneshot.h b/arch/arm/src/stm32h7/stm32_oneshot.h
index 075cf7f..6eb64c6 100644
--- a/arch/arm/src/stm32h7/stm32_oneshot.h
+++ b/arch/arm/src/stm32h7/stm32_oneshot.h
@@ -65,7 +65,7 @@
typedef void (*oneshot_handler_t)(void *arg);
/* The oneshot client must allocate an instance of this structure and called
- * stm32_oneshot_initialize() before using the oneshot facilities. The client
+ * stm32_oneshot_initialize() before using the oneshot facilities. The client
* should not access the contents of this structure directly since the
* contents are subject to change.
*/
diff --git a/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c b/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
index 4424165..f0efc63 100644
--- a/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
+++ b/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
@@ -39,7 +39,8 @@
* Private Types
****************************************************************************/
-/* This structure describes the state of the oneshot timer lower-half driver */
+/* This structure describes the state of the oneshot timer lower-half driver
+ */
struct stm32_oneshot_lowerhalf_s
{
[incubator-nuttx] 01/02: arch/arm/src/stm32h7: add support for
oneshot timer
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit d96565a7658685fb644c9e8fcc7154042aa2d75c
Author: Pierre-Olivier Vauboin <po...@lambdaconcept.com>
AuthorDate: Tue May 5 17:44:14 2020 +0200
arch/arm/src/stm32h7: add support for oneshot timer
The code is ported from arch/arm/src/stm32
---
arch/arm/src/stm32h7/Kconfig | 18 ++
arch/arm/src/stm32h7/Make.defs | 4 +
arch/arm/src/stm32h7/stm32_oneshot.c | 402 +++++++++++++++++++++++++
arch/arm/src/stm32h7/stm32_oneshot.h | 195 ++++++++++++
arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c | 330 ++++++++++++++++++++
5 files changed, 949 insertions(+)
diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig
index c1a7e15..7b4f490 100644
--- a/arch/arm/src/stm32h7/Kconfig
+++ b/arch/arm/src/stm32h7/Kconfig
@@ -1625,6 +1625,24 @@ config STM32H7_DMACAPABLE
menu "Timer Configuration"
+config STM32H7_ONESHOT
+ bool "TIM one-shot wrapper"
+ default n
+ ---help---
+ Enable a wrapper around the low level timer/counter functions to
+ support one-shot timer.
+
+config STM32H7_ONESHOT_MAXTIMERS
+ int "Maximum number of oneshot timers"
+ default 1
+ range 1 8
+ depends on STM32H7_ONESHOT
+ ---help---
+ Determines the maximum number of oneshot timers that can be
+ supported. This setting pre-allocates some minimal support for each
+ of the timers and places an upper limit on the number of oneshot
+ timers that you can use.
+
config STM32H7_PWM_LL_OPS
bool "PWM low-level operations"
default n
diff --git a/arch/arm/src/stm32h7/Make.defs b/arch/arm/src/stm32h7/Make.defs
index 4cb092e..2951768 100644
--- a/arch/arm/src/stm32h7/Make.defs
+++ b/arch/arm/src/stm32h7/Make.defs
@@ -117,6 +117,10 @@ ifneq ($(CONFIG_SCHED_TICKLESS),y)
CHIP_CSRCS += stm32_timerisr.c
endif
+ifeq ($(CONFIG_STM32H7_ONESHOT),y)
+CHIP_CSRCS += stm32_oneshot.c stm32_oneshot_lowerhalf.c
+endif
+
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CHIP_CSRCS += stm32_userspace.c stm32_mpuinit.c
endif
diff --git a/arch/arm/src/stm32h7/stm32_oneshot.c b/arch/arm/src/stm32h7/stm32_oneshot.c
new file mode 100644
index 0000000..6d8d71e
--- /dev/null
+++ b/arch/arm/src/stm32h7/stm32_oneshot.c
@@ -0,0 +1,402 @@
+/****************************************************************************
+ * arch/arm/src/stm32h7/stm32_oneshot.c
+ *
+ * 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 <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sched.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/clock.h>
+
+#include "stm32_oneshot.h"
+
+#ifdef CONFIG_STM32H7_ONESHOT
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_oneshot_handler(int irg_num, void * context, void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct stm32_oneshot_s *g_oneshot[CONFIG_STM32H7_ONESHOT_MAXTIMERS];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_handler
+ *
+ * Description:
+ * Common timer interrupt callback. When any oneshot timer interrupt
+ * expires, this function will be called. It will forward the call to
+ * the next level up.
+ *
+ * Input Parameters:
+ * oneshot - The state associated with the expired timer
+ *
+ * Returned Value:
+ * Always returns OK
+ *
+ ****************************************************************************/
+
+static int stm32_oneshot_handler(int irg_num, void * context, void *arg)
+{
+ struct stm32_oneshot_s * oneshot = (struct stm32_oneshot_s *) arg;
+ oneshot_handler_t oneshot_handler;
+ void *oneshot_arg;
+
+ tmrinfo("Expired (Interrupt)...\n");
+ DEBUGASSERT(oneshot != NULL && oneshot->handler);
+
+ /* The clock was stopped, but not disabled when the RC match occurred.
+ * Disable the TC now and disable any further interrupts.
+ */
+
+ STM32_TIM_SETISR(oneshot->tch, NULL, NULL, 0);
+ STM32_TIM_DISABLEINT(oneshot->tch, GTIM_DIER_UIE);
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
+ STM32_TIM_ACKINT(oneshot->tch, GTIM_SR_UIF);
+
+ /* The timer is no longer running */
+
+ oneshot->running = false;
+
+ /* Forward the event, clearing out any vestiges */
+
+ oneshot_handler = (oneshot_handler_t)oneshot->handler;
+ oneshot->handler = NULL;
+ oneshot_arg = (void *)oneshot->arg;
+ oneshot->arg = NULL;
+
+ oneshot_handler(oneshot_arg);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_allocate_handler
+ *
+ * Description:
+ * Allocate a timer callback handler for the oneshot instance.
+ *
+ * Input Parameters:
+ * oneshot - The state instance the new oneshot timer
+ *
+ * Returned Value:
+ * Returns zero (OK) on success. This can only fail if the number of
+ * timers exceeds CONFIG_STM32H7_ONESHOT_MAXTIMERS.
+ *
+ ****************************************************************************/
+
+static inline int stm32_allocate_handler(struct stm32_oneshot_s *oneshot)
+{
+#if CONFIG_STM32H7_ONESHOT_MAXTIMERS > 1
+ int ret = -EBUSY;
+ int i;
+
+ /* Search for an unused handler */
+
+ sched_lock();
+ for (i = 0; i < CONFIG_STM32H7_ONESHOT_MAXTIMERS; i++)
+ {
+ /* Is this handler available? */
+
+ if (g_oneshot[i] == NULL)
+ {
+ /* Yes... assign it to this oneshot */
+
+ g_oneshot[i] = oneshot;
+ oneshot->cbndx = i;
+ ret = OK;
+ break;
+ }
+ }
+
+ sched_unlock();
+ return ret;
+
+#else
+ if (g_oneshot[0] == NULL)
+ {
+ g_oneshot[0] = oneshot;
+ return OK;
+ }
+
+ return -EBUSY;
+#endif
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_initialize
+ *
+ * Description:
+ * Initialize the oneshot timer wrapper
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_initialize(struct stm32_oneshot_s *oneshot, int chan,
+ uint16_t resolution)
+{
+ uint32_t frequency;
+
+ tmrinfo("chan=%d resolution=%d usec, USEC_PER_SEC:%d\n", chan, resolution, USEC_PER_SEC);
+ DEBUGASSERT(oneshot && resolution > 0);
+
+ /* Get the TC frequency the corresponds to the requested resolution */
+
+ frequency = USEC_PER_SEC / (uint32_t)resolution;
+ tmrinfo("frequency: %d\n", frequency);
+ oneshot->frequency = frequency;
+
+ oneshot->tch = stm32_tim_init(chan);
+ if (!oneshot->tch)
+ {
+ tmrerr("ERROR: Failed to allocate TIM%d\n", chan);
+ return -EBUSY;
+ }
+
+ STM32_TIM_SETCLOCK(oneshot->tch, frequency);
+
+ /* Initialize the remaining fields in the state structure. */
+
+ oneshot->chan = chan;
+ oneshot->running = false;
+ oneshot->handler = NULL;
+ oneshot->arg = NULL;
+
+ /* Assign a callback handler to the oneshot */
+
+ return stm32_allocate_handler(oneshot);
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_max_delay
+ *
+ * Description:
+ * Determine the maximum delay of the one-shot timer (in microseconds)
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_max_delay(struct stm32_oneshot_s *oneshot, uint64_t *usec)
+{
+ DEBUGASSERT(oneshot != NULL && usec != NULL);
+
+ tmrinfo("frequency: %d, USEC_PER_SEC: %d\n", oneshot->frequency, USEC_PER_SEC);
+ *usec = (uint64_t)(UINT32_MAX / oneshot->frequency) *
+ (uint64_t)USEC_PER_SEC;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_start
+ *
+ * Description:
+ * Start the oneshot timer
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * handler The function to call when when the oneshot timer expires.
+ * arg An opaque argument that will accompany the callback.
+ * ts Provides the duration of the one shot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_start(struct stm32_oneshot_s *oneshot,
+ oneshot_handler_t handler, void *arg,
+ const struct timespec *ts)
+{
+ uint64_t usec;
+ uint64_t period;
+ irqstate_t flags;
+
+ tmrinfo("handler=%p arg=%p, ts=(%lu, %lu)\n",
+ handler, arg, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
+ DEBUGASSERT(oneshot && handler && ts);
+ DEBUGASSERT(oneshot->tch);
+
+ /* Was the oneshot already running? */
+
+ flags = enter_critical_section();
+ if (oneshot->running)
+ {
+ /* Yes.. then cancel it */
+
+ tmrinfo("Already running... cancelling\n");
+ stm32_oneshot_cancel(oneshot, NULL);
+ }
+
+ /* Save the new handler and its argument */
+
+ oneshot->handler = handler;
+ oneshot->arg = arg;
+
+ /* Express the delay in microseconds */
+
+ usec = (uint64_t)ts->tv_sec * USEC_PER_SEC +
+ (uint64_t)(ts->tv_nsec / NSEC_PER_USEC);
+
+ /* Get the timer counter frequency and determine the number of counts need
+ * to achieve the requested delay.
+ *
+ * frequency = ticks / second
+ * ticks = seconds * frequency
+ * = (usecs * frequency) / USEC_PER_SEC;
+ */
+
+ period = (usec * (uint64_t)oneshot->frequency) / USEC_PER_SEC;
+
+ tmrinfo("usec=%llu period=%08llx\n", usec, period);
+ DEBUGASSERT(period <= UINT32_MAX);
+
+ /* Set up to receive the callback when the interrupt occurs */
+
+ STM32_TIM_SETISR(oneshot->tch, stm32_oneshot_handler, oneshot, 0);
+
+ /* Set timer period */
+
+ oneshot->period = (uint32_t)period;
+ STM32_TIM_SETPERIOD(oneshot->tch, (uint32_t)period);
+
+ /* Start the counter */
+
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_PULSE);
+
+ STM32_TIM_ACKINT(oneshot->tch, GTIM_SR_UIF);
+ STM32_TIM_ENABLEINT(oneshot->tch, GTIM_DIER_UIE);
+
+ /* Enable interrupts. We should get the callback when the interrupt
+ * occurs.
+ */
+
+ oneshot->running = true;
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_oneshot_cancel
+ *
+ * Description:
+ * Cancel the oneshot timer and return the time remaining on the timer.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer. A time of zero is returned if the timer is
+ * not running. ts may be zero in which case the time remaining
+ * is not returned.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_cancel(struct stm32_oneshot_s *oneshot,
+ struct timespec *ts)
+{
+ irqstate_t flags;
+
+ /* Was the timer running? */
+
+ flags = enter_critical_section();
+ if (!oneshot->running)
+ {
+ /* No.. Just return zero timer remaining and successful cancellation.
+ * This function may execute at a high rate with no timer running
+ * (as when pre-emption is enabled and disabled).
+ */
+
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ leave_critical_section(flags);
+ return OK;
+ }
+
+ tmrinfo("Cancelling...\n");
+
+ /* Now we can disable the interrupt and stop the timer. */
+
+ STM32_TIM_DISABLEINT(oneshot->tch, GTIM_DIER_UIE);
+ STM32_TIM_SETISR(oneshot->tch, NULL, NULL, 0);
+ STM32_TIM_SETMODE(oneshot->tch, STM32_TIM_MODE_DISABLED);
+
+ oneshot->running = false;
+ oneshot->handler = NULL;
+ oneshot->arg = NULL;
+ leave_critical_section(flags);
+
+ /* Did the caller provide us with a location to return the time
+ * remaining?
+ */
+
+ if (ts)
+ {
+ /* Not implemented */
+
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_STM32H7_ONESHOT */
diff --git a/arch/arm/src/stm32h7/stm32_oneshot.h b/arch/arm/src/stm32h7/stm32_oneshot.h
new file mode 100644
index 0000000..075cf7f
--- /dev/null
+++ b/arch/arm/src/stm32h7/stm32_oneshot.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * arch/arm/src/stm32h7/stm32_oneshot.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32_ONESHOT_H
+#define __ARCH_ARM_SRC_STM32_ONESHOT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <time.h>
+
+#include <nuttx/irq.h>
+
+#include "stm32_tim.h"
+
+#ifdef CONFIG_STM32H7_ONESHOT
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if !defined(CONFIG_STM32H7_ONESHOT_MAXTIMERS) || \
+ CONFIG_STM32H7_ONESHOT_MAXTIMERS < 1
+# undef CONFIG_STM32H7_ONESHOT_MAXTIMERS
+# define CONFIG_STM32H7_ONESHOT_MAXTIMERS 1
+#endif
+
+#if CONFIG_STM32H7_ONESHOT_MAXTIMERS > 8
+# warning Additional logic required to handle more than 8 timers
+# undef CONFIG_STM32H7_ONESHOT_MAXTIMERS
+# define CONFIG_STM32H7_ONESHOT_MAXTIMERS 8
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This describes the callback function that will be invoked when the oneshot
+ * timer expires. The oneshot fires, the client will receive:
+ *
+ * arg - The opaque argument provided when the interrupt was registered
+ */
+
+typedef void (*oneshot_handler_t)(void *arg);
+
+/* The oneshot client must allocate an instance of this structure and called
+ * stm32_oneshot_initialize() before using the oneshot facilities. The client
+ * should not access the contents of this structure directly since the
+ * contents are subject to change.
+ */
+
+struct stm32_oneshot_s
+{
+ uint8_t chan; /* The timer/counter in use */
+#if CONFIG_STM32H7_ONESHOT_MAXTIMERS > 1
+ uint8_t cbndx; /* Timer callback handler index */
+#endif
+ volatile bool running; /* True: the timer is running */
+ FAR struct stm32_tim_dev_s *tch; /* Pointer returned by
+ * stm32_tim_init() */
+ volatile oneshot_handler_t handler; /* Oneshot expiration callback */
+ volatile void *arg; /* The argument that will accompany
+ * the callback */
+ uint32_t frequency;
+ uint32_t period;
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_initialize
+ *
+ * Description:
+ * Initialize the oneshot timer wrapper
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_initialize(struct stm32_oneshot_s *oneshot, int chan,
+ uint16_t resolution);
+
+/****************************************************************************
+ * Name: stm32_oneshot_max_delay
+ *
+ * Description:
+ * Determine the maximum delay of the one-shot timer (in microseconds)
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_max_delay(struct stm32_oneshot_s *oneshot, uint64_t *usec);
+
+/****************************************************************************
+ * Name: stm32_oneshot_start
+ *
+ * Description:
+ * Start the oneshot timer
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * handler The function to call when when the oneshot timer expires.
+ * arg An opaque argument that will accompany the callback.
+ * ts Provides the duration of the one shot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_start(struct stm32_oneshot_s *oneshot,
+ oneshot_handler_t handler, void *arg,
+ const struct timespec *ts);
+
+/****************************************************************************
+ * Name: stm32_oneshot_cancel
+ *
+ * Description:
+ * Cancel the oneshot timer and return the time remaining on the timer.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Input Parameters:
+ * oneshot Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * stm32_oneshot_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer. A time of zero is returned if the timer is
+ * not running.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int stm32_oneshot_cancel(struct stm32_oneshot_s *oneshot,
+ struct timespec *ts);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_STM32H7_ONESHOT */
+#endif /* __ARCH_ARM_SRC_STM32_ONESHOT_H */
diff --git a/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c b/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
new file mode 100644
index 0000000..4424165
--- /dev/null
+++ b/arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
@@ -0,0 +1,330 @@
+/****************************************************************************
+ * arch/arm/src/stm32h7/stm32_oneshot_lowerhalf.c
+ *
+ * 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 <stdint.h>
+#include <time.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/timers/oneshot.h>
+
+#include "stm32_oneshot.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure describes the state of the oneshot timer lower-half driver */
+
+struct stm32_oneshot_lowerhalf_s
+{
+ /* This is the part of the lower half driver that is visible to the upper-
+ * half client of the driver. This must be the first thing in this
+ * structure so that pointers to struct oneshot_lowerhalf_s are cast
+ * compatible to struct stm32_oneshot_lowerhalf_s and vice versa.
+ */
+
+ struct oneshot_lowerhalf_s lh; /* Common lower-half driver fields */
+
+ /* Private lower half data follows */
+
+ struct stm32_oneshot_s oneshot; /* STM32-specific oneshot state */
+ oneshot_callback_t callback; /* Internal handler that receives callback */
+ FAR void *arg; /* Argument that is passed to the handler */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void stm32_oneshot_handler(void *arg);
+
+static int stm32_max_delay(FAR struct oneshot_lowerhalf_s *lower,
+ FAR struct timespec *ts);
+static int stm32_start(FAR struct oneshot_lowerhalf_s *lower,
+ oneshot_callback_t callback, FAR void *arg,
+ FAR const struct timespec *ts);
+static int stm32_cancel(FAR struct oneshot_lowerhalf_s *lower,
+ FAR struct timespec *ts);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Lower half operations */
+
+static const struct oneshot_operations_s g_oneshot_ops =
+{
+ .max_delay = stm32_max_delay,
+ .start = stm32_start,
+ .cancel = stm32_cancel,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_oneshot_handler
+ *
+ * Description:
+ * Timer expiration handler
+ *
+ * Input Parameters:
+ * arg - Should be the same argument provided when stm32_oneshot_start()
+ * was called.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void stm32_oneshot_handler(void *arg)
+{
+ FAR struct stm32_oneshot_lowerhalf_s *priv =
+ (FAR struct stm32_oneshot_lowerhalf_s *)arg;
+ oneshot_callback_t callback;
+ FAR void *cbarg;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Perhaps the callback was nullified in a race condition with
+ * stm32_cancel?
+ */
+
+ if (priv->callback)
+ {
+ /* Sample and nullify BEFORE executing callback (in case the callback
+ * restarts the oneshot).
+ */
+
+ callback = priv->callback;
+ cbarg = priv->arg;
+ priv->callback = NULL;
+ priv->arg = NULL;
+
+ /* Then perform the callback */
+
+ callback(&priv->lh, cbarg);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_max_delay
+ *
+ * Description:
+ * Determine the maximum delay of the one-shot timer (in microseconds)
+ *
+ * Input Parameters:
+ * lower An instance of the lower-half oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * oneshot_initialize();
+ * ts The location in which to return the maximum delay.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_max_delay(FAR struct oneshot_lowerhalf_s *lower,
+ FAR struct timespec *ts)
+{
+ FAR struct stm32_oneshot_lowerhalf_s *priv =
+ (FAR struct stm32_oneshot_lowerhalf_s *)lower;
+ uint64_t usecs;
+ int ret;
+
+ DEBUGASSERT(priv != NULL && ts != NULL);
+ ret = stm32_oneshot_max_delay(&priv->oneshot, &usecs);
+ if (ret >= 0)
+ {
+ uint64_t sec = usecs / 1000000;
+ usecs -= 1000000 * sec;
+
+ ts->tv_sec = (time_t)sec;
+ ts->tv_nsec = (long)(usecs * 1000);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_start
+ *
+ * Description:
+ * Start the oneshot timer
+ *
+ * Input Parameters:
+ * lower An instance of the lower-half oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * oneshot_initialize();
+ * handler The function to call when when the oneshot timer expires.
+ * arg An opaque argument that will accompany the callback.
+ * ts Provides the duration of the one shot timer.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned
+ * on failure.
+ *
+ ****************************************************************************/
+
+static int stm32_start(FAR struct oneshot_lowerhalf_s *lower,
+ oneshot_callback_t callback, FAR void *arg,
+ FAR const struct timespec *ts)
+{
+ FAR struct stm32_oneshot_lowerhalf_s *priv =
+ (FAR struct stm32_oneshot_lowerhalf_s *)lower;
+ irqstate_t flags;
+ int ret;
+
+ DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
+
+ /* Save the callback information and start the timer */
+
+ flags = enter_critical_section();
+ priv->callback = callback;
+ priv->arg = arg;
+ ret = stm32_oneshot_start(&priv->oneshot,
+ stm32_oneshot_handler, priv, ts);
+ leave_critical_section(flags);
+
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_oneshot_start failed: %d\n", flags);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_cancel
+ *
+ * Description:
+ * Cancel the oneshot timer and return the time remaining on the timer.
+ *
+ * NOTE: This function may execute at a high rate with no timer running (as
+ * when pre-emption is enabled and disabled).
+ *
+ * Input Parameters:
+ * lower Caller allocated instance of the oneshot state structure. This
+ * structure must have been previously initialized via a call to
+ * oneshot_initialize();
+ * ts The location in which to return the time remaining on the
+ * oneshot timer. A time of zero is returned if the timer is
+ * not running.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A call to up_timer_cancel() when
+ * the timer is not active should also return success; a negated errno
+ * value is returned on any failure.
+ *
+ ****************************************************************************/
+
+static int stm32_cancel(FAR struct oneshot_lowerhalf_s *lower,
+ FAR struct timespec *ts)
+{
+ FAR struct stm32_oneshot_lowerhalf_s *priv =
+ (FAR struct stm32_oneshot_lowerhalf_s *)lower;
+ irqstate_t flags;
+ int ret;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Cancel the timer */
+
+ flags = enter_critical_section();
+ ret = stm32_oneshot_cancel(&priv->oneshot, ts);
+ priv->callback = NULL;
+ priv->arg = NULL;
+ leave_critical_section(flags);
+
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_oneshot_cancel failed: %d\n", flags);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: oneshot_initialize
+ *
+ * Description:
+ * Initialize the oneshot timer and return a oneshot lower half driver
+ * instance.
+ *
+ * Input Parameters:
+ * chan Timer counter channel to be used.
+ * resolution The required resolution of the timer in units of
+ * microseconds. NOTE that the range is restricted to the
+ * range of uint16_t (excluding zero).
+ *
+ * Returned Value:
+ * On success, a non-NULL instance of the oneshot lower-half driver is
+ * returned. NULL is return on any failure.
+ *
+ ****************************************************************************/
+
+FAR struct oneshot_lowerhalf_s *oneshot_initialize(int chan,
+ uint16_t resolution)
+{
+ FAR struct stm32_oneshot_lowerhalf_s *priv;
+ int ret;
+
+ /* Allocate an instance of the lower half driver */
+
+ priv = (FAR struct stm32_oneshot_lowerhalf_s *)
+ kmm_zalloc(sizeof(struct stm32_oneshot_lowerhalf_s));
+
+ if (priv == NULL)
+ {
+ tmrerr("ERROR: Failed to initialized state structure\n");
+ return NULL;
+ }
+
+ /* Initialize the lower-half driver structure */
+
+ priv->lh.ops = &g_oneshot_ops;
+
+ /* Initialize the contained STM32 oneshot timer */
+
+ ret = stm32_oneshot_initialize(&priv->oneshot, chan, resolution);
+ if (ret < 0)
+ {
+ tmrerr("ERROR: stm32_oneshot_initialize failed: %d\n", ret);
+ kmm_free(priv);
+ return NULL;
+ }
+
+ return &priv->lh;
+}