1 /*
2  * Copyright (c) 2015 - 2023, Nordic Semiconductor ASA
3  *
4  * Modifications to the GPIOTE HAL to use with simulation models
5  *
6  * Code which is not copied from the nRFx HAL is licensed as:
7  * SPDX-License-Identifier: Apache-2.0
8  *
9  * Most of the code below is taken from the NRFx HAL with minor
10  * modifications. For that code, the original license applies:
11  *
12  * SPDX-License-Identifier: BSD-3-Clause
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright notice, this
18  *    list of conditions and the following disclaimer.
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * 3. Neither the name of the copyright holder nor the names of its
25  *    contributors may be used to endorse or promote products derived from this
26  *    software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include <stdint.h>
42 #include "NRF_GPIOTE.h"
43 #include "hal/nrf_gpiote.h"
44 #include "bs_tracing.h"
45 
nrf_gpiote_task_trigger(NRF_GPIOTE_Type * p_reg,nrf_gpiote_task_t task)46 void nrf_gpiote_task_trigger(NRF_GPIOTE_Type * p_reg, nrf_gpiote_task_t task)
47 {
48 	uint32_t *reg = (uint32_t *)((uintptr_t)p_reg + task);
49 	*(volatile uint32_t *)reg = 0x1UL;
50 
51 	if ((reg >= &NRF_GPIOTE_regs.TASKS_OUT[0])
52 	    && (reg<= &NRF_GPIOTE_regs.TASKS_OUT[N_GPIOTE_CHANNELS])) {
53 		nrf_gpiote_regw_sideeffects_TASKS_OUT(reg - &NRF_GPIOTE_regs.TASKS_OUT[0]);
54 	} else if ((reg >= &NRF_GPIOTE_regs.TASKS_SET[0])
55 		   && (reg<= &NRF_GPIOTE_regs.TASKS_SET[N_GPIOTE_CHANNELS])) {
56 		nrf_gpiote_regw_sideeffects_TASKS_SET(reg - &NRF_GPIOTE_regs.TASKS_SET[0]);
57 	} else if ((reg >= &NRF_GPIOTE_regs.TASKS_CLR[0])
58 		   && (reg<= &NRF_GPIOTE_regs.TASKS_CLR[N_GPIOTE_CHANNELS])) {
59 		nrf_gpiote_regw_sideeffects_TASKS_CLR(reg - &NRF_GPIOTE_regs.TASKS_CLR[0]);
60 	} else {
61 		bs_trace_error_time_line("%s: Unknown GPIOTE tasks %i\n",task); /* LCOV_EXCL_LINE */
62 	}
63 }
64 
nrf_gpiote_event_clear(NRF_GPIOTE_Type * p_reg,nrf_gpiote_event_t event)65 void nrf_gpiote_event_clear(NRF_GPIOTE_Type * p_reg, nrf_gpiote_event_t event)
66 {
67 	uint32_t *reg = (uint32_t *)((uintptr_t)p_reg + event);
68 	*(volatile uint32_t *)reg = 0;
69 
70 	if ((reg >= &NRF_GPIOTE_regs.EVENTS_IN[0])
71 	    && (reg <= &NRF_GPIOTE_regs.EVENTS_IN[N_GPIOTE_CHANNELS])) {
72 		nrf_gpiote_regw_sideeffects_EVENTS_IN(reg - &NRF_GPIOTE_regs.EVENTS_IN[0]);
73 	} else if (reg == &NRF_GPIOTE_regs.EVENTS_PORT) {
74 		nrf_gpiote_regw_sideeffects_EVENTS_PORT();
75 	} else {
76 		bs_trace_error_time_line("%s: Unknown GPIOTE event %i\n",event); /* LCOV_EXCL_LINE */
77 	}
78 }
79 
nrf_gpiote_int_enable(NRF_GPIOTE_Type * p_reg,uint32_t mask)80 void nrf_gpiote_int_enable(NRF_GPIOTE_Type * p_reg, uint32_t mask)
81 {
82     p_reg->NRFX_CONCAT_2(INTENSET, NRF_GPIOTE_IRQ_GROUP) = mask;
83     nrf_gpiote_regw_sideeffects_INTENSET();
84 
85 }
86 
nrf_gpiote_int_disable(NRF_GPIOTE_Type * p_reg,uint32_t mask)87 void nrf_gpiote_int_disable(NRF_GPIOTE_Type * p_reg, uint32_t mask)
88 {
89     p_reg->NRFX_CONCAT_2(INTENCLR, NRF_GPIOTE_IRQ_GROUP) = mask;
90     nrf_gpiote_regw_sideeffects_INTENCLR();
91 }
92 
nrf_gpiote_event_enable(NRF_GPIOTE_Type * p_reg,uint32_t idx)93 void nrf_gpiote_event_enable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
94 {
95    p_reg->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event;
96    nrf_gpiote_regw_sideeffects_CONFIG(idx);
97 }
98 
nrf_gpiote_event_disable(NRF_GPIOTE_Type * p_reg,uint32_t idx)99 void nrf_gpiote_event_disable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
100 {
101    p_reg->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Msk;
102    nrf_gpiote_regw_sideeffects_CONFIG(idx);
103 }
104 
nrf_gpiote_event_configure(NRF_GPIOTE_Type * p_reg,uint32_t idx,uint32_t pin,nrf_gpiote_polarity_t polarity)105 void nrf_gpiote_event_configure(NRF_GPIOTE_Type *     p_reg,
106                                 uint32_t              idx,
107                                 uint32_t              pin,
108                                 nrf_gpiote_polarity_t polarity)
109 {
110   p_reg->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk);
111   p_reg->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) |
112                         ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk);
113   nrf_gpiote_regw_sideeffects_CONFIG(idx);
114 }
115 
nrf_gpiote_task_enable(NRF_GPIOTE_Type * p_reg,uint32_t idx)116 void nrf_gpiote_task_enable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
117 {
118     uint32_t final_config = p_reg->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
119     p_reg->CONFIG[idx] = final_config;
120     nrf_gpiote_regw_sideeffects_CONFIG(idx);
121 }
122 
nrf_gpiote_task_disable(NRF_GPIOTE_Type * p_reg,uint32_t idx)123 void nrf_gpiote_task_disable(NRF_GPIOTE_Type * p_reg, uint32_t idx)
124 {
125     p_reg->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Msk;
126     nrf_gpiote_regw_sideeffects_CONFIG(idx);
127 }
128 
nrf_gpiote_task_configure(NRF_GPIOTE_Type * p_reg,uint32_t idx,uint32_t pin,nrf_gpiote_polarity_t polarity,nrf_gpiote_outinit_t init_val)129 void nrf_gpiote_task_configure(NRF_GPIOTE_Type *     p_reg,
130                                uint32_t              idx,
131                                uint32_t              pin,
132                                nrf_gpiote_polarity_t polarity,
133                                nrf_gpiote_outinit_t  init_val)
134 {
135   p_reg->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk |
136                           GPIOTE_CONFIG_POLARITY_Msk |
137                           GPIOTE_CONFIG_OUTINIT_Msk);
138 
139   p_reg->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) |
140                         ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) |
141                         ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
142 
143   nrf_gpiote_regw_sideeffects_CONFIG(idx);
144 }
145 
nrf_gpiote_task_force(NRF_GPIOTE_Type * p_reg,uint32_t idx,nrf_gpiote_outinit_t init_val)146 void nrf_gpiote_task_force(NRF_GPIOTE_Type *    p_reg,
147                            uint32_t             idx,
148                            nrf_gpiote_outinit_t init_val)
149 {
150     p_reg->CONFIG[idx] = (p_reg->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) |
151                          ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
152     nrf_gpiote_regw_sideeffects_CONFIG(idx);
153 }
154 
nrf_gpiote_te_default(NRF_GPIOTE_Type * p_reg,uint32_t idx)155 void nrf_gpiote_te_default(NRF_GPIOTE_Type * p_reg, uint32_t idx)
156 {
157     p_reg->CONFIG[idx] = 0;
158 #if !defined(NRF51_SERIES) && !defined(NRF52_SERIES)
159     p_reg->CONFIG[idx] = 0;
160 #endif
161     nrf_gpiote_regw_sideeffects_CONFIG(idx);
162 }
163