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