You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/07/18 19:01:02 UTC

[incubator-nuttx] branch master updated (17bd5f3 -> 774ea6e)

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 17bd5f3  tools/checkrelease.sh: auto import KEYS from the release server
     new 7db6199  arch/arm/src/nrf52: add a low-level TIMER interface
     new f6235c5  boards/arm/nrf52/nrf52840-dk: add highpri example configuration
     new 774ea6e  arch/arm/src/nrf52: add a low-level RTC interface

The 3 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/nrf52/Kconfig                         |  16 +
 arch/arm/src/nrf52/Make.defs                       |   7 +
 arch/arm/src/nrf52/hardware/nrf52_rtc.h            | 108 +++
 arch/arm/src/nrf52/hardware/nrf52_tim.h            |  86 ++-
 arch/arm/src/nrf52/nrf52_rtc.c                     | 672 ++++++++++++++++
 arch/arm/src/nrf52/nrf52_rtc.h                     | 119 +++
 arch/arm/src/nrf52/nrf52_tim.c                     | 857 +++++++++++++++++++++
 arch/arm/src/nrf52/nrf52_tim.h                     | 176 +++++
 boards/arm/nrf52/nrf52840-dk/Kconfig               |   4 +
 .../nrf52840-dk/configs/{nsh => highpri}/defconfig |  15 +-
 .../arm/nrf52/nrf52840-dk/scripts/flash_config.ld  |   6 +
 boards/arm/nrf52/nrf52840-dk/src/Makefile          |   4 +
 .../nrf52840-dk/src/nrf52_highpri.c}               | 159 ++--
 13 files changed, 2127 insertions(+), 102 deletions(-)
 create mode 100644 arch/arm/src/nrf52/hardware/nrf52_rtc.h
 create mode 100644 arch/arm/src/nrf52/nrf52_rtc.c
 create mode 100644 arch/arm/src/nrf52/nrf52_rtc.h
 create mode 100644 arch/arm/src/nrf52/nrf52_tim.c
 create mode 100644 arch/arm/src/nrf52/nrf52_tim.h
 copy boards/arm/nrf52/nrf52840-dk/configs/{nsh => highpri}/defconfig (82%)
 copy boards/arm/{stm32/viewtool-stm32f107/src/stm32_highpri.c => nrf52/nrf52840-dk/src/nrf52_highpri.c} (66%)


[incubator-nuttx] 01/03: arch/arm/src/nrf52: add a low-level TIMER interface

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 7db61992f9d3464b70f988ecdd24cefb7b423f80
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Jul 18 10:00:41 2020 +0200

    arch/arm/src/nrf52: add a low-level TIMER interface
---
 arch/arm/src/nrf52/Kconfig              |   9 +
 arch/arm/src/nrf52/Make.defs            |   3 +
 arch/arm/src/nrf52/hardware/nrf52_tim.h |  86 ++--
 arch/arm/src/nrf52/nrf52_tim.c          | 857 ++++++++++++++++++++++++++++++++
 arch/arm/src/nrf52/nrf52_tim.h          | 176 +++++++
 5 files changed, 1099 insertions(+), 32 deletions(-)

diff --git a/arch/arm/src/nrf52/Kconfig b/arch/arm/src/nrf52/Kconfig
index 394006c..acd40f2 100644
--- a/arch/arm/src/nrf52/Kconfig
+++ b/arch/arm/src/nrf52/Kconfig
@@ -90,6 +90,10 @@ config NRF52_UART
 	bool
 	default n
 
+config NRF52_TIMER
+	bool
+	default n
+
 config NRF52_SPI_MASTER_WORKAROUND_1BYTE_TRANSFER
 	bool "SPI Master 1 Byte transfer anomaly workaround"
 	depends on NRF52_SPI_MASTER && ARCH_FAMILY_NRF52832
@@ -181,22 +185,27 @@ config NRF52_SAADC
 
 config NRF52_TIMER0
 	bool "TIMER0"
+	select NRF52_TIMER
 	default n
 
 config NRF52_TIMER1
 	bool "TIMER1"
+	select NRF52_TIMER
 	default n
 
 config NRF52_TIMER2
 	bool "TIMER2"
+	select NRF52_TIMER
 	default n
 
 config NRF52_TIMER3
 	bool "TIMER3"
+	select NRF52_TIMER
 	default n
 
 config NRF52_TIMER4
 	bool "TIMER4"
+	select NRF52_TIMER
 	default n
 
 config NRF52_RTC0
diff --git a/arch/arm/src/nrf52/Make.defs b/arch/arm/src/nrf52/Make.defs
index b2c81c4..74f172a 100644
--- a/arch/arm/src/nrf52/Make.defs
+++ b/arch/arm/src/nrf52/Make.defs
@@ -128,5 +128,8 @@ endif
 
 ifeq ($(CONFIG_NRF52_RADIO),y)
 CHIP_CSRCS += nrf52_radio.c
+endif
 
+ifeq ($(CONFIG_NRF52_TIMER),y)
+CHIP_CSRCS += nrf52_tim.c
 endif
diff --git a/arch/arm/src/nrf52/hardware/nrf52_tim.h b/arch/arm/src/nrf52/hardware/nrf52_tim.h
index a61bcf5..09f2ffe 100644
--- a/arch/arm/src/nrf52/hardware/nrf52_tim.h
+++ b/arch/arm/src/nrf52/hardware/nrf52_tim.h
@@ -1,4 +1,4 @@
-/**************************************************************************
+/************************************************************************************
  * arch/arm/src/nrf52/hardware/nrf52_tim.h
  *
  *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
@@ -31,60 +31,81 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- ***************************************************************************/
+ ************************************************************************************/
 
 #ifndef __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_TIM_H
 #define __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_TIM_H
 
-/***************************************************************************
+/************************************************************************************
  * Included Files
- ***************************************************************************/
+ ************************************************************************************/
 
 #include <nuttx/config.h>
 #include "hardware/nrf52_memorymap.h"
 
-/***************************************************************************
+/************************************************************************************
  * Pre-processor Definitions
- ***************************************************************************/
-
-/* Register offsets for TIM ************************************************/
-
-#define NRF52_TIM_TASKS_START_OFFSET       0x0000 /* Start Timer */
-#define NRF52_TIM_TASKS_STOP_OFFSET        0x0004 /* Stop Timer */
-#define NRF52_TIM_TASKS_COUNT_OFFSET       0x0008 /* Increment Timer*/
-#define NRF52_TIM_TASKS_CLEAR_OFFSET       0x000c /* Clear time */
-#define NRF52_TIM_TASKS_SHUTDOWN_OFFSET    0x0010 /* Shutdown Timer */
-#define NRF52_TIM_TASKS_CAPTURE_OFFSET(x)  (0x0040 + ((x) * 0x04)) /* Capture Timer value to CC[x] */
-#define NRF52_TIM_EVENTS_COMPARE_OFFSET(x) (0x0140 + ((x) * 0x04)) /* Compare event on CC[x] */
-#define NRF52_TIM_SHORTS_OFFSET            0x0200 /* Shortcuts between local events and tasks */
-#define NRF52_TIM_INTENSET_OFFSET          0x0304 /* Enable interrupt */
-#define NRF52_TIM_MODE_OFFSET              0x0504 /* Timer mode selection */
-#define NRF52_TIM_BITMODE_OFFSET           0x0508 /* Configure the number of bits used by the Timer */
-#define NRF52_TIM_PRESCALER_OFFSET         0x0510 /* Timer prescaler register */
-#define NRF52_TIM_CC_OFFSET(x)             (0x0540 + ((x) * 0x04)) /* Capture/Compare register x */
-
-/* Register offsets for TIM ************************************************/
+ ************************************************************************************/
+
+/* TIMER constants ******************************************************************/
+
+#define TIMER_BASE_FERQUENCY              (16000000)
+
+/* Register offsets for TIM *********************************************************/
+
+#define NRF52_TIM_TASKS_START_OFFSET       0x0000                  /* Start Timer */
+#define NRF52_TIM_TASKS_STOP_OFFSET        0x0004                  /* Stop Timer */
+#define NRF52_TIM_TASKS_COUNT_OFFSET       0x0008                  /* Increment Timer */
+#define NRF52_TIM_TASKS_CLEAR_OFFSET       0x000c                  /* Clear time */
+#define NRF52_TIM_TASKS_SHUTDOWN_OFFSET    0x0010                  /* Shutdown Timer */
+#define NRF52_TIM_TASKS_CAPTURE_OFFSET(x)  (0x0040 + ((x) * 4))    /* Capture Timer value to CC[x] */
+#define NRF52_TIM_EVENTS_COMPARE_OFFSET(x) (0x0140 + ((x) * 4))    /* Compare event on CC[x] */
+#define NRF52_TIM_SHORTS_OFFSET            0x0200                  /* Shortcuts between local events and tasks */
+#define NRF52_TIM_INTENSET_OFFSET          0x0304                  /* Enable interrupt */
+#define NRF52_TIM_INTCLR_OFFSET            0x0308                  /* Disable interrupt */
+#define NRF52_TIM_MODE_OFFSET              0x0504                  /* Timer mode selection */
+#define NRF52_TIM_BITMODE_OFFSET           0x0508                  /* Configure the number of bits used by the Timer */
+#define NRF52_TIM_PRESCALER_OFFSET         0x0510                  /* Timer prescaler register */
+#define NRF52_TIM_CC_OFFSET(x)             (0x0540 + ((x) * 4))    /* Capture/Compare register x */
+
+/* Register offsets for TIM *********************************************************/
+
+/* TASKS_START Register */
+
+#define TIM_TASKS_START                    (1 << 0)                /* Bit 0: Start Timer */
+
+/* TASKS_STOP Register */
+
+#define TIM_TASKS_STOP                     (1 << 0)                /* Bit 0: Stop Timer */
+
+/* TASKS_COUNT Register */
+
+#define TIM_TASKS_COUNT                    (1 << 0)                /* Bit 0: Increment Timer */
+
+/* TASKS_CLEAR Register */
+
+#define TIM_TASKS_CLEAR                    (1 << 0)                /* Bit 0: Clear Timer */
 
 /* SHORTS Register */
 
-#define TIM_SHORTS_COMPARE_CLEAR(x)        (1 << (x))        /* Bits 0-5: */
-#define TIM_SHORTS_COMPARE_STOP(x)         (1 << (x + 0x8))  /* Bits 8-13 */
+#define TIM_SHORTS_COMPARE_CLEAR(x)        (1 << (x))              /* Bits 0-5: */
+#define TIM_SHORTS_COMPARE_STOP(x)         (1 << (x + 8))          /* Bits 8-13 */
 
 /* INTENSET/INTENCLR Register */
 
-#define TIM_INT_COMPARE(x)                 (1 << (x + 0x16)) /* Bits 16-21 */
+#define TIM_INT_COMPARE(x)                 (1 << (x + 16))         /* Bits 16-21 */
 
 /* MODE Register */
 
-#define TIM_MODE_SHIFT                     (0)               /* Bits 0-1: Timer mode */
+#define TIM_MODE_SHIFT                     (0)                     /* Bits 0-1: Timer mode */
 #define TIM_MODE_MASK                      (0x3 << TIM_MODE_SHIFT)
 #  define TIM_MODE_TIMER                   (0x0 << TIM_MODE_SHIFT) /* 0: Timer mode */
 #  define TIM_MODE_COUNTER                 (0x1 << TIM_MODE_SHIFT) /* 1: Counter mode */
-#  define TIM_MODE_LPCONUTER               (0x2 << TIM_MODE_SHIFT) /* 2: Low Power Counter mode */
+#  define TIM_MODE_LPCOUNTER               (0x2 << TIM_MODE_SHIFT) /* 2: Low Power Counter mode */
 
 /* BITMODE Register */
 
-#define TIM_BITMODE_SHIFT                  (0)               /* Bits 0-1: Timer bit width */
+#define TIM_BITMODE_SHIFT                  (0)                        /* Bits 0-1: Timer bit width */
 #define TIM_BITMODE_MASK                   (0x3 << TIM_BITMODE_SHIFT)
 #  define TIM_BITMODE_16B                  (0x0 << TIM_BITMODE_SHIFT) /* 0: 16 bit */
 #  define TIM_BITMODE_8B                   (0x1 << TIM_BITMODE_SHIFT) /* 1: 8 bit */
@@ -93,7 +114,8 @@
 
 /* PRESCALER Register */
 
-#define TIM_PRESCALER_SHIFT                (0)               /* Bits 0-3: Prescaler value */
-#define TIM_PRESCALER_MASK                 (0xf << TIM_PRESCALER_SHIFT)
+#define TIM_PRESCALER_SHIFT                (0)                        /* Bits 0-3: Prescaler value */
+#define TIM_PRESCALER_MAX                  (0xf)
+#define TIM_PRESCALER_MASK                 (TIM_PRESCALER_MAX << TIM_PRESCALER_SHIFT)
 
 #endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_TIM_H */
diff --git a/arch/arm/src/nrf52/nrf52_tim.c b/arch/arm/src/nrf52/nrf52_tim.c
new file mode 100644
index 0000000..24b2c99
--- /dev/null
+++ b/arch/arm/src/nrf52/nrf52_tim.c
@@ -0,0 +1,857 @@
+/****************************************************************************
+ * arch/arm/src/nrf52/nrf52_tim.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 <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "arm_arch.h"
+
+#include "hardware/nrf52_tim.h"
+
+#include "nrf52_tim.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct nrf52_tim_priv_s
+{
+  FAR struct nrf52_tim_ops_s *ops;
+  uint32_t                    base;
+  uint32_t                    irq;
+  uint8_t                     chan;
+  bool                        inuse;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* TIM registers access *****************************************************/
+
+static uint32_t nrf52_tim_getreg(FAR struct nrf52_tim_dev_s *dev,
+                                 uint32_t offset);
+static void nrf52_tim_putreg(FAR struct nrf52_tim_dev_s *dev,
+                             uint32_t offset,
+                             uint32_t value);
+
+/* TIM helpers **************************************************************/
+
+static uint32_t nrf52_tim_irq2reg(FAR struct nrf52_tim_dev_s *dev,
+                                  uint8_t s);
+
+/* TIM operations ***********************************************************/
+
+static int nrf52_tim_start(FAR struct nrf52_tim_dev_s *dev);
+static int nrf52_tim_stop(FAR struct nrf52_tim_dev_s *dev);
+static int nrf52_tim_clear(FAR struct nrf52_tim_dev_s *dev);
+static int nrf52_tim_configure(FAR struct nrf52_tim_dev_s *dev, uint8_t mode,
+                               uint8_t width);
+static int nrf52_tim_shorts(FAR struct nrf52_tim_dev_s *dev, uint8_t s,
+                            uint8_t i, bool en);
+static int nrf52_tim_count(FAR struct nrf52_tim_dev_s *dev);
+static int nrf52_tim_setcc(FAR struct nrf52_tim_dev_s *dev, uint8_t i,
+                           uint32_t cc);
+static int nrf52_tim_getcc(FAR struct nrf52_tim_dev_s *dev, uint8_t i,
+                           FAR uint32_t *cc);
+static int nrf52_tim_setpre(FAR struct nrf52_tim_dev_s *dev, uint8_t pre);
+static int nrf52_tim_setisr(FAR struct nrf52_tim_dev_s *dev, xcpt_t handler,
+                            FAR void * arg);
+static int nrf52_tim_enableint(FAR struct nrf52_tim_dev_s *dev, uint8_t s);
+static int nrf52_tim_disableint(FAR struct nrf52_tim_dev_s *dev, uint8_t s);
+static int nrf52_tim_checkint(FAR struct nrf52_tim_dev_s *dev, uint8_t s);
+static int nrf52_tim_ackint(FAR struct nrf52_tim_dev_s *dev, uint8_t s);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* NRF52 TIM ops */
+
+struct nrf52_tim_ops_s nrf52_tim_ops =
+{
+  .start      = nrf52_tim_start,
+  .stop       = nrf52_tim_stop,
+  .clear      = nrf52_tim_clear,
+  .configure  = nrf52_tim_configure,
+  .shorts     = nrf52_tim_shorts,
+  .count      = nrf52_tim_count,
+  .setcc      = nrf52_tim_setcc,
+  .getcc      = nrf52_tim_getcc,
+  .setpre     = nrf52_tim_setpre,
+  .setisr     = nrf52_tim_setisr,
+  .enableint  = nrf52_tim_enableint,
+  .disableint = nrf52_tim_disableint,
+  .checkint   = nrf52_tim_checkint,
+  .ackint     = nrf52_tim_ackint
+};
+
+#ifdef CONFIG_NRF52_TIMER0
+/* TIMER0 */
+
+struct nrf52_tim_priv_s g_nrf52_tim0_priv =
+{
+  .ops   = &nrf52_tim_ops,
+  .base  = NRF52_TIMER0_BASE,
+  .irq   = NRF52_IRQ_TIMER0,
+  .chan  = 4,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_TIMER1
+/* TIMER1 */
+
+struct nrf52_tim_priv_s g_nrf52_tim1_priv =
+{
+  .ops   = &nrf52_tim_ops,
+  .base  = NRF52_TIMER1_BASE,
+  .irq   = NRF52_IRQ_TIMER1,
+  .chan  = 4,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_TIMER2
+/* TIMER2 */
+
+struct nrf52_tim_priv_s g_nrf52_tim2_priv =
+{
+  .ops   = &nrf52_tim_ops,
+  .base  = NRF52_TIMER2_BASE,
+  .irq   = NRF52_IRQ_TIMER2,
+  .chan  = 4,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_TIMER3
+/* TIMER3 */
+
+struct nrf52_tim_priv_s g_nrf52_tim3_priv =
+{
+  .ops   = &nrf52_tim_ops,
+  .base  = NRF52_TIMER3_BASE,
+  .irq   = NRF52_IRQ_TIMER3,
+  .chan  = 6,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_TIMER4
+/* TIMER4 */
+
+struct nrf52_tim_priv_s g_nrf52_tim4_priv =
+{
+  .ops   = &nrf52_tim_ops,
+  .base  = NRF52_TIMER4_BASE,
+  .irq   = NRF52_IRQ_TIMER4,
+  .chan  = 6,
+  .inuse = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf52_tim_getreg
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static uint32_t nrf52_tim_getreg(FAR struct nrf52_tim_dev_s *dev,
+                                 uint32_t offset)
+{
+  DEBUGASSERT(dev);
+
+  return getreg32(((struct nrf52_tim_priv_s *)dev)->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_putreg
+ *
+ * Description:
+ *   Put a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static void nrf52_tim_putreg(FAR struct nrf52_tim_dev_s *dev,
+                             uint32_t offset,
+                             uint32_t value)
+{
+  DEBUGASSERT(dev);
+
+  putreg32(value, ((struct nrf52_tim_priv_s *)dev)->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_irq2reg
+ *
+ * Description:
+ *   Get the vaule of the interrupt register corresponding to the given
+ *   interrupt source
+ *
+ ****************************************************************************/
+
+static uint32_t nrf52_tim_irq2reg(FAR struct nrf52_tim_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+
+  switch (s)
+    {
+      case NRF52_TIM_INT_COMPARE0:
+        {
+          regval = TIM_INT_COMPARE(0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE1:
+        {
+          regval = TIM_INT_COMPARE(1);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE2:
+        {
+          regval = TIM_INT_COMPARE(2);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE3:
+        {
+          regval = TIM_INT_COMPARE(3);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE4:
+        {
+          regval = TIM_INT_COMPARE(4);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE5:
+        {
+          regval = TIM_INT_COMPARE(5);
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported IRQ source %d\n", s);
+          regval = 0;
+          goto errout;
+        }
+    }
+
+errout:
+  return regval;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_start
+ ****************************************************************************/
+
+static int nrf52_tim_start(FAR struct nrf52_tim_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_tim_putreg(dev, NRF52_TIM_TASKS_START_OFFSET, TIM_TASKS_START);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_stop
+ ****************************************************************************/
+
+static int nrf52_tim_stop(FAR struct nrf52_tim_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_tim_putreg(dev, NRF52_TIM_TASKS_STOP_OFFSET, TIM_TASKS_STOP);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_clear
+ ****************************************************************************/
+
+static int nrf52_tim_clear(FAR struct nrf52_tim_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_tim_putreg(dev, NRF52_TIM_TASKS_CLEAR_OFFSET, TIM_TASKS_CLEAR);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_configure
+ ****************************************************************************/
+
+static int nrf52_tim_configure(FAR struct nrf52_tim_dev_s *dev, uint8_t mode,
+                               uint8_t width)
+{
+  uint32_t regval = 0;
+  int      ret    = OK;
+
+  DEBUGASSERT(dev);
+
+  /* Configure TIMER mode */
+
+  switch (mode)
+    {
+      case NRF52_TIM_MODE_UNUSED:
+        {
+          regval = 0;
+          break;
+        }
+
+      case NRF52_TIM_MODE_TIMER:
+        {
+          regval = TIM_MODE_TIMER;
+          break;
+        }
+
+      case NRF52_TIM_MODE_COUNTER:
+        {
+          regval = TIM_MODE_COUNTER;
+          break;
+        }
+
+      case NRF52_TIM_MODE_LOWPOWER:
+        {
+          regval = TIM_MODE_LPCOUNTER;
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported TIMER mode %d\n", mode);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_MODE_OFFSET, regval);
+
+  /* Configure TIMER width */
+
+  switch (width)
+    {
+      case NRF52_TIM_WIDTH_16B:
+        {
+          regval = TIM_BITMODE_16B;
+          break;
+        }
+
+      case NRF52_TIM_WIDTH_8B:
+        {
+          regval = TIM_BITMODE_8B;
+          break;
+        }
+
+      case NRF52_TIM_WIDTH_24B:
+        {
+          regval = TIM_BITMODE_24B;
+          break;
+        }
+
+      case NRF52_TIM_WIDTH_32B:
+        {
+          regval = TIM_BITMODE_32B;
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported TIMER width %d\n", width);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_BITMODE_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_shorts
+ ****************************************************************************/
+
+static int nrf52_tim_shorts(FAR struct nrf52_tim_dev_s *dev, uint8_t s,
+                            uint8_t i, bool en)
+{
+  uint32_t regval = 0;
+  uint32_t val    = 0;
+  int      ret    = OK;
+
+  regval = nrf52_tim_getreg(dev, NRF52_TIM_SHORTS_OFFSET);
+
+  switch (s)
+    {
+      case NRF52_TIM_SHORT_COMPARE_CLEAR:
+        {
+          val = TIM_SHORTS_COMPARE_CLEAR(i);
+          break;
+        }
+
+      case NRF52_TIM_SHORT_COMPARE_STOP:
+        {
+          val = TIM_SHORTS_COMPARE_STOP(i);
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported SHORT %d\n", s);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+  if (en == true)
+    {
+      regval |= val;
+    }
+  else
+    {
+      regval &= ~val;
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_SHORTS_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_count
+ ****************************************************************************/
+
+static int nrf52_tim_count(FAR struct nrf52_tim_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_tim_putreg(dev, NRF52_TIM_TASKS_COUNT_OFFSET, TIM_TASKS_COUNT);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_setcc
+ ****************************************************************************/
+
+static int nrf52_tim_setcc(FAR struct nrf52_tim_dev_s *dev, uint8_t i,
+                           uint32_t cc)
+{
+  FAR struct nrf52_tim_priv_s *tim = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  tim = (FAR struct nrf52_tim_priv_s *)dev;
+
+  /* Is the channel supported? */
+
+  if (i > tim->chan)
+    {
+      tmrerr("ERROR: unsupported TIMER channel %d\n", i);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_CC_OFFSET(i), cc);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_getcc
+ ****************************************************************************/
+
+static int nrf52_tim_getcc(FAR struct nrf52_tim_dev_s *dev, uint8_t i,
+                           FAR uint32_t *cc)
+{
+  FAR struct nrf52_tim_priv_s *tim = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+  DEBUGASSERT(cc);
+
+  tim = (FAR struct nrf52_tim_priv_s *)dev;
+
+  /* Is the channel supported? */
+
+  if (i > tim->chan)
+    {
+      tmrerr("ERROR: unsupported TIMER channel %d\n", i);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  *cc = nrf52_tim_getreg(dev, NRF52_TIM_CC_OFFSET(i));
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_setpre
+ ****************************************************************************/
+
+static int nrf52_tim_setpre(FAR struct nrf52_tim_dev_s *dev, uint8_t pre)
+{
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  if (pre < NRF52_TIM_PRE_16000000 || pre > NRF52_TIM_PRE_31250)
+    {
+      tmrerr("ERROR: unsupported TIMER prescaler %d\n", pre);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_PRESCALER_OFFSET, pre);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_setisr
+ ****************************************************************************/
+
+static int nrf52_tim_setisr(FAR struct nrf52_tim_dev_s *dev, xcpt_t handler,
+                            FAR void *arg)
+{
+  FAR struct nrf52_tim_priv_s *tim = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  tim = (FAR struct nrf52_tim_priv_s *)dev;
+
+  /* Disable interrupt when callback is removed */
+
+  if (!handler)
+    {
+      up_disable_irq(tim->irq);
+      irq_detach(tim->irq);
+      ret = OK;
+      goto errout;
+    }
+
+  /* Otherwise set callback and enable interrupt */
+
+  irq_attach(tim->irq, handler, arg);
+  up_enable_irq(tim->irq);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_enableint
+ ****************************************************************************/
+
+static int nrf52_tim_enableint(FAR struct nrf52_tim_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+  int      ret    = OK;
+
+  DEBUGASSERT(dev);
+
+  /* Get register value for given interrupt source */
+
+  regval = nrf52_tim_irq2reg(dev, s);
+  if (regval == 0)
+    {
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_INTENSET_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_disableint
+ ****************************************************************************/
+
+static int nrf52_tim_disableint(FAR struct nrf52_tim_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+  int      ret    = OK;
+
+  DEBUGASSERT(dev);
+
+  /* Get register value for given interrupt source */
+
+  regval = nrf52_tim_irq2reg(dev, s);
+  if (regval == 0)
+    {
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_tim_putreg(dev, NRF52_TIM_INTCLR_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_checkint
+ ****************************************************************************/
+
+static int nrf52_tim_checkint(FAR struct nrf52_tim_dev_s *dev, uint8_t s)
+{
+  int ret = 0;
+
+  DEBUGASSERT(dev);
+
+  switch (s)
+    {
+      case NRF52_TIM_INT_COMPARE0:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(0));
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE1:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(0));
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE2:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(2));
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE3:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(3));
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE4:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(4));
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE5:
+        {
+          ret = nrf52_tim_getreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(5));
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported IRQ source %d\n", s);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_ackint
+ ****************************************************************************/
+
+static int nrf52_tim_ackint(FAR struct nrf52_tim_dev_s *dev, uint8_t s)
+{
+  int ret = 0;
+
+  DEBUGASSERT(dev);
+
+  switch (s)
+    {
+      case NRF52_TIM_INT_COMPARE0:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(0), 0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE1:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(1), 0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE2:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(2), 0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE3:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(3), 0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE4:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(4), 0);
+          break;
+        }
+
+      case NRF52_TIM_INT_COMPARE5:
+        {
+          nrf52_tim_putreg(dev, NRF52_TIM_EVENTS_COMPARE_OFFSET(5), 0);
+          break;
+        }
+
+      default:
+        {
+          tmrerr("ERROR: unsupported IRQ source %d\n", s);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf52_tim_init
+ *
+ * Description:
+ *   Initialize TIMER device
+ *
+ ****************************************************************************/
+
+FAR struct nrf52_tim_dev_s *nrf52_tim_init(int timer)
+{
+  FAR struct nrf52_tim_priv_s *tim = NULL;
+
+  /* Get timer instance */
+
+  switch (timer)
+    {
+#ifdef CONFIG_NRF52_TIMER0
+      case 0:
+        {
+          tim = &g_nrf52_tim0_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_TIMER1
+      case 1:
+        {
+          tim = &g_nrf52_tim1_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_TIMER2
+      case 2:
+        {
+          tim = &g_nrf52_tim2_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_TIMER3
+      case 3:
+        {
+          tim = &g_nrf52_tim3_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_TIMER4
+      case 4:
+        {
+          tim = &g_nrf52_tim4_priv;
+          break;
+        }
+#endif
+
+      default:
+        {
+          tmrerr("ERROR: unsupported TIMER %d\n", timer);
+          goto errout;
+        }
+    }
+
+  if (tim->inuse != false)
+    {
+      /* Timer already in use */
+
+      tim = NULL;
+    }
+
+errout:
+  return (FAR struct nrf52_tim_dev_s *)tim;
+}
+
+/****************************************************************************
+ * Name: nrf52_tim_deinit
+ *
+ * Description:
+ *   Deinit TIMER device
+ *
+ ****************************************************************************/
+
+int nrf52_tim_deinit(FAR struct nrf52_tim_dev_s *dev)
+{
+  FAR struct nrf52_tim_priv_s *tim = NULL;
+
+  DEBUGASSERT(dev);
+
+  tim = (FAR struct nrf52_tim_priv_s *)dev;
+
+  tim->inuse = false;
+
+  return OK;
+}
diff --git a/arch/arm/src/nrf52/nrf52_tim.h b/arch/arm/src/nrf52/nrf52_tim.h
new file mode 100644
index 0000000..fe70887
--- /dev/null
+++ b/arch/arm/src/nrf52/nrf52_tim.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * arch/arm/src/nrf52/nrf52_tim.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_NRF52_NRF52_TIM_H
+#define __ARCH_ARM_SRC_NRF52_NRF52_TIM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <nuttx/irq.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Helpers ******************************************************************/
+
+#define NRF52_TIM_START(d)                ((d)->ops->start(d))
+#define NRF52_TIM_STOP(d)                 ((d)->ops->stop(d))
+#define NRF52_TIM_CLEAR(d)                ((d)->ops->clear(d))
+#define NRF52_TIM_CONFIGURE(d, m, w)      ((d)->ops->configure(d, m, w))
+#define NRF52_TIM_SHORTS(d, s, i, e)      ((d)->ops->shorts(d, s, i, e))
+#define NRF52_TIM_COUNT(d)                ((d)->ops->count(d))
+#define NRF52_TIM_SETCC(d, i, cc)         ((d)->ops->setcc(d, i, cc))
+#define NRF52_TIM_GETCC(d, i, cc)         ((d)->ops->setcc(d, i, cc))
+#define NRF52_TIM_SETPRE(d, pre)          ((d)->ops->setpre(d, pre))
+#define NRF52_TIM_SETISR(d, hnd, arg)     ((d)->ops->setisr(d, hnd, arg))
+#define NRF52_TIM_ENABLEINT(d, s)         ((d)->ops->enableint(d, s))
+#define NRF52_TIM_DISABLEINT(d, s)        ((d)->ops->disableint(d, s))
+#define NRF52_TIM_CHECKINT(d, s)          ((d)->ops->checkint(d, s))
+#define NRF52_TIM_ACKINT(d, s)            ((d)->ops->ackint(d, s))
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Timer mode */
+
+enum nrf52_tim_mode_e
+{
+  NRF52_TIM_MODE_UNUSED   = 0,
+  NRF52_TIM_MODE_TIMER    = 1,
+  NRF52_TIM_MODE_COUNTER  = 2,
+  NRF52_TIM_MODE_LOWPOWER = 3,
+};
+
+/* Timer bit width */
+
+enum nrf52_tim_width_e
+{
+  NRF52_TIM_WIDTH_16B    = 0,
+  NRF52_TIM_WIDTH_8B     = 1,
+  NRF52_TIM_WIDTH_24B    = 2,
+  NRF52_TIM_WIDTH_32B    = 3,
+};
+
+/* Timer CC index */
+
+enum nrf52_tim_cc_e
+{
+  NRF52_TIM_CC0 = 0,
+  NRF52_TIM_CC1 = 1,
+  NRF52_TIM_CC2 = 2,
+  NRF52_TIM_CC3 = 3,
+  NRF52_TIM_CC4 = 4,
+  NRF52_TIM_CC5 = 5
+};
+
+/* Timer IRQ source */
+
+enum nrf52_tim_irq_e
+{
+  NRF52_TIM_INT_COMPARE0 = 0,
+  NRF52_TIM_INT_COMPARE1 = 1,
+  NRF52_TIM_INT_COMPARE2 = 2,
+  NRF52_TIM_INT_COMPARE3 = 3,
+  NRF52_TIM_INT_COMPARE4 = 4,
+  NRF52_TIM_INT_COMPARE5 = 5,
+};
+
+/* Timer shorts type */
+
+enum nrf52_tim_shorts_e
+{
+  NRF52_TIM_SHORT_COMPARE_CLEAR = 1,
+  NRF52_TIM_SHORT_COMPARE_STOP  = 2
+};
+
+/* Timer frequency prescaler */
+
+enum nrf52_tim_pre_e
+{
+  NRF52_TIM_PRE_16000000 = 0,
+  NRF52_TIM_PRE_8000000  = 1,
+  NRF52_TIM_PRE_4000000  = 2,
+  NRF52_TIM_PRE_2000000  = 3,
+  NRF52_TIM_PRE_1000000  = 4,
+  NRF52_TIM_PRE_500000   = 5,
+  NRF52_TIM_PRE_250000   = 6,
+  NRF52_TIM_PRE_125000   = 7,
+  NRF52_TIM_PRE_62500    = 8,
+  NRF52_TIM_PRE_31250    = 9
+};
+
+/* NRF52 TIM device */
+
+struct nrf52_tim_dev_s
+{
+  struct nrf52_tim_ops_s *ops;
+};
+
+/* NRF52 TIM ops */
+
+struct nrf52_tim_ops_s
+{
+  /* Timer tasks */
+
+  CODE int (*start)(FAR struct nrf52_tim_dev_s *dev);
+  CODE int (*stop)(FAR struct nrf52_tim_dev_s *dev);
+  CODE int (*clear)(FAR struct nrf52_tim_dev_s *dev);
+
+  /* Timer configuration */
+
+  CODE int (*configure)(FAR struct nrf52_tim_dev_s *dev, uint8_t mode,
+                        uint8_t width);
+  CODE int (*shorts)(FAR struct nrf52_tim_dev_s *dev, uint8_t s,
+                     uint8_t i, bool en);
+
+  /* Timer operations */
+
+  CODE int (*count)(FAR struct nrf52_tim_dev_s *dev);
+  CODE int (*setcc)(FAR struct nrf52_tim_dev_s *dev, uint8_t i, uint32_t cc);
+  CODE int (*getcc)(FAR struct nrf52_tim_dev_s *dev, uint8_t i,
+                    FAR uint32_t *cc);
+  CODE int (*setpre)(FAR struct nrf52_tim_dev_s *dev, uint8_t pre);
+
+  /* Timer interrupts */
+
+  CODE int (*setisr)(FAR struct nrf52_tim_dev_s *dev, xcpt_t handler,
+                     FAR void * arg);
+  CODE int (*enableint)(FAR struct nrf52_tim_dev_s *dev, uint8_t source);
+  CODE int (*disableint)(FAR struct nrf52_tim_dev_s *dev, uint8_t source);
+  CODE int (*checkint)(FAR struct nrf52_tim_dev_s *dev, uint8_t source);
+  CODE int (*ackint)(FAR struct nrf52_tim_dev_s *dev, uint8_t source);
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+FAR struct nrf52_tim_dev_s *nrf52_tim_init(int timer);
+int nrf52_tim_deinit(FAR struct nrf52_tim_dev_s *dev);
+
+#endif /* __ARCH_ARM_SRC_NRF52_NRF52_TIM_H */


[incubator-nuttx] 02/03: boards/arm/nrf52/nrf52840-dk: add highpri example configuration

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit f6235c52f73cde8bf7149250759e23c765c832ef
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Jul 18 10:03:44 2020 +0200

    boards/arm/nrf52/nrf52840-dk: add highpri example configuration
---
 boards/arm/nrf52/nrf52840-dk/Kconfig               |   4 +
 .../nrf52/nrf52840-dk/configs/highpri/defconfig    |  48 ++++
 .../arm/nrf52/nrf52840-dk/scripts/flash_config.ld  |   6 +
 boards/arm/nrf52/nrf52840-dk/src/Makefile          |   4 +
 boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c   | 303 +++++++++++++++++++++
 5 files changed, 365 insertions(+)

diff --git a/boards/arm/nrf52/nrf52840-dk/Kconfig b/boards/arm/nrf52/nrf52840-dk/Kconfig
index 52b4e6b..12fe14e 100644
--- a/boards/arm/nrf52/nrf52840-dk/Kconfig
+++ b/boards/arm/nrf52/nrf52840-dk/Kconfig
@@ -5,4 +5,8 @@
 
 if ARCH_BOARD_NRF52840_DK
 
+config NRF52840DK_HIGHPRI
+	bool "High priority interrupt test"
+	default n
+
 endif
diff --git a/boards/arm/nrf52/nrf52840-dk/configs/highpri/defconfig b/boards/arm/nrf52/nrf52840-dk/configs/highpri/defconfig
new file mode 100644
index 0000000..9c35757
--- /dev/null
+++ b/boards/arm/nrf52/nrf52840-dk/configs/highpri/defconfig
@@ -0,0 +1,48 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nrf52840-dk"
+CONFIG_ARCH_BOARD_NRF52840_DK=y
+CONFIG_ARCH_CHIP="nrf52"
+CONFIG_ARCH_CHIP_NRF52840=y
+CONFIG_ARCH_CHIP_NRF52=y
+CONFIG_ARCH_HIPRI_INTERRUPT=y
+CONFIG_ARCH_RAMVECTORS=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_STDARG_H=y
+CONFIG_BOARDCTL_MKRD=y
+CONFIG_BOARD_LOOPSPERMSEC=5500
+CONFIG_FAT_LCNAMES=y
+CONFIG_FAT_LFN=y
+CONFIG_FS_FAT=y
+CONFIG_LIB_BOARDCTL=y
+CONFIG_MAX_TASKS=16
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_MM_REGIONS=2
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NRF52840DK_HIGHPRI=y
+CONFIG_NRF52_TIMER0=y
+CONFIG_NRF52_UART0=y
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=4
+CONFIG_RAM_SIZE=65535
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_START_DAY=26
+CONFIG_START_MONTH=3
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="highpri_main"
+CONFIG_WDOG_INTRESERVE=0
diff --git a/boards/arm/nrf52/nrf52840-dk/scripts/flash_config.ld b/boards/arm/nrf52/nrf52840-dk/scripts/flash_config.ld
index 23acb1c..ac347f0 100644
--- a/boards/arm/nrf52/nrf52840-dk/scripts/flash_config.ld
+++ b/boards/arm/nrf52/nrf52840-dk/scripts/flash_config.ld
@@ -82,6 +82,12 @@ SECTIONS
 
     _eronly = ABSOLUTE(.);
 
+    /* The RAM vector table (if present) should lie at the beginning of SRAM */
+
+    .ram_vectors : {
+        *(.ram_vectors)
+    } > datamem
+
     .data :
     {
         _sdata = ABSOLUTE(.);
diff --git a/boards/arm/nrf52/nrf52840-dk/src/Makefile b/boards/arm/nrf52/nrf52840-dk/src/Makefile
index 06f3004..08441a6 100644
--- a/boards/arm/nrf52/nrf52840-dk/src/Makefile
+++ b/boards/arm/nrf52/nrf52840-dk/src/Makefile
@@ -71,4 +71,8 @@ ifeq ($(CONFIG_LPWAN_SX127X),y)
 CSRCS += nrf52_sx127x.c
 endif
 
+ifeq ($(CONFIG_NRF52840DK_HIGHPRI),y)
+CSRCS += nrf52_highpri.c
+endif
+
 include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c b/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c
new file mode 100644
index 0000000..5420939
--- /dev/null
+++ b/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c
@@ -0,0 +1,303 @@
+/****************************************************************************
+ * boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.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 <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/signal.h>
+
+#include <arch/irq.h>
+#include <arch/armv7-m/nvicpri.h>
+
+#include "arm_internal.h"
+#include "ram_vectors.h"
+
+#include "nrf52_tim.h"
+
+#include <arch/board/board.h>
+
+#ifdef CONFIG_NRF52840DK_HIGHPRI
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_ARCH_HIPRI_INTERRUPT
+#  error CONFIG_ARCH_HIPRI_INTERRUPT is required
+#endif
+
+#ifndef CONFIG_ARCH_RAMVECTORS
+#  error CONFIG_ARCH_RAMVECTORS is required
+#endif
+
+#ifndef CONFIG_ARCH_IRQPRIO
+#  error CONFIG_ARCH_IRQPRIO is required
+#endif
+
+#ifndef CONFIG_NRF52_TIMER0
+#  error CONFIG_NRF52_TIMER0 is required
+#endif
+
+/* Timer configuration */
+
+#define NRF52_HIGHPRI_TIMER     (0)
+#define NRF52_HIGHPRI_TIMER_IRQ (NRF52_IRQ_TIMER0)
+#define NRF52_TIMER_PRESCALER   (NRF52_TIM_PRE_16000000)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct highpri_s
+{
+  FAR struct nrf52_tim_dev_s *dev;
+  volatile uint64_t           basepri[16];
+  volatile uint64_t           handler;
+  volatile uint64_t           thread;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct highpri_s g_highpri;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: timer_handler
+ *
+ * Description:
+ *   This is the handler for the high speed TIMER0 interrupt.
+ *
+ ****************************************************************************/
+
+void timer_handler(void)
+{
+  uint8_t basepri;
+  int     index;
+  int     ret;
+
+  /* Verify interrupt source */
+
+  ret = NRF52_TIM_CHECKINT(g_highpri.dev, NRF52_TIM_CC0);
+  if (ret != 1)
+    {
+      DEBUGASSERT(0);
+    }
+
+  /* Increment the count associated with the current basepri */
+
+  basepri = getbasepri();
+  index   = ((basepri >> 4) & 15);
+  g_highpri.basepri[index]++;
+
+  /* Check if we are in an interrupt handle */
+
+  if (up_interrupt_context())
+    {
+      g_highpri.handler++;
+    }
+  else
+    {
+      g_highpri.thread++;
+    }
+
+  /* Clear event */
+
+  NRF52_TIM_ACKINT(g_highpri.dev, NRF52_TIM_CC0);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: highpri_main
+ *
+ * Description:
+ *   Main entry point in into the high priority interrupt test.
+ *
+ ****************************************************************************/
+
+int highpri_main(int argc, char *argv[])
+{
+  FAR struct nrf52_tim_dev_s *tim = NULL;
+  uint64_t basepri[16];
+  uint64_t handler;
+  uint64_t thread;
+  uint64_t total;
+  uint32_t seconds;
+  int      ret;
+  int      i;
+
+  /* Initialzie TIMER */
+
+  tim = nrf52_tim_init(NRF52_HIGHPRI_TIMER);
+  if (tim == NULL)
+    {
+      printf("ERROR: failed to initialize TIMER%d instance\n",
+             NRF52_HIGHPRI_TIMER);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  g_highpri.dev = tim;
+
+  /* Configure TIMER mode and width */
+
+  ret = NRF52_TIM_CONFIGURE(tim, NRF52_TIM_MODE_TIMER, NRF52_TIM_WIDTH_16B);
+  if (ret < 0)
+    {
+      printf("ERROR: failed to configure timer %d\n", ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Configure TIMER prescaler */
+
+  ret = NRF52_TIM_SETPRE(tim, NRF52_TIMER_PRESCALER);
+  if (ret < 0)
+    {
+      printf("ERROR: failed to set timer prescaler %d\n", ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Set TIMER CC0 */
+
+  ret = NRF52_TIM_SETCC(tim, NRF52_TIM_CC0, 0x01);
+  if (ret < 0)
+    {
+      printf("ERROR: failed to set TIMER CC %d\n", ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Enable IRQ for TIMER CC0 */
+
+  ret = NRF52_TIM_ENABLEINT(tim, NRF52_TIM_INT_COMPARE0);
+  if (ret < 0)
+    {
+      printf("ERROR: failed to enable TIMER0 CC IRQ %d\n", ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Attach TIMER ram vector */
+
+  ret = arm_ramvec_attach(NRF52_HIGHPRI_TIMER_IRQ, timer_handler);
+  if (ret < 0)
+    {
+      fprintf(stderr, "highpri_main: ERROR: arm_ramvec_attach failed: %d\n",
+              ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Set the priority of the TIM6 interrupt vector */
+
+  ret = up_prioritize_irq(NRF52_HIGHPRI_TIMER_IRQ, NVIC_SYSH_HIGH_PRIORITY);
+  if (ret < 0)
+    {
+      fprintf(stderr, "highpri_main: ERROR: up_prioritize_irq failed: %d\n",
+              ret);
+      ret = EXIT_FAILURE;
+      goto errout;
+    }
+
+  /* Enable the timer interrupt at the NVIC and at TIMER */
+
+  up_enable_irq(NRF52_HIGHPRI_TIMER_IRQ);
+  NRF52_TIM_START(tim);
+
+  seconds = 0;
+
+  while (1)
+    {
+      /* Flush stdout and wait a bit */
+
+      fflush(stdout);
+      nxsig_sleep(1);
+      seconds++;
+
+      /* Sample counts so that they are not volatile.  Missing a count now
+       * and then is a normal consequence of this design.
+       */
+
+      for (i = 0; i < 16; i++)
+        {
+          basepri[i] = g_highpri.basepri[i];
+        }
+
+      handler = g_highpri.handler;
+      thread  = g_highpri.thread;
+
+      /* Then print out what is happening */
+
+      printf("Elapsed time: %d seconds\n\n", seconds);
+      for (i = 0, total = 0; i < 16; i++)
+        {
+          total += basepri[i];
+        }
+
+      if (total > 0)
+        {
+          for (i = 0; i < 16; i++)
+            {
+              if (basepri[i] > 0)
+                {
+                  printf("  basepri[%02x]: %lld (%d%%)\n",
+                         i << 4, basepri[i],
+                         (int)((100 * basepri[i] + (total / 2)) / total));
+                }
+            }
+        }
+
+      total = handler + thread;
+      if (total > 0)
+        {
+          printf("  Handler:     %lld (%d%%)\n",
+                 handler,  (int)((100*handler + (total / 2)) / total));
+          printf("  Thread:      %lld (%d%%)\n\n",
+                 thread,   (int)((100*thread + (total / 2)) / total));
+        }
+    }
+
+  ret = EXIT_SUCCESS;
+
+errout:
+  return ret;
+}
+
+#endif /* CONFIG_NRF52840DK_HIGHPRI */


[incubator-nuttx] 03/03: arch/arm/src/nrf52: add a low-level RTC interface

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 774ea6eae748db370b265136612a8ad70036ab06
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Jul 18 10:05:46 2020 +0200

    arch/arm/src/nrf52: add a low-level RTC interface
---
 arch/arm/src/nrf52/Kconfig              |   7 +
 arch/arm/src/nrf52/Make.defs            |   4 +
 arch/arm/src/nrf52/hardware/nrf52_rtc.h | 108 +++++
 arch/arm/src/nrf52/nrf52_rtc.c          | 672 ++++++++++++++++++++++++++++++++
 arch/arm/src/nrf52/nrf52_rtc.h          | 119 ++++++
 5 files changed, 910 insertions(+)

diff --git a/arch/arm/src/nrf52/Kconfig b/arch/arm/src/nrf52/Kconfig
index acd40f2..effdea6 100644
--- a/arch/arm/src/nrf52/Kconfig
+++ b/arch/arm/src/nrf52/Kconfig
@@ -94,6 +94,10 @@ config NRF52_TIMER
 	bool
 	default n
 
+config NRF52_RTC
+	bool
+	default n
+
 config NRF52_SPI_MASTER_WORKAROUND_1BYTE_TRANSFER
 	bool "SPI Master 1 Byte transfer anomaly workaround"
 	depends on NRF52_SPI_MASTER && ARCH_FAMILY_NRF52832
@@ -210,14 +214,17 @@ config NRF52_TIMER4
 
 config NRF52_RTC0
 	bool "RTC0"
+	select NRF52_RTC
 	default n
 
 config NRF52_RTC1
 	bool "RTC1"
+	select NRF52_RTC
 	default n
 
 config NRF52_RTC2
 	bool "RTC2"
+	select NRF52_RTC
 	default n
 
 config NRF52_I2S
diff --git a/arch/arm/src/nrf52/Make.defs b/arch/arm/src/nrf52/Make.defs
index 74f172a..ecdfa7c 100644
--- a/arch/arm/src/nrf52/Make.defs
+++ b/arch/arm/src/nrf52/Make.defs
@@ -133,3 +133,7 @@ endif
 ifeq ($(CONFIG_NRF52_TIMER),y)
 CHIP_CSRCS += nrf52_tim.c
 endif
+
+ifeq ($(CONFIG_NRF52_RTC),y)
+CHIP_CSRCS += nrf52_rtc.c
+endif
diff --git a/arch/arm/src/nrf52/hardware/nrf52_rtc.h b/arch/arm/src/nrf52/hardware/nrf52_rtc.h
new file mode 100644
index 0000000..b6c79e5
--- /dev/null
+++ b/arch/arm/src/nrf52/hardware/nrf52_rtc.h
@@ -0,0 +1,108 @@
+/************************************************************************************
+ * arch/arm/src/nrf52/hardware/nrf52_rtc.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_NRF52_HARDWARE_NRF52_RTC_H
+#define __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_RTC_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/nrf52_memorymap.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register offsets for RTC *********************************************************/
+
+#define NRF52_RTC_TASKS_START_OFFSET       0x0000                  /* Start RTC counter */
+#define NRF52_RTC_TASKS_STOP_OFFSET        0x0004                  /* Stop RTC counter */
+#define NRF52_RTC_TASKS_CLEAR_OFFSET       0x0008                  /* Clear RTC counter */
+#define NRF52_RTC_TASKS_TRIGOVRFLW_OFFSET  0x000c                  /* Clear Set counter to 0xfffff0 */
+#define NRF52_RTC_EVENTS_TICK_OFFSET       0x0100                  /* Event on counter increment */
+#define NRF52_RTC_EVENTS_OVRFLW_OFFSET     0x0104                  /* Event on counter overflow */
+#define NRF52_RTC_EVENTS_COMPARE_OFFSET(x) (0x0140 + ((x) * 0x04)) /* Compare event on CC[x] match */
+#define NRF52_RTC_INTENSET_OFFSET          0x0304                  /* Enable interrupt */
+#define NRF52_RTC_INTENCLR_OFFSET          0x0308                  /* Disable interrupt */
+#define NRF52_RTC_EVTEN_OFFSET             0x0340                  /* Enable or disable event routing */
+#define NRF52_RTC_EVTENSET_OFFSET          0x0344                  /* Enable event routing */
+#define NRF52_RTC_EVTENCLR_OFFSET          0x0348                  /* Disable event routing */
+#define NRF52_RTC_COUNTER_OFFSET           0x0504                  /* Current counter value */
+#define NRF52_RTC_PRESCALER_OFFSET         0x0508                  /* 12 bit prescaler for counter frequency */
+#define NRF52_RTC_CC_OFFSET(x)             (0x0540 + ((x) * 0x04)) /* Compare register x */
+
+/* Register offsets for RTC *********************************************************/
+
+/* TASKS_START Register */
+
+#define RTC_TASKS_START            (1 << 0)                        /* Bit 0: Start RTC counter */
+
+/* TASKS_STOP Register */
+
+#define RTC_TASKS_STOP             (1 << 0)                        /* Bit 0: Stop RTC counter */
+
+/* TASKS_CLEAR Register */
+
+#define RTC_TASKS_CLEAR            (1 << 0)                        /* Bit 0: Clear RTC counter */
+
+/* TASKS_TRIGOVRFLW Register */
+
+#define RTC_TASKS_TRIGOVRFLW       (1 << 0)                        /* Bit 0: Set counter to 0xfffff0 */
+
+/* EVENTS_TICK Register */
+
+#define RTC_EVENTS_TICK            (1 << 0)                        /* Bit 0: Event on counter increment */
+
+/* EVENTS_OVRFLW Register */
+
+#define RTC_EVENTS_OVRFLW          (1 << 0)                        /* Bit 0: Event on counter overflow */
+
+/* EVENTS_COMPARE Register */
+
+#define RTC_EVENTS_COMPARE         (1 << 0)                        /* Bit 0: Eompare event on CC[x] match */
+
+/* INTENSET/INTENCLR Register */
+
+#define RTC_INT_TICK               (1 << 0)                        /* Bit 0: TICK interrupt*/
+#define RTC_INT_OVRFLW             (1 << 1)                        /* Bit 1: OVRFLW interrupt */
+#define RTC_INT_COMPARE(x)         (1 << (16 + (x)))               /* Bit 16-19: COMPARE[x] interrupt */
+
+/* EVTEN/EVTENSET/EVTSENCLR Register */
+
+#define RTC_EVTEN_TICK             (1 << 0)                        /* Bit 0: TICK event */
+#define RTC_EVTEN_OVRFLW           (1 << 1)                        /* Bit 1: OVRFLW event */
+#define RTC_EVTEN_COMPARE(x)       (1 << (16 + (x)))               /* Bit 16-19: COMPARE[x] event */
+
+/* COUNTER Register */
+
+#define RTC_COUNTER_MASK           (0x00ffffff)                    /* Bits 0-23: Counter value */
+
+/* PRESCALER Register */
+
+#define RTC_PRESCALER_MASK         (0x00000fff)                    /* Bits 0-11: Prescaler value */
+#define RTC_PRESCALER_MAX          (0x00000fff)
+
+/* CC Register */
+
+#define RTC_CC_MASK                (0x00ffffff)                    /* Bits 0-23: Comapre register */
+
+#endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_RTC_H */
diff --git a/arch/arm/src/nrf52/nrf52_rtc.c b/arch/arm/src/nrf52/nrf52_rtc.c
new file mode 100644
index 0000000..51f9b99
--- /dev/null
+++ b/arch/arm/src/nrf52/nrf52_rtc.c
@@ -0,0 +1,672 @@
+/****************************************************************************
+ * arch/arm/src/nrf52/nrf52_rtc.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 <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "arm_arch.h"
+
+#include "hardware/nrf52_rtc.h"
+
+#include "nrf52_rtc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct nrf52_rtc_priv_s
+{
+  FAR struct nrf52_rtc_ops_s *ops;
+  uint32_t                    base;
+  uint32_t                    irq;
+  uint8_t                     chan;
+  bool                        inuse;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* RTC registers access *****************************************************/
+
+static uint32_t nrf52_rtc_getreg(FAR struct nrf52_rtc_dev_s *dev,
+                                 uint32_t offset);
+static void nrf52_rtc_putreg(FAR struct nrf52_rtc_dev_s *dev,
+                             uint32_t offset,
+                             uint32_t value);
+
+/* RTC helpers **************************************************************/
+
+static uint32_t nrf52_rtc_irq2reg(FAR struct nrf52_rtc_dev_s *dev,
+                                  uint8_t s);
+
+/* RTC operations ***********************************************************/
+
+static int nrf52_rtc_start(FAR struct nrf52_rtc_dev_s *dev);
+static int nrf52_rtc_stop(FAR struct nrf52_rtc_dev_s *dev);
+static int nrf52_rtc_clear(FAR struct nrf52_rtc_dev_s *dev);
+static int nrf52_rtc_trgovrflw(FAR struct nrf52_rtc_dev_s *dev);
+static int nrf52_rtc_setcc(FAR struct nrf52_rtc_dev_s *dev, uint8_t i,
+                           uint32_t cc);
+static int nrf52_rtc_getcc(FAR struct nrf52_rtc_dev_s *dev, uint8_t i,
+                           FAR uint32_t *cc);
+static int nrf52_rtc_setpre(FAR struct nrf52_rtc_dev_s *dev, uint16_t pre);
+static int nrf52_rtc_setisr(FAR struct nrf52_rtc_dev_s *dev, xcpt_t handler,
+                            FAR void * arg);
+static int nrf52_rtc_enableint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s);
+static int nrf52_rtc_disableint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s);
+static int nrf52_rtc_checkint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s);
+static int nrf52_rtc_ackint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* NRF52 RTC ops */
+
+struct nrf52_rtc_ops_s nrf52_rtc_ops =
+{
+  .start      = nrf52_rtc_start,
+  .stop       = nrf52_rtc_stop,
+  .clear      = nrf52_rtc_clear,
+  .trgovrflw  = nrf52_rtc_trgovrflw,
+  .setcc      = nrf52_rtc_setcc,
+  .getcc      = nrf52_rtc_getcc,
+  .setpre     = nrf52_rtc_setpre,
+  .setisr     = nrf52_rtc_setisr,
+  .enableint  = nrf52_rtc_enableint,
+  .disableint = nrf52_rtc_disableint,
+  .checkint   = nrf52_rtc_checkint,
+  .ackint     = nrf52_rtc_ackint
+};
+
+#ifdef CONFIG_NRF52_RTC0
+/* RTC0 */
+
+struct nrf52_rtc_priv_s g_nrf52_rtc0_priv =
+{
+  .ops   = &nrf52_rtc_ops,
+  .base  = NRF52_RTC0_BASE,
+  .irq   = NRF52_IRQ_RTC0,
+  .chan  = 3,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_RTC1
+/* RTC1 */
+
+struct nrf52_rtc_priv_s g_nrf52_rtc1_priv =
+{
+  .ops   = &nrf52_rtc_ops,
+  .base  = NRF52_RTC1_BASE,
+  .irq   = NRF52_IRQ_RTC1,
+  .chan  = 4,
+  .inuse = false,
+};
+#endif
+
+#ifdef CONFIG_NRF52_RTC2
+/* RTC2 */
+
+struct nrf52_rtc_priv_s g_nrf52_rtc2_priv =
+{
+  .ops   = &nrf52_rtc_ops,
+  .base  = NRF52_RTC2_BASE,
+  .irq   = NRF52_IRQ_RTC2,
+  .chan  = 4,
+  .inuse = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf52_rtc_getreg
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static uint32_t nrf52_rtc_getreg(FAR struct nrf52_rtc_dev_s *dev,
+                                 uint32_t offset)
+{
+  DEBUGASSERT(dev);
+
+  return getreg32(((struct nrf52_rtc_priv_s *)dev)->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_putreg
+ *
+ * Description:
+ *   Put a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static void nrf52_rtc_putreg(FAR struct nrf52_rtc_dev_s *dev,
+                             uint32_t offset,
+                             uint32_t value)
+{
+  DEBUGASSERT(dev);
+
+  putreg32(value, ((struct nrf52_rtc_priv_s *)dev)->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_irq2reg
+ *
+ * Description:
+ *   Get the vaule of the interrupt register corresponding to the given
+ *   interrupt source
+ *
+ ****************************************************************************/
+
+static uint32_t nrf52_rtc_irq2reg(FAR struct nrf52_rtc_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+
+  switch (s)
+    {
+      case NRF52_RTC_INT_TICK:
+        {
+          regval = RTC_INT_TICK;
+          break;
+        }
+
+      case NRF52_RTC_INT_OVRFLW:
+        {
+          regval = RTC_INT_OVRFLW;
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE0:
+        {
+          regval = RTC_INT_COMPARE(0);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE1:
+        {
+          regval = RTC_INT_COMPARE(1);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE2:
+        {
+          regval = RTC_INT_COMPARE(2);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE3:
+        {
+          regval = RTC_INT_COMPARE(3);
+          break;
+        }
+
+      default:
+        {
+          rtcerr("ERROR: unsupported IRQ source %d\n", s);
+          regval = 0;
+          goto errout;
+        }
+    }
+
+errout:
+  return regval;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_start
+ ****************************************************************************/
+
+static int nrf52_rtc_start(FAR struct nrf52_rtc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_TASKS_START_OFFSET, RTC_TASKS_START);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_stop
+ ****************************************************************************/
+
+static int nrf52_rtc_stop(FAR struct nrf52_rtc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_TASKS_STOP_OFFSET, RTC_TASKS_STOP);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_clear
+ ****************************************************************************/
+
+static int nrf52_rtc_clear(FAR struct nrf52_rtc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_TASKS_CLEAR_OFFSET, RTC_TASKS_CLEAR);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_trgovrflw
+ ****************************************************************************/
+
+static int nrf52_rtc_trgovrflw(FAR struct nrf52_rtc_dev_s *dev)
+{
+  DEBUGASSERT(dev);
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_TASKS_TRIGOVRFLW_OFFSET,
+                   RTC_TASKS_TRIGOVRFLW);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_setcc
+ ****************************************************************************/
+
+static int nrf52_rtc_setcc(FAR struct nrf52_rtc_dev_s *dev, uint8_t i,
+                           uint32_t cc)
+{
+  FAR struct nrf52_rtc_priv_s *rtc = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  rtc = (FAR struct nrf52_rtc_priv_s *)dev;
+
+  /* Is the channel supported? */
+
+  if (i > rtc->chan)
+    {
+      rtcerr("ERROR: unsupported RTCER channel %d\n", i);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_CC_OFFSET(i), cc);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_getcc
+ ****************************************************************************/
+
+static int nrf52_rtc_getcc(FAR struct nrf52_rtc_dev_s *dev, uint8_t i,
+                           FAR uint32_t *cc)
+{
+  FAR struct nrf52_rtc_priv_s *rtc = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+  DEBUGASSERT(cc);
+
+  rtc = (FAR struct nrf52_rtc_priv_s *)dev;
+
+  /* Is the channel supported? */
+
+  if (i > rtc->chan)
+    {
+      rtcerr("ERROR: unsupported RTCER channel %d\n", i);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  *cc = nrf52_rtc_getreg(dev, NRF52_RTC_CC_OFFSET(i));
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_setpre
+ ****************************************************************************/
+
+static int nrf52_rtc_setpre(FAR struct nrf52_rtc_dev_s *dev, uint16_t pre)
+{
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  if (pre > RTC_PRESCALER_MAX)
+    {
+      rtcerr("ERROR: unsupported RTC prescaler %d\n", pre);
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_PRESCALER_OFFSET, pre);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_setisr
+ ****************************************************************************/
+
+static int nrf52_rtc_setisr(FAR struct nrf52_rtc_dev_s *dev, xcpt_t handler,
+                            FAR void *arg)
+{
+  FAR struct nrf52_rtc_priv_s *rtc = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(dev);
+
+  rtc = (FAR struct nrf52_rtc_priv_s *)dev;
+
+  /* Disable interrupt when callback is removed */
+
+  if (!handler)
+    {
+      up_disable_irq(rtc->irq);
+      irq_detach(rtc->irq);
+      ret = OK;
+      goto errout;
+    }
+
+  /* Otherwise set callback and enable interrupt */
+
+  irq_attach(rtc->irq, handler, arg);
+  up_enable_irq(rtc->irq);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_enableint
+ ****************************************************************************/
+
+static int nrf52_rtc_enableint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+  int      ret    = OK;
+
+  DEBUGASSERT(dev);
+
+  /* Get register value for given interrupt source */
+
+  regval = nrf52_rtc_irq2reg(dev, s);
+  if (regval == 0)
+    {
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_INTENSET_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_disableint
+ ****************************************************************************/
+
+static int nrf52_rtc_disableint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s)
+{
+  uint32_t regval = 0;
+  int      ret    = OK;
+
+  DEBUGASSERT(dev);
+
+  /* Get register value for given interrupt source */
+
+  regval = nrf52_rtc_irq2reg(dev, s);
+  if (regval == 0)
+    {
+      ret = -EINVAL;
+      goto errout;
+    }
+
+  nrf52_rtc_putreg(dev, NRF52_RTC_INTENCLR_OFFSET, regval);
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_checkint
+ ****************************************************************************/
+
+static int nrf52_rtc_checkint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s)
+{
+  int ret = 0;
+
+  DEBUGASSERT(dev);
+
+  switch (s)
+    {
+      case NRF52_RTC_INT_TICK:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_TICK_OFFSET);
+          break;
+        }
+
+      case NRF52_RTC_INT_OVRFLW:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_OVRFLW_OFFSET);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE0:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(0));
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE1:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(0));
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE2:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(2));
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE3:
+        {
+          ret = nrf52_rtc_getreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(3));
+          break;
+        }
+
+      default:
+        {
+          rtcerr("ERROR: unsupported IRQ source %d\n", s);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_ackint
+ ****************************************************************************/
+
+static int nrf52_rtc_ackint(FAR struct nrf52_rtc_dev_s *dev, uint8_t s)
+{
+  int ret = 0;
+
+  DEBUGASSERT(dev);
+
+  switch (s)
+    {
+      case NRF52_RTC_INT_TICK:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_TICK_OFFSET, 0);
+          break;
+        }
+
+      case NRF52_RTC_INT_OVRFLW:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_OVRFLW_OFFSET, 0);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE0:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(0), 0);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE1:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(1), 0);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE2:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(2), 0);
+          break;
+        }
+
+      case NRF52_RTC_INT_COMPARE3:
+        {
+          nrf52_rtc_putreg(dev, NRF52_RTC_EVENTS_COMPARE_OFFSET(3), 0);
+          break;
+        }
+
+      default:
+        {
+          rtcerr("ERROR: unsupported IRQ source %d\n", s);
+          ret = -EINVAL;
+          goto errout;
+        }
+    }
+
+errout:
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf52_rtc_init
+ *
+ * Description:
+ *   Initialize RTC device
+ *
+ ****************************************************************************/
+
+FAR struct nrf52_rtc_dev_s *nrf52_rtc_init(int rtc)
+{
+  FAR struct nrf52_rtc_priv_s *priv = NULL;
+
+  /* Get RTC instance */
+
+  switch (rtc)
+    {
+#ifdef CONFIG_NRF52_RTC0
+      case 0:
+        {
+          priv = &g_nrf52_rtc0_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_RTC1
+      case 1:
+        {
+          priv = &g_nrf52_rtc1_priv;
+          break;
+        }
+#endif
+
+#ifdef CONFIG_NRF52_RTC2
+      case 2:
+        {
+          priv = &g_nrf52_rtc2_priv;
+          break;
+        }
+#endif
+
+      default:
+        {
+          rtcerr("ERROR: unsupported RTC %d\n", rtc);
+          goto errout;
+        }
+    }
+
+  if (priv->inuse != false)
+    {
+      /* RTC already in use */
+
+      priv = NULL;
+    }
+
+errout:
+  return (FAR struct nrf52_rtc_dev_s *)priv;
+}
+
+/****************************************************************************
+ * Name: nrf52_rtc_deinit
+ *
+ * Description:
+ *   Deinit RTC device
+ *
+ ****************************************************************************/
+
+int nrf52_rtc_deinit(FAR struct nrf52_rtc_dev_s *dev)
+{
+  FAR struct nrf52_rtc_priv_s *rtc = NULL;
+
+  DEBUGASSERT(dev);
+
+  rtc = (FAR struct nrf52_rtc_priv_s *)dev;
+
+  rtc->inuse = false;
+
+  return OK;
+}
diff --git a/arch/arm/src/nrf52/nrf52_rtc.h b/arch/arm/src/nrf52/nrf52_rtc.h
new file mode 100644
index 0000000..03dbb26
--- /dev/null
+++ b/arch/arm/src/nrf52/nrf52_rtc.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * arch/arm/src/nrf52/nrf52_rtc.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_NRF52_NRF52_RTC_H
+#define __ARCH_ARM_SRC_NRF52_NRF52_RTC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Helpers ******************************************************************/
+
+#define NRF52_RTC_START(d)                ((d)->ops->start(d))
+#define NRF52_RTC_STOP(d)                 ((d)->ops->stop(d))
+#define NRF52_RTC_CLEAR(d)                ((d)->ops->clear(d))
+#define NRF52_RTC_TRGOVRFLW(d)            ((d)->ops->trgovrflw(d))
+#define NRF52_RTC_SETCC(d, i, cc)         ((d)->ops->setcc(d, i, cc))
+#define NRF52_RTC_GETCC(d, i, cc)         ((d)->ops->setcc(d, i, cc))
+#define NRF52_RTC_SETPRE(d, pre)          ((d)->ops->setpre(d, pre))
+#define NRF52_RTC_SETISR(d, hnd, arg, s)  ((d)->ops->setisr(d, hnd, arg, s))
+#define NRF52_RTC_ENABLEINT(d, s)         ((d)->ops->enableint(d, s))
+#define NRF52_RTC_DISABLEINT(d, s)        ((d)->ops->disableint(d, s))
+#define NRF52_RTC_CHECKINT(d, s)          ((d)->ops->checkint(d, s))
+#define NRF52_RTC_ACKINT(d, s)            ((d)->ops->ackint(d, s))
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* RTC CC index */
+
+enum nrf52_rtc_cc_e
+{
+  NRF52_RTC_CC0 = 0,
+  NRF52_RTC_CC1 = 1,
+  NRF52_RTC_CC2 = 2,
+  NRF52_RTC_CC3 = 3,
+};
+
+/* RTC IRQ source */
+
+enum nrf52_rtc_irq_e
+{
+  NRF52_RTC_INT_TICK     = 0,
+  NRF52_RTC_INT_OVRFLW   = 1,
+  NRF52_RTC_INT_COMPARE0 = 2,
+  NRF52_RTC_INT_COMPARE1 = 3,
+  NRF52_RTC_INT_COMPARE2 = 4,
+  NRF52_RTC_INT_COMPARE3 = 5,
+};
+
+/* NRF52 RTC device */
+
+struct nrf52_rtc_dev_s
+{
+  struct nrf52_rtc_ops_s *ops;
+};
+
+/* NRF52 RTC ops */
+
+struct nrf52_rtc_ops_s
+{
+  /* RTC tasks */
+
+  CODE int (*start)(FAR struct nrf52_rtc_dev_s *dev);
+  CODE int (*stop)(FAR struct nrf52_rtc_dev_s *dev);
+  CODE int (*clear)(FAR struct nrf52_rtc_dev_s *dev);
+  CODE int (*trgovrflw)(FAR struct nrf52_rtc_dev_s *dev);
+
+  /* RTC operations */
+
+  CODE int (*setcc)(FAR struct nrf52_rtc_dev_s *dev, uint8_t i, uint32_t cc);
+  CODE int (*getcc)(FAR struct nrf52_rtc_dev_s *dev, uint8_t i,
+                    FAR uint32_t *cc);
+  CODE int (*setpre)(FAR struct nrf52_rtc_dev_s *dev, uint16_t pre);
+
+  /* RTC interrupts */
+
+  CODE int (*setisr)(FAR struct nrf52_rtc_dev_s *dev, xcpt_t handler,
+                     FAR void * arg);
+  CODE int (*enableint)(FAR struct nrf52_rtc_dev_s *dev, uint8_t source);
+  CODE int (*disableint)(FAR struct nrf52_rtc_dev_s *dev, uint8_t source);
+  CODE int (*checkint)(FAR struct nrf52_rtc_dev_s *dev, uint8_t source);
+  CODE int (*ackint)(FAR struct nrf52_rtc_dev_s *dev, uint8_t source);
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+FAR struct nrf52_rtc_dev_s *nrf52_rtc_init(int rtc);
+int nrf52_rtc_deinit(FAR struct nrf52_rtc_dev_s *dev);
+
+#endif /* __ARCH_ARM_SRC_NRF52_NRF52_RTC_H */