xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_wdt.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1 /*
2  * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  *    list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  *    contributors may be used to endorse or promote products derived from this
17  *    software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <nrfx.h>
33 
34 #if NRFX_CHECK(NRFX_WDT_ENABLED)
35 #include <nrfx_wdt.h>
36 
37 #define NRFX_LOG_MODULE WDT
38 #include <nrfx_log.h>
39 
40 /**@brief WDT state. */
41 static nrfx_drv_state_t m_state;
42 
43 /**@brief WDT alloc table. */
44 static uint8_t m_alloc_index;
45 
46 #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ)
47 /**@brief WDT event handler. */
48 static nrfx_wdt_event_handler_t m_wdt_event_handler;
49 
50 /**@brief WDT interrupt handler. */
nrfx_wdt_irq_handler(void)51 void nrfx_wdt_irq_handler(void)
52 {
53     if (nrf_wdt_event_check(NRF_WDT_EVENT_TIMEOUT))
54     {
55         m_wdt_event_handler();
56         nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT);
57     }
58 }
59 #endif
60 
61 
nrfx_wdt_init(nrfx_wdt_config_t const * p_config,nrfx_wdt_event_handler_t wdt_event_handler)62 nrfx_err_t nrfx_wdt_init(nrfx_wdt_config_t const * p_config,
63                          nrfx_wdt_event_handler_t  wdt_event_handler)
64 {
65     NRFX_ASSERT(p_config);
66     nrfx_err_t err_code;
67 
68 #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ)
69     NRFX_ASSERT(wdt_event_handler != NULL);
70     m_wdt_event_handler = wdt_event_handler;
71 #else
72     NRFX_ASSERT(wdt_event_handler == NULL);
73     (void)wdt_event_handler;
74 #endif
75     if (m_state == NRFX_DRV_STATE_UNINITIALIZED)
76     {
77         m_state = NRFX_DRV_STATE_INITIALIZED;
78     }
79     else
80     {
81         err_code = NRFX_ERROR_INVALID_STATE;
82         NRFX_LOG_WARNING("Function: %s, error code: %s.",
83                          __func__,
84                          NRFX_LOG_ERROR_STRING_GET(err_code));
85         return err_code;
86     }
87 
88     nrf_wdt_behaviour_set(p_config->behaviour);
89 
90     nrf_wdt_reload_value_set((p_config->reload_value * 32768) / 1000);
91 
92 #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ)
93     NRFX_IRQ_PRIORITY_SET(WDT_IRQn, p_config->interrupt_priority);
94     NRFX_IRQ_ENABLE(WDT_IRQn);
95 #endif
96 
97     err_code = NRFX_SUCCESS;
98     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
99     return err_code;
100 }
101 
102 
nrfx_wdt_enable(void)103 void nrfx_wdt_enable(void)
104 {
105     NRFX_ASSERT(m_alloc_index != 0);
106     NRFX_ASSERT(m_state == NRFX_DRV_STATE_INITIALIZED);
107 #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ)
108     nrf_wdt_int_enable(NRF_WDT_INT_TIMEOUT_MASK);
109 #endif
110     nrf_wdt_task_trigger(NRF_WDT_TASK_START);
111     m_state = NRFX_DRV_STATE_POWERED_ON;
112     NRFX_LOG_INFO("Enabled.");
113 }
114 
115 
nrfx_wdt_feed(void)116 void nrfx_wdt_feed(void)
117 {
118     NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
119     for (uint8_t i = 0; i < m_alloc_index; i++)
120     {
121         nrf_wdt_reload_request_set((nrf_wdt_rr_register_t)(NRF_WDT_RR0 + i));
122     }
123 }
124 
nrfx_wdt_channel_alloc(nrfx_wdt_channel_id * p_channel_id)125 nrfx_err_t nrfx_wdt_channel_alloc(nrfx_wdt_channel_id * p_channel_id)
126 {
127     nrfx_err_t result;
128     NRFX_ASSERT(p_channel_id);
129     NRFX_ASSERT(m_state == NRFX_DRV_STATE_INITIALIZED);
130 
131     NRFX_CRITICAL_SECTION_ENTER();
132     if (m_alloc_index < NRF_WDT_CHANNEL_NUMBER)
133     {
134         *p_channel_id = (nrfx_wdt_channel_id)(NRF_WDT_RR0 + m_alloc_index);
135         m_alloc_index++;
136         nrf_wdt_reload_request_enable(*p_channel_id);
137         result = NRFX_SUCCESS;
138     }
139     else
140     {
141         result = NRFX_ERROR_NO_MEM;
142     }
143     NRFX_CRITICAL_SECTION_EXIT();
144     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(result));
145     return result;
146 }
147 
nrfx_wdt_channel_feed(nrfx_wdt_channel_id channel_id)148 void nrfx_wdt_channel_feed(nrfx_wdt_channel_id channel_id)
149 {
150     NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
151     nrf_wdt_reload_request_set(channel_id);
152 }
153 
154 #endif // NRFX_CHECK(NRFX_WDT_ENABLED)
155