1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Note that the function prototypes are taken from the NRFx HAL
7  */
8 
9 #define DPPIC_TASKS_CHG_Type NRF_DPPIC_TASKS_CHG_Type /* This type changed name between the 53 and 54 */
10 
11 #include "hal/nrf_dppi.h"
12 #include "bs_tracing.h"
13 #include "NHW_DPPI.h"
14 
get_dppi_inst_from_ptr(NRF_DPPIC_Type * p_reg)15 static int get_dppi_inst_from_ptr(NRF_DPPIC_Type * p_reg)
16 {
17     extern NRF_DPPIC_Type NRF_DPPIC_regs[];
18 
19     return ((uintptr_t)p_reg - (uintptr_t)NRF_DPPIC_regs) / sizeof(NRF_DPPIC_Type);
20 }
21 
nrf_dppi_task_trigger(NRF_DPPIC_Type * p_reg,nrf_dppi_task_t dppi_task)22 void nrf_dppi_task_trigger(NRF_DPPIC_Type * p_reg, nrf_dppi_task_t dppi_task)
23 {
24     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) dppi_task)) = 1;
25 
26     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
27     uint task_off = dppi_task - NRF_DPPI_TASK_CHG0_EN;
28     uint group = task_off / sizeof(NRF_DPPIC_TASKS_CHG_Type);
29 
30     if (task_off % sizeof(NRF_DPPIC_TASKS_CHG_Type) == 0) {
31         nhw_dppi_regw_sideeffects_TASK_CHGn_EN(dppi_inst, group);
32     } else {
33         nhw_dppi_regw_sideeffects_TASK_CHGn_DIS(dppi_inst, group);
34     }
35 }
36 
nrf_dppi_channels_disable_all(NRF_DPPIC_Type * p_reg)37 void nrf_dppi_channels_disable_all(NRF_DPPIC_Type * p_reg)
38 {
39     p_reg->CHENCLR = 0xFFFFFFFFuL;
40 
41     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
42     nhw_dppi_regw_sideeffects_CHENCLR(dppi_inst);
43 }
44 
nrf_dppi_channels_enable(NRF_DPPIC_Type * p_reg,uint32_t mask)45 void nrf_dppi_channels_enable(NRF_DPPIC_Type * p_reg, uint32_t mask)
46 {
47     p_reg->CHENSET = mask;
48 
49     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
50     nhw_dppi_regw_sideeffects_CHENSET(dppi_inst);
51 }
52 
nrf_dppi_channels_disable(NRF_DPPIC_Type * p_reg,uint32_t mask)53 void nrf_dppi_channels_disable(NRF_DPPIC_Type * p_reg, uint32_t mask)
54 {
55     p_reg->CHENCLR = mask;
56 
57     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
58     nhw_dppi_regw_sideeffects_CHENCLR(dppi_inst);
59 }
60 
nrf_dppi_subscribe_common(NRF_DPPIC_Type * p_reg,nrf_dppi_task_t task)61 static void nrf_dppi_subscribe_common(NRF_DPPIC_Type * p_reg,
62                                       nrf_dppi_task_t  task)
63 {
64     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
65     uint task_off = task - NRF_DPPI_TASK_CHG0_EN;
66     uint group = task_off / sizeof(NRF_DPPIC_TASKS_CHG_Type);
67 
68     if (task_off % sizeof(NRF_DPPIC_TASKS_CHG_Type) == 0) {
69         nhw_dppi_regw_sideeffects_SUBSCRIBE_CHG_EN(dppi_inst, group);
70     } else {
71         nhw_dppi_regw_sideeffects_SUBSCRIBE_CHG_DIS(dppi_inst, group);
72     }
73 }
74 
nrf_dppi_subscribe_set(NRF_DPPIC_Type * p_reg,nrf_dppi_task_t task,uint8_t channel)75 void nrf_dppi_subscribe_set(NRF_DPPIC_Type * p_reg,
76                             nrf_dppi_task_t  task,
77                             uint8_t          channel)
78 {
79     NRFX_ASSERT(channel < nrf_dppi_channel_number_get(p_reg));
80     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
81             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
82 
83     nrf_dppi_subscribe_common(p_reg, task);
84 }
85 
nrf_dppi_subscribe_clear(NRF_DPPIC_Type * p_reg,nrf_dppi_task_t task)86 void nrf_dppi_subscribe_clear(NRF_DPPIC_Type * p_reg, nrf_dppi_task_t task)
87 {
88     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
89 
90     nrf_dppi_subscribe_common(p_reg, task);
91 }
92 
nrf_dppi_channels_include_in_group(NRF_DPPIC_Type * p_reg,uint32_t channel_mask,nrf_dppi_channel_group_t channel_group)93 void nrf_dppi_channels_include_in_group(NRF_DPPIC_Type *         p_reg,
94                                         uint32_t                 channel_mask,
95                                         nrf_dppi_channel_group_t channel_group)
96 {
97     p_reg->CHG[(uint32_t) channel_group] =
98         p_reg->CHG[(uint32_t) channel_group] | (channel_mask);
99 
100     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
101     nhw_dppi_regw_sideeffects_CHGn(dppi_inst, channel_group);
102 }
103 
nrf_dppi_channels_remove_from_group(NRF_DPPIC_Type * p_reg,uint32_t channel_mask,nrf_dppi_channel_group_t channel_group)104 void nrf_dppi_channels_remove_from_group(NRF_DPPIC_Type *         p_reg,
105                                          uint32_t                 channel_mask,
106                                          nrf_dppi_channel_group_t channel_group)
107 {
108     p_reg->CHG[(uint32_t) channel_group] =
109         p_reg->CHG[(uint32_t) channel_group] & ~(channel_mask);
110 
111     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
112     nhw_dppi_regw_sideeffects_CHGn(dppi_inst, channel_group);
113 }
114 
nrf_dppi_group_clear(NRF_DPPIC_Type * p_reg,nrf_dppi_channel_group_t group)115 void nrf_dppi_group_clear(NRF_DPPIC_Type *         p_reg,
116                           nrf_dppi_channel_group_t group)
117 {
118     p_reg->CHG[(uint32_t) group] = 0;
119 
120     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
121     nhw_dppi_regw_sideeffects_CHGn(dppi_inst, group);
122 }
123 
nrf_dppi_group_enable(NRF_DPPIC_Type * p_reg,nrf_dppi_channel_group_t group)124 void nrf_dppi_group_enable(NRF_DPPIC_Type * p_reg, nrf_dppi_channel_group_t group)
125 {
126     p_reg->TASKS_CHG[(uint32_t) group].EN = 1;
127 
128     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
129     nhw_dppi_regw_sideeffects_TASK_CHGn_EN(dppi_inst, group);
130 }
131 
nrf_dppi_group_disable(NRF_DPPIC_Type * p_reg,nrf_dppi_channel_group_t group)132 void nrf_dppi_group_disable(NRF_DPPIC_Type *         p_reg,
133                             nrf_dppi_channel_group_t group)
134 {
135     p_reg->TASKS_CHG[(uint32_t) group].DIS = 1;
136 
137     uint dppi_inst = get_dppi_inst_from_ptr(p_reg);
138     nhw_dppi_regw_sideeffects_TASK_CHGn_DIS(dppi_inst, group);
139 
140 }
141