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