1 /*
2 * Copyright (c) 2016 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <nrfx.h>
35
36 #if NRFX_CHECK(NRFX_RNG_ENABLED)
37
38 #include <nrfx_rng.h>
39
40 #define NRFX_LOG_MODULE RNG
41 #include <nrfx_log.h>
42
43 /**
44 * @brief Internal state of RNG driver.
45 */
46 static nrfx_drv_state_t m_rng_state;
47
48 /**
49 * @brief Pointer to handler calling from interrupt routine.
50 */
51 static nrfx_rng_evt_handler_t m_rng_hndl;
52
nrfx_rng_init(nrfx_rng_config_t const * p_config,nrfx_rng_evt_handler_t handler)53 nrfx_err_t nrfx_rng_init(nrfx_rng_config_t const * p_config, nrfx_rng_evt_handler_t handler)
54 {
55 NRFX_ASSERT(p_config);
56 NRFX_ASSERT(handler);
57 if (m_rng_state != NRFX_DRV_STATE_UNINITIALIZED)
58 {
59 return NRFX_ERROR_ALREADY;
60 }
61
62 m_rng_hndl = handler;
63
64 if (p_config->error_correction)
65 {
66 nrf_rng_error_correction_enable(NRF_RNG);
67 }
68 nrf_rng_shorts_disable(NRF_RNG, NRF_RNG_SHORT_VALRDY_STOP_MASK);
69 NRFX_IRQ_PRIORITY_SET(RNG_IRQn, p_config->interrupt_priority);
70 NRFX_IRQ_ENABLE(RNG_IRQn);
71
72 m_rng_state = NRFX_DRV_STATE_INITIALIZED;
73
74 return NRFX_SUCCESS;
75 }
76
nrfx_rng_start(void)77 void nrfx_rng_start(void)
78 {
79 NRFX_ASSERT(m_rng_state == NRFX_DRV_STATE_INITIALIZED);
80 nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
81 nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
82 nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START);
83 }
84
nrfx_rng_stop(void)85 void nrfx_rng_stop(void)
86 {
87 NRFX_ASSERT(m_rng_state == NRFX_DRV_STATE_INITIALIZED);
88 nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
89 nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP);
90 }
91
nrfx_rng_uninit(void)92 void nrfx_rng_uninit(void)
93 {
94 NRFX_ASSERT(m_rng_state == NRFX_DRV_STATE_INITIALIZED);
95
96 nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK);
97 nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP);
98 NRFX_IRQ_DISABLE(RNG_IRQn);
99
100 m_rng_state = NRFX_DRV_STATE_UNINITIALIZED;
101 NRFX_LOG_INFO("Uninitialized.");
102 }
103
nrfx_rng_init_check(void)104 bool nrfx_rng_init_check(void)
105 {
106 return (m_rng_state != NRFX_DRV_STATE_UNINITIALIZED);
107 }
108
nrfx_rng_irq_handler(void)109 void nrfx_rng_irq_handler(void)
110 {
111 nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
112
113 uint8_t rng_value = nrf_rng_random_value_get(NRF_RNG);
114
115 m_rng_hndl(rng_value);
116
117 NRFX_LOG_DEBUG("Event: NRF_RNG_EVENT_VALRDY.");
118 }
119
120 #endif // NRFX_CHECK(NRFX_RNG_ENABLED)
121