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})