nordic: add watchdog timer driver
Add driver for the hardware watchdog timer
Use the watchdog timer in FF target
Signed-off-by: Andreas Vibeto <andreas.vibeto@nordicsemi.no>
diff --git a/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.c b/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.c
new file mode 100644
index 0000000..6040265
--- /dev/null
+++ b/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.c
@@ -0,0 +1,142 @@
+ /** @file
+ * Copyright (c) 2021 Nordic Semiconductor ASA.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed 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.
+ **/
+
+#include "nrf_wdt.h"
+
+/* Following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/**
+ * @brief Watchdog Timer
+ */
+struct NRF_WDT_Type{ /*!< (@ 0x40018000) WDT0_NS Structure */
+__OM uint32_t TASKS_START; /*!< (@ 0x00000000) Start WDT */
+__OM uint32_t TASKS_STOP; /*!< (@ 0x00000004) Stop WDT */
+__IM uint32_t RESERVED[30];
+__IOM uint32_t SUBSCRIBE_START; /*!< (@ 0x00000080) Subscribe configuration for task START */
+__IOM uint32_t SUBSCRIBE_STOP; /*!< (@ 0x00000084) Subscribe configuration for task STOP */
+__IM uint32_t RESERVED1[30];
+__IOM uint32_t EVENTS_TIMEOUT; /*!< (@ 0x00000100) Watchdog timeout */
+__IOM uint32_t EVENTS_STOPPED; /*!< (@ 0x00000104) Watchdog stopped */
+__IM uint32_t RESERVED2[30];
+__IOM uint32_t PUBLISH_TIMEOUT; /*!< (@ 0x00000180) Publish configuration for event TIMEOUT */
+__IOM uint32_t PUBLISH_STOPPED; /*!< (@ 0x00000184) Publish configuration for event STOPPED */
+__IM uint32_t RESERVED3[95];
+__IOM uint32_t INTENSET; /*!< (@ 0x00000304) Enable interrupt */
+__IOM uint32_t INTENCLR; /*!< (@ 0x00000308) Disable interrupt */
+__IM uint32_t RESERVED4[6];
+__IOM uint32_t NMIENSET; /*!< (@ 0x00000324) Enable interrupt */
+__IOM uint32_t NMIENCLR; /*!< (@ 0x00000328) Disable interrupt */
+__IM uint32_t RESERVED5[53];
+__IM uint32_t RUNSTATUS; /*!< (@ 0x00000400) Run status */
+__IM uint32_t REQSTATUS; /*!< (@ 0x00000404) Request status */
+__IM uint32_t RESERVED6[63];
+__IOM uint32_t CRV; /*!< (@ 0x00000504) Counter reload value */
+__IOM uint32_t RREN; /*!< (@ 0x00000508) Enable register for reload request registers */
+__IOM uint32_t CONFIG; /*!< (@ 0x0000050C) Configuration register */
+__IM uint32_t RESERVED7[4];
+__OM uint32_t TSEN; /*!< (@ 0x00000520) Task stop enable */
+__IM uint32_t RESERVED8[55];
+__OM uint32_t RR[8]; /*!< (@ 0x00000600) Description collection: Reload request n */
+}; /*!< Size = 1568 (0x620) */
+
+/* Register: WDT_CONFIG */
+/* Description: Configuration register */
+#define WDT_CONFIG_STOPEN_Pos (6UL) /*!< Position of STOPEN field. */
+#define WDT_CONFIG_STOPEN_Disable (0UL) /*!< Do not allow stopping WDT */
+#define WDT_CONFIG_STOPEN_Enable (1UL) /*!< Allow stopping WDT */
+
+#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */
+#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause WDT while the CPU is sleeping */
+#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Keep WDT running while the CPU is sleeping */
+
+/* Register: WDT_RUNSTATUS */
+/* Description: Run status */
+#define WDT_RUNSTATUS_RUNSTATUSWDT_Pos (0UL) /*!< Position of RUNSTATUSWDT field. */
+#define WDT_RUNSTATUS_RUNSTATUSWDT_Msk (0x1UL << WDT_RUNSTATUS_RUNSTATUSWDT_Pos) /*!< Bit mask of RUNSTATUSWDT field. */
+#define WDT_RUNSTATUS_RUNSTATUSWDT_NotRunning (0UL) /*!< Watchdog is not running */
+#define WDT_RUNSTATUS_RUNSTATUSWDT_Running (1UL) /*!< Watchdog is running */
+
+/**
+ @brief - Initializes an hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ - time_us : Time in micro seconds
+ @return - SUCCESS, FAILURE
+**/
+int nrf_wdt_init(addr_t base_addr, uint32_t time_us)
+{
+ struct NRF_WDT_Type *nrf_wdt = (struct NRF_WDT_Type*)base_addr;
+
+ /* From nRF53 documentation, the timeout in seconds is
+ * timeout [s] = (CRV + 1) / 32768
+ */
+ uint32_t ticks = ((time_us / 1000000) * 32768) - 1;
+
+ if ((ticks >= 0xFFFFFFFFUL) || (ticks < 0xFUL))
+ {
+ // Maximum and minimum values defined in nRF53 documentation
+ return PAL_STATUS_ERROR;
+ }
+
+ nrf_wdt->CRV = ticks;
+
+ // Enable Stop and keep the watchdog running while CPU is sleeping
+ nrf_wdt->CONFIG = ((WDT_CONFIG_STOPEN_Enable << WDT_CONFIG_STOPEN_Pos) |
+ (WDT_CONFIG_SLEEP_Run << WDT_CONFIG_SLEEP_Pos));
+
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Enables a hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ @return - SUCCESS, FAILURE
+**/
+int nrf_wdt_enable(addr_t base_addr)
+{
+ struct NRF_WDT_Type *nrf_wdt = (struct NRF_WDT_Type*)base_addr;
+ nrf_wdt->TASKS_START = 0x01UL; // Trigger start task
+
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Disables a hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ @return - SUCCESS, FAILURE
+**/
+int nrf_wdt_disable(addr_t base_addr)
+{
+ struct NRF_WDT_Type *nrf_wdt = (struct NRF_WDT_Type*)base_addr;
+ nrf_wdt->TSEN = 0x6E524635UL; // Special value to enable stop task
+ nrf_wdt->TASKS_STOP = 0x01UL; // Trigger stop task
+
+ return PAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Checks whether hardware watchdog timer is enabled
+ @param - base_addr : Base address of the watchdog module
+ @return - Enabled : 1, Disabled : 0
+**/
+int nrf_wdt_is_enabled(addr_t base_addr)
+{
+ struct NRF_WDT_Type *nrf_wdt = (struct NRF_WDT_Type*)base_addr;
+ return (nrf_wdt->RUNSTATUS & WDT_RUNSTATUS_RUNSTATUSWDT_Msk);
+}
diff --git a/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.h b/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.h
new file mode 100644
index 0000000..58a2475
--- /dev/null
+++ b/api-tests/platform/drivers/watchdog/nrf/nrf_wdt.h
@@ -0,0 +1,30 @@
+ /** @file
+ *
+ * Copyright (c) 2021 Nordic Semiconductor ASA.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed 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 NRF_WDT_H__
+#define NRF_WDT_H__
+
+#include "pal_common.h"
+
+
+int nrf_wdt_init(addr_t base_addr, uint32_t time_us);
+int nrf_wdt_enable(addr_t base_addr);
+int nrf_wdt_disable(addr_t base_addr);
+int nrf_wdt_is_enabled(addr_t base_addr);
+
+#endif // NRF_WDT_H__
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf5340/target.cfg b/api-tests/platform/targets/tgt_ff_tfm_nrf5340/target.cfg
index c2a9132..4bac53a 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf5340/target.cfg
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf5340/target.cfg
@@ -24,12 +24,12 @@
// Watchdog device info
watchdog.num = 1;
-watchdog.0.base = 0; // Unused value
-watchdog.0.num_of_tick_per_micro_sec = 1;
-watchdog.0.timeout_in_micro_sec_low = 60000000; // 60 secs
-watchdog.0.timeout_in_micro_sec_medium = 60000000; // 60 secs
-watchdog.0.timeout_in_micro_sec_high = 60000000; // 60 secs
-watchdog.0.timeout_in_micro_sec_crypto = 60000000; // 60 secs
+watchdog.0.base = 0x50018000; // Secure WDT0
+watchdog.0.num_of_tick_per_micro_sec = 0; // Unused
+watchdog.0.timeout_in_micro_sec_low = 1000000; // 1.0 secs
+watchdog.0.timeout_in_micro_sec_medium = 2000000; // 2 secs
+watchdog.0.timeout_in_micro_sec_high = 5000000; // 5 secs
+watchdog.0.timeout_in_micro_sec_crypto = 18000000; // 18 secs
// Range of 1KB Non-volatile memory to preserve data over reset. Ex, NVRAM and FLASH
nvmem.num =1;
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf9160/nspe/pal_config.h b/api-tests/platform/targets/tgt_ff_tfm_nrf9160/nspe/pal_config.h
index 832d5b5..23925a1 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf9160/nspe/pal_config.h
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf9160/nspe/pal_config.h
@@ -34,7 +34,7 @@
#define NONSECURE_TEST_BUILD
/* If not defined, skip watchdog programming */
-#define WATCHDOG_AVAILABLE
+//#define WATCHDOG_AVAILABLE
/* Are Dynamic memory APIs available to secure partition? */
#define SP_HEAP_MEM_SUPP
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf9160/target.cmake b/api-tests/platform/targets/tgt_ff_tfm_nrf9160/target.cmake
index 9eccad3..960c0db 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf9160/target.cmake
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf9160/target.cmake
@@ -18,4 +18,6 @@
# * limitations under the License.
#**/
-include(${PSA_ROOT_DIR}/platform/targets/tgt_ff_tfm_nrf_common/target.cmake)
\ No newline at end of file
+set(WATCHDOG_AVAILABLE 0)
+
+include(${PSA_ROOT_DIR}/platform/targets/tgt_ff_tfm_nrf_common/target.cmake)
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.c b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.c
index 84feaa3..490361a 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.c
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.c
@@ -20,19 +20,13 @@
#include "pal_driver_intf.h"
#include "pal_common.h"
+#include "pal_config.h"
#include "pal_nvmem.h"
+#include "nrf_wdt.h"
+
extern int tfm_log_printf(const char *, ...);
-/* Initialize the timer with the given number of ticks. */
-extern void pal_timer_init_ns(uint32_t ticks);
-
-/* Start the timer. */
-extern void pal_timer_start_ns(void);
-
-/* Stop and reset the timer. */
-extern void pal_timer_stop_ns(void);
-
/* Get the address of a free, word-aligned, 1K memory area. */
extern uint32_t pal_nvmem_get_addr(void);
@@ -61,7 +55,6 @@
tfm_log_printf(str, data);
}
-
/**
@brief - Writes into given non-volatile address.
@param - base : Base address of nvmem
@@ -98,7 +91,6 @@
return nvmem_read(base, offset, buffer, size);
}
-
/**
@brief - Initializes an hardware watchdog timer
@param - base_addr : Base address of the watchdog module
@@ -108,9 +100,8 @@
**/
int pal_wd_timer_init(addr_t base_addr, uint32_t time_us, uint32_t timer_tick_us)
{
- (void)base_addr;
- pal_timer_init_ns(time_us * timer_tick_us);
- return PAL_STATUS_SUCCESS;
+ (void)timer_tick_us;
+ return nrf_wdt_init(base_addr, time_us);
}
/**
@@ -120,10 +111,7 @@
**/
int pal_wd_timer_enable(addr_t base_addr)
{
- (void)base_addr;
- pal_timer_start_ns();
- return PAL_STATUS_SUCCESS;
-
+ return nrf_wdt_enable(base_addr);
}
/**
@@ -133,9 +121,7 @@
**/
int pal_wd_timer_disable(addr_t base_addr)
{
- (void)base_addr;
- pal_timer_stop_ns();
- return PAL_STATUS_SUCCESS;
+ return nrf_wdt_disable(base_addr);
}
/**
@@ -145,7 +131,7 @@
**/
int pal_wd_timer_is_enabled(addr_t base_addr)
{
- return pal_wd_cmsdk_is_enabled(base_addr);
+ return nrf_wdt_is_enabled(base_addr);
}
/**
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.h b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.h
index b7f86ca..00ffde4 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.h
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.h
@@ -23,7 +23,6 @@
#include "pal_uart.h"
#include "pal_nvmem.h"
-#include "pal_wd_cmsdk.h"
/* Following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
diff --git a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/target.cmake b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/target.cmake
index 697eb05..aba24ba 100644
--- a/api-tests/platform/targets/tgt_ff_tfm_nrf_common/target.cmake
+++ b/api-tests/platform/targets/tgt_ff_tfm_nrf_common/target.cmake
@@ -43,7 +43,7 @@
# Driver files will be compiled as part of driver partition
${PSA_ROOT_DIR}/platform/targets/tgt_ff_tfm_nrf_common/spe/pal_driver_intf.c
${PSA_ROOT_DIR}/platform/drivers/nvmem/pal_nvmem.c
- ${PSA_ROOT_DIR}/platform/drivers/watchdog/cmsdk/pal_wd_cmsdk.c
+ ${PSA_ROOT_DIR}/platform/drivers/watchdog/nrf/nrf_wdt.c
)
endif()
@@ -66,7 +66,7 @@
list(APPEND PAL_DRIVER_INCLUDE_PATHS
${PSA_ROOT_DIR}/platform/drivers/nvmem
${PSA_ROOT_DIR}/platform/drivers/uart/cmsdk
- ${PSA_ROOT_DIR}/platform/drivers/watchdog/cmsdk
+ ${PSA_ROOT_DIR}/platform/drivers/watchdog/nrf/
)
message(WARNING ${PSA_ROOT_DIR})