1 /*
2 * Copyright (c) 2021 - 2025, 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_VEVIF_ENABLED)
37
38 #include <nrfx_vevif.h>
39 #include <nrf_bitmask.h>
40 #include <hal/nrf_vpr.h>
41 #include <hal/nrf_vpr_csr.h>
42 #include <hal/nrf_vpr_csr_vevif.h>
43
44 #define NRFX_LOG_MODULE VEVIF
45 #include <nrfx_log.h>
46
47 #define NRFX_VEVIF_IRQ_HANDLER_DEFINE(idx, _) \
48 void nrfx_vevif_##idx##_irq_handler(void) \
49 { \
50 nrfx_vevif_irq_handler(idx); \
51 }
52
53 typedef struct
54 {
55 nrfx_vevif_event_handler_t handler;
56 void * p_context;
57 nrfx_drv_state_t state;
58 } nrfx_vevif_cb_t;
59
60 static nrfx_vevif_cb_t m_cb;
61
nrfx_vevif_init(uint8_t interrupt_priority,nrfx_vevif_event_handler_t event_handler,void * p_context)62 nrfx_err_t nrfx_vevif_init(uint8_t interrupt_priority,
63 nrfx_vevif_event_handler_t event_handler,
64 void * p_context)
65 {
66 NRFX_ASSERT(event_handler);
67
68 nrfx_err_t err_code = NRFX_SUCCESS;
69
70 if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
71 {
72 #if NRFX_API_VER_AT_LEAST(3, 2, 0)
73 err_code = NRFX_ERROR_ALREADY;
74 #else
75 err_code = NRFX_ERROR_INVALID_STATE;
76 #endif
77 NRFX_LOG_WARNING("Function: %s, error code: %s.",
78 __func__,
79 NRFX_LOG_ERROR_STRING_GET(err_code));
80 return err_code;
81 }
82
83 m_cb.handler = event_handler;
84 m_cb.p_context = p_context;
85 m_cb.state = NRFX_DRV_STATE_INITIALIZED;
86
87 nrf_vpr_csr_vevif_tasks_clear(NRF_VPR_TASK_TRIGGER_ALL_MASK);
88
89 for (uint8_t i = 0; i < NRF_VPR_CSR_VEVIF_EVENT_TASK_COUNT; i++)
90 {
91 NRFY_IRQ_PRIORITY_SET((VPRCLIC_0_IRQn + i), interrupt_priority);
92 }
93
94 NRFX_LOG_INFO("Initialized.");
95 return err_code;
96 }
97
nrfx_vevif_uninit(void)98 void nrfx_vevif_uninit(void)
99 {
100 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
101
102 for (uint8_t i = 0; i < NRF_VPR_CSR_VEVIF_EVENT_TASK_COUNT; i++)
103 {
104 NRFY_IRQ_DISABLE(VPRCLIC_0_IRQn + i);
105 }
106
107 m_cb.handler = NULL;
108 m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
109 NRFX_LOG_INFO("Uninitialized.");
110 }
111
nrfx_vevif_int_enable(uint32_t mask)112 void nrfx_vevif_int_enable(uint32_t mask)
113 {
114 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
115
116 while (mask != 0)
117 {
118 uint32_t event_no = NRF_CTZ(mask);
119 NRFY_IRQ_ENABLE(VPRCLIC_0_IRQn + event_no);
120 nrf_bitmask_bit_clear(event_no, (void *)&mask);
121 }
122 }
123
nrfx_vevif_init_check(void)124 bool nrfx_vevif_init_check(void)
125 {
126 return (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
127 }
128
nrfx_vevif_int_disable(uint32_t mask)129 void nrfx_vevif_int_disable(uint32_t mask)
130 {
131 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
132
133 while (mask != 0)
134 {
135 uint32_t event_no = NRF_CTZ(mask);
136 NRFY_IRQ_DISABLE(VPRCLIC_0_IRQn + event_no);
137 nrf_bitmask_bit_clear(event_no, (void *)&mask);
138 }
139 }
140
nrfx_vevif_irq_handler(uint8_t irq_idx)141 static void nrfx_vevif_irq_handler(uint8_t irq_idx)
142 {
143 nrf_vpr_csr_vevif_tasks_clear(1UL << irq_idx);
144
145 m_cb.handler(irq_idx, m_cb.p_context);
146 }
147
148 /* Define interrupt handlers for 0..31 NRF_VEVIF driver instances. */
149 NRFX_LISTIFY(32, NRFX_VEVIF_IRQ_HANDLER_DEFINE, (;), _)
150
151 #endif // NRFX_CHECK(NRFX_VEVIF_ENABLED)
152