1 /*
2  * Copyright (c) 2017 Oticon A/S
3  * Copyright (c) 2023 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Note that the function prototypes are taken from the NRFx HAL
8  */
9 #include "hal/nrf_radio.h"
10 #include "bs_tracing.h"
11 #include "NHW_RADIO.h"
12 
nrf_radio_task_trigger(NRF_RADIO_Type * p_reg,nrf_radio_task_t task)13 void nrf_radio_task_trigger(NRF_RADIO_Type * p_reg, nrf_radio_task_t task)
14 {
15   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
16 
17 #define CASE_CALL_SIDEEFFECT(x) \
18   case NRF_RADIO_TASK_##x :\
19     nhw_RADIO_regw_sideeffects_TASKS_##x();\
20     break
21 
22   switch (task) {
23     CASE_CALL_SIDEEFFECT(TXEN);
24     CASE_CALL_SIDEEFFECT(RXEN);
25     CASE_CALL_SIDEEFFECT(START);
26     CASE_CALL_SIDEEFFECT(STOP);
27     CASE_CALL_SIDEEFFECT(DISABLE);
28     CASE_CALL_SIDEEFFECT(RSSISTART);
29 #if defined(RADIO_TASKS_RSSISTOP_TASKS_RSSISTOP_Msk)
30     CASE_CALL_SIDEEFFECT(RSSISTOP);
31 #endif
32     CASE_CALL_SIDEEFFECT(BCSTART);
33     CASE_CALL_SIDEEFFECT(BCSTOP);
34     CASE_CALL_SIDEEFFECT(EDSTART);
35     CASE_CALL_SIDEEFFECT(EDSTOP);
36     CASE_CALL_SIDEEFFECT(CCASTART);
37     CASE_CALL_SIDEEFFECT(CCASTOP);
38 #if defined(RADIO_TASKS_SOFTRESET_TASKS_SOFTRESET_Msk)
39     //To be enabled once NRF_RADIO_TASK_SOFTRESET is added to the HAL
40     CASE_CALL_SIDEEFFECT(SOFTRESET);
41 #endif
42     default:
43       bs_trace_error_line_time("%s: Not supported task %i started\n", __func__, task);
44       break;
45   }
46 #undef CASE_CALL_SIDEEFFECT
47 }
48 
nrf_radio_int_enable(NRF_RADIO_Type * p_reg,uint32_t mask)49 void nrf_radio_int_enable(NRF_RADIO_Type * p_reg, uint32_t mask)
50 {
51 #if defined(RADIO_INTENSET_READY_Msk)
52     p_reg->INTENSET = mask;
53 #elif defined(RADIO_INTENSET00_READY_Msk)
54     p_reg->INTENSET00 = mask;
55 #endif
56     nhw_RADIO_regw_sideeffects_INTENSET(0);
57 }
58 
nrf_radio_int_disable(NRF_RADIO_Type * p_reg,uint32_t mask)59 void nrf_radio_int_disable(NRF_RADIO_Type * p_reg, uint32_t mask)
60 {
61 #if defined(RADIO_INTENCLR_READY_Msk)
62     p_reg->INTENCLR = mask;
63 #elif defined(RADIO_INTENCLR00_READY_Msk)
64     p_reg->INTENCLR00 = mask;
65 #endif
66     nhw_RADIO_regw_sideeffects_INTENCLR(0);
67 }
68 
nrf_radio_bcc_set(NRF_RADIO_Type * p_reg,uint32_t radio_bcc)69 void nrf_radio_bcc_set(NRF_RADIO_Type * p_reg, uint32_t radio_bcc)
70 {
71   p_reg->BCC = radio_bcc;
72   nhw_RADIO_regw_sideeffects_BCC();
73 }
74 
75 #if defined(RADIO_POWER_POWER_Msk)
nrf_radio_power_set(NRF_RADIO_Type * p_reg,bool radio_power)76 void nrf_radio_power_set(NRF_RADIO_Type * p_reg, bool radio_power)
77 {
78   p_reg->POWER = (uint32_t) radio_power;
79   nhw_RADIO_regw_sideeffects_POWER();
80 }
81 #endif
82 
nrf_radio_event_clear(NRF_RADIO_Type * p_reg,nrf_radio_event_t event)83 void nrf_radio_event_clear(NRF_RADIO_Type * p_reg, nrf_radio_event_t event)
84 {
85   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
86   nhw_RADIO_regw_sideeffects_EVENTS_all(0);
87 }
88 
89 #if defined(DPPI_PRESENT)
90 
nrf_radio_subscribe_common(NRF_RADIO_Type * p_reg,nrf_radio_task_t task)91 static void nrf_radio_subscribe_common(NRF_RADIO_Type * p_reg,
92                                        nrf_radio_task_t task)
93 {
94   (void) p_reg;
95 
96 #define CASE_CALL_SIDEEFFECT(x) \
97   case NRF_RADIO_TASK_##x :\
98     nhw_RADIO_regw_sideeffects_SUBSCRIBE_##x(0);\
99     break
100 
101   switch (task) {
102     CASE_CALL_SIDEEFFECT(TXEN);
103     CASE_CALL_SIDEEFFECT(RXEN);
104     CASE_CALL_SIDEEFFECT(START);
105     CASE_CALL_SIDEEFFECT(STOP);
106     CASE_CALL_SIDEEFFECT(DISABLE);
107     CASE_CALL_SIDEEFFECT(RSSISTART);
108 #if defined(RADIO_TASKS_RSSISTOP_TASKS_RSSISTOP_Msk)
109     CASE_CALL_SIDEEFFECT(RSSISTOP);
110 #endif
111     CASE_CALL_SIDEEFFECT(BCSTART);
112     CASE_CALL_SIDEEFFECT(BCSTOP);
113     CASE_CALL_SIDEEFFECT(EDSTART);
114     CASE_CALL_SIDEEFFECT(EDSTOP);
115     CASE_CALL_SIDEEFFECT(CCASTART);
116     CASE_CALL_SIDEEFFECT(CCASTOP);
117 #if 0 /* defined(RADIO_TASKS_SOFTRESET_TASKS_SOFTRESET_Msk) */
118     CASE_CALL_SIDEEFFECT(SOFTRESET); //TODO missing in HAL
119 #endif
120     default:
121       bs_trace_error_line_time("%s: Attempted to subscribe to a not-supported task in the nrf_radio (%i)\n",
122                                __func__, task);
123       break;
124   }
125 #undef CASE_CALL_SIDEEFFECT
126 }
127 
nrf_radio_subscribe_set(NRF_RADIO_Type * p_reg,nrf_radio_task_t task,uint8_t channel)128 void nrf_radio_subscribe_set(NRF_RADIO_Type * p_reg,
129                              nrf_radio_task_t task,
130                              uint8_t        channel)
131 {
132     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + NRF_RADIO_DPPI_OFFSET)) =
133           ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
134     nrf_radio_subscribe_common(p_reg, task);
135 }
136 
nrf_radio_subscribe_clear(NRF_RADIO_Type * p_reg,nrf_radio_task_t task)137 void nrf_radio_subscribe_clear(NRF_RADIO_Type * p_reg,
138                                nrf_radio_task_t task)
139 {
140     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + NRF_RADIO_DPPI_OFFSET)) = 0;
141     nrf_radio_subscribe_common(p_reg, task);
142 }
143 
144 #endif /* defined(DPPI_PRESENT) */
145