1 /*
2 * Copyright (c) 2015 - 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_COMP_ENABLED)
37
38 #include <nrfx_comp.h>
39 #include "prs/nrfx_prs.h"
40
41 #define NRFX_LOG_MODULE COMP
42 #include <nrfx_log.h>
43
44 #define EVT_TO_STR(event) \
45 (event == NRF_COMP_EVENT_READY ? "NRF_COMP_EVENT_READY" : \
46 (event == NRF_COMP_EVENT_DOWN ? "NRF_COMP_EVENT_DOWN" : \
47 (event == NRF_COMP_EVENT_UP ? "NRF_COMP_EVENT_UP" : \
48 (event == NRF_COMP_EVENT_CROSS ? "NRF_COMP_EVENT_CROSS" : \
49 "UNKNOWN ERROR"))))
50
51
52 static nrfx_comp_event_handler_t m_comp_event_handler = NULL;
53 static nrfx_drv_state_t m_state = NRFX_DRV_STATE_UNINITIALIZED;
54
comp_configure(nrfx_comp_config_t const * p_config)55 static void comp_configure(nrfx_comp_config_t const * p_config)
56 {
57 nrfy_comp_config_t nrfy_config =
58 {
59 .reference = p_config->reference,
60 .ext_ref = p_config->ext_ref,
61 .main_mode = p_config->main_mode,
62 .threshold = p_config->threshold,
63 .speed_mode = p_config->speed_mode,
64 .hyst = p_config->hyst,
65 NRFX_COND_CODE_1(NRF_COMP_HAS_ISOURCE, (.isource = p_config->isource,), ())
66 .input = p_config->input
67 };
68
69 nrfy_comp_periph_configure(NRF_COMP, &nrfy_config);
70 nrfy_comp_int_init(NRF_COMP,
71 NRF_COMP_INT_READY_MASK |
72 NRF_COMP_INT_DOWN_MASK |
73 NRF_COMP_INT_UP_MASK |
74 NRF_COMP_INT_CROSS_MASK,
75 p_config->interrupt_priority,
76 false);
77 }
78
comp_execute_handler(nrf_comp_event_t event,uint32_t event_mask)79 static void comp_execute_handler(nrf_comp_event_t event, uint32_t event_mask)
80 {
81 if (event_mask & nrfy_comp_int_enable_check(NRF_COMP, NRFY_EVENT_TO_INT_BITMASK(event)))
82 {
83 NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(event));
84
85 m_comp_event_handler(event);
86 }
87 }
88
nrfx_comp_irq_handler(void)89 void nrfx_comp_irq_handler(void)
90 {
91 uint32_t evt_mask = nrfy_comp_events_process(NRF_COMP,
92 NRF_COMP_INT_READY_MASK |
93 NRF_COMP_INT_DOWN_MASK |
94 NRF_COMP_INT_UP_MASK |
95 NRF_COMP_INT_CROSS_MASK);
96 comp_execute_handler(NRF_COMP_EVENT_READY, evt_mask);
97 comp_execute_handler(NRF_COMP_EVENT_DOWN, evt_mask);
98 comp_execute_handler(NRF_COMP_EVENT_UP, evt_mask);
99 comp_execute_handler(NRF_COMP_EVENT_CROSS, evt_mask);
100 }
101
102
nrfx_comp_init(nrfx_comp_config_t const * p_config,nrfx_comp_event_handler_t event_handler)103 nrfx_err_t nrfx_comp_init(nrfx_comp_config_t const * p_config,
104 nrfx_comp_event_handler_t event_handler)
105 {
106 NRFX_ASSERT(p_config);
107 NRFX_ASSERT(event_handler);
108 nrfx_err_t err_code;
109
110 if (m_state != NRFX_DRV_STATE_UNINITIALIZED)
111 { // COMP driver is already initialized
112 #if NRFX_API_VER_AT_LEAST(3, 2, 0)
113 err_code = NRFX_ERROR_ALREADY;
114 #else
115 err_code = NRFX_ERROR_INVALID_STATE;
116 #endif
117 NRFX_LOG_WARNING("Function: %s, error code: %s.",
118 __func__,
119 NRFX_LOG_ERROR_STRING_GET(err_code));
120 return err_code;
121 }
122
123 m_comp_event_handler = event_handler;
124
125 #if NRFX_CHECK(NRFX_PRS_ENABLED)
126 if (nrfx_prs_acquire(NRF_COMP, nrfx_comp_irq_handler) != NRFX_SUCCESS)
127 {
128 err_code = NRFX_ERROR_BUSY;
129 NRFX_LOG_WARNING("Function: %s, error code: %s.",
130 __func__,
131 NRFX_LOG_ERROR_STRING_GET(err_code));
132 return err_code;
133 }
134 #endif
135 nrfy_comp_shorts_disable(NRF_COMP,
136 NRFX_COMP_SHORT_STOP_AFTER_CROSS_EVT |
137 NRFX_COMP_SHORT_STOP_AFTER_UP_EVT |
138 NRFX_COMP_SHORT_STOP_AFTER_DOWN_EVT);
139 nrfy_comp_int_disable(NRF_COMP,
140 NRF_COMP_INT_READY_MASK |
141 NRF_COMP_INT_DOWN_MASK |
142 NRF_COMP_INT_UP_MASK |
143 NRF_COMP_INT_CROSS_MASK);
144
145 if (p_config)
146 {
147 comp_configure(p_config);
148 }
149
150 nrfy_comp_enable(NRF_COMP);
151 nrfy_comp_task_trigger(NRF_COMP, NRF_COMP_TASK_STOP);
152
153 m_state = NRFX_DRV_STATE_INITIALIZED;
154
155 err_code = NRFX_SUCCESS;
156 NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
157 return err_code;
158 }
159
nrfx_comp_reconfigure(nrfx_comp_config_t const * p_config)160 nrfx_err_t nrfx_comp_reconfigure(nrfx_comp_config_t const * p_config)
161 {
162 NRFX_ASSERT(p_config);
163 nrfx_err_t err_code;
164
165 if (m_state == NRFX_DRV_STATE_UNINITIALIZED)
166 {
167 err_code = NRFX_ERROR_INVALID_STATE;
168 NRFX_LOG_WARNING("Function: %s, error code: %s.",
169 __func__,
170 NRFX_LOG_ERROR_STRING_GET(err_code));
171 return err_code;
172
173 }
174 else if (m_state == NRFX_DRV_STATE_POWERED_ON)
175 {
176 err_code = NRFX_ERROR_BUSY;
177 NRFX_LOG_WARNING("Function: %s, error code: %s.",
178 __func__,
179 NRFX_LOG_ERROR_STRING_GET(err_code));
180 return err_code;
181 }
182 nrfy_comp_disable(NRF_COMP);
183 comp_configure(p_config);
184 nrfy_comp_enable(NRF_COMP);
185 return NRFX_SUCCESS;
186 }
187
nrfx_comp_uninit(void)188 void nrfx_comp_uninit(void)
189 {
190 NRFX_ASSERT(m_state != NRFX_DRV_STATE_UNINITIALIZED);
191
192 nrfy_comp_shorts_disable(NRF_COMP, UINT32_MAX);
193 nrfy_comp_int_disable(NRF_COMP, UINT32_MAX);
194 nrfy_comp_task_trigger(NRF_COMP, NRF_COMP_TASK_STOP);
195 nrfy_comp_int_uninit(NRF_COMP);
196 nrfy_comp_disable(NRF_COMP);
197 #if NRFX_CHECK(NRFX_PRS_ENABLED)
198 nrfx_prs_release(NRF_COMP);
199 #endif
200 m_state = NRFX_DRV_STATE_UNINITIALIZED;
201 m_comp_event_handler = NULL;
202 NRFX_LOG_INFO("Uninitialized.");
203 }
204
nrfx_comp_init_check(void)205 bool nrfx_comp_init_check(void)
206 {
207 return (m_state != NRFX_DRV_STATE_UNINITIALIZED);
208 }
209
nrfx_comp_pin_select(nrf_comp_input_t psel)210 void nrfx_comp_pin_select(nrf_comp_input_t psel)
211 {
212 NRFX_ASSERT(m_state != NRFX_DRV_STATE_UNINITIALIZED);
213
214 bool comp_enable_state = nrfy_comp_enable_check(NRF_COMP);
215 nrfy_comp_task_trigger(NRF_COMP, NRF_COMP_TASK_STOP);
216 if (m_state == NRFX_DRV_STATE_POWERED_ON)
217 {
218 m_state = NRFX_DRV_STATE_INITIALIZED;
219 }
220 nrfy_comp_disable(NRF_COMP);
221 nrfy_comp_input_select(NRF_COMP, psel);
222 if (comp_enable_state == true)
223 {
224 nrfy_comp_enable(NRF_COMP);
225 }
226 }
227
nrfx_comp_start(uint32_t comp_int_mask,uint32_t comp_shorts_mask)228 void nrfx_comp_start(uint32_t comp_int_mask, uint32_t comp_shorts_mask)
229 {
230 NRFX_ASSERT(m_state == NRFX_DRV_STATE_INITIALIZED);
231
232 (void)nrfy_comp_events_process(NRF_COMP, comp_int_mask);
233 nrfy_comp_int_enable(NRF_COMP, comp_int_mask);
234 nrfy_comp_shorts_enable(NRF_COMP, comp_shorts_mask);
235 m_state = NRFX_DRV_STATE_POWERED_ON;
236 nrfy_comp_task_trigger(NRF_COMP, NRF_COMP_TASK_START);
237 NRFX_LOG_INFO("Enabled.");
238 }
239
nrfx_comp_stop(void)240 void nrfx_comp_stop(void)
241 {
242 NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
243
244 nrfy_comp_shorts_disable(NRF_COMP, UINT32_MAX);
245 nrfy_comp_int_disable(NRF_COMP, UINT32_MAX);
246 nrfy_comp_task_trigger(NRF_COMP, NRF_COMP_TASK_STOP);
247 m_state = NRFX_DRV_STATE_INITIALIZED;
248 NRFX_LOG_INFO("Disabled.");
249 }
250
nrfx_comp_sample()251 uint32_t nrfx_comp_sample()
252 {
253 NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
254
255 return nrfy_comp_sample(NRF_COMP);
256 }
257
258 #endif // NRFX_CHECK(NRFX_COMP_ENABLED)
259