1 /*
2 * Copyright (c) 2017 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdbool.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include "time_machine_if.h"
10 #include "NRF_HW_model_top.h"
11 #include "NRF_AAR.h"
12 #include "NRF_AES_CCM.h"
13 #include "NRF_RNG.h"
14 #include "NRF_PPI.h"
15 #include "NRF_RTC.h"
16 #include "NRF_TIMER.h"
17 #include "NRF_CLOCK.h"
18 #include "NRF_RADIO.h"
19 #include "NRF_EGU.h"
20 #include "bs_tracing.h"
21
22 /*
23 * PPI — Programmable peripheral interconnect
24 * https://infocenter.nordicsemi.com/topic/ps_nrf52833/ppi.html?cp=4_1_0_5_14
25 *
26 */
27
28 NRF_PPI_Type NRF_PPI_regs; ///< The PPI registers
29
30 /**
31 * PPI module own TASKs handlers
32 */
nrf_ppi_TASK_CHG_ENDIS(int groupnbr,bool enable)33 void nrf_ppi_TASK_CHG_ENDIS( int groupnbr, bool enable /*false=disable task*/ ){
34 if ( enable ){
35 bs_trace_raw_time(9, "ppi: Channel group %i enabled\n", groupnbr);
36 NRF_PPI_regs.CHEN |= NRF_PPI_regs.CHG[groupnbr];
37 } else {
38 bs_trace_raw_time(9 ,"ppi: Channel group %i disable\n", groupnbr);
39 NRF_PPI_regs.CHEN &= ~NRF_PPI_regs.CHG[groupnbr];
40 }
41 //Note of the author: From the spec I cannot guess if these tasks will affect
42 //CHEN or a separate hidden register
43 }
nrf_ppi_TASK_CHG0_EN()44 void nrf_ppi_TASK_CHG0_EN() { nrf_ppi_TASK_CHG_ENDIS(0,true); }
nrf_ppi_TASK_CHG1_EN()45 void nrf_ppi_TASK_CHG1_EN() { nrf_ppi_TASK_CHG_ENDIS(1,true); }
nrf_ppi_TASK_CHG2_EN()46 void nrf_ppi_TASK_CHG2_EN() { nrf_ppi_TASK_CHG_ENDIS(2,true); }
nrf_ppi_TASK_CHG3_EN()47 void nrf_ppi_TASK_CHG3_EN() { nrf_ppi_TASK_CHG_ENDIS(3,true); }
nrf_ppi_TASK_CHG4_EN()48 void nrf_ppi_TASK_CHG4_EN() { nrf_ppi_TASK_CHG_ENDIS(4,true); }
nrf_ppi_TASK_CHG5_EN()49 void nrf_ppi_TASK_CHG5_EN() { nrf_ppi_TASK_CHG_ENDIS(5,true); }
nrf_ppi_TASK_CHG0_DIS()50 void nrf_ppi_TASK_CHG0_DIS(){ nrf_ppi_TASK_CHG_ENDIS(0,false); }
nrf_ppi_TASK_CHG1_DIS()51 void nrf_ppi_TASK_CHG1_DIS(){ nrf_ppi_TASK_CHG_ENDIS(1,false); }
nrf_ppi_TASK_CHG2_DIS()52 void nrf_ppi_TASK_CHG2_DIS(){ nrf_ppi_TASK_CHG_ENDIS(2,false); }
nrf_ppi_TASK_CHG3_DIS()53 void nrf_ppi_TASK_CHG3_DIS(){ nrf_ppi_TASK_CHG_ENDIS(3,false); }
nrf_ppi_TASK_CHG4_DIS()54 void nrf_ppi_TASK_CHG4_DIS(){ nrf_ppi_TASK_CHG_ENDIS(4,false); }
nrf_ppi_TASK_CHG5_DIS()55 void nrf_ppi_TASK_CHG5_DIS(){ nrf_ppi_TASK_CHG_ENDIS(5,false); }
56
57 typedef void (*dest_f_t)(void); ///<Syntactic sugar for task function pointer
58
59 typedef struct{
60 uint32_t channels_mask; //bitmask indicating which channel the event is mapped to
61 } ppi_event_to_ch_t;
62 ///Table contain which channels each event is activating (one entry per event)
63 static ppi_event_to_ch_t ppi_evt_to_ch[NUMBER_PPI_EVENTS];
64
65 typedef struct {
66 dest_f_t tep_f;
67 dest_f_t fork_tep_f;
68 } ppi_channel_tasks_t;
69 ///Table with TASKs each channel activates
70 static ppi_channel_tasks_t ppi_ch_tasks[NUMBER_PPI_CHANNELS];
71
72 typedef struct {
73 void *task_addr;
74 dest_f_t dest; //function to be called when task is triggered
75 } ppi_tasks_table_t;
76
77 /**
78 * Table of TASKs addresses (as provided by the SW) vs the model function
79 * pointer (which handles the task trigger)
80 */
81 static const ppi_tasks_table_t ppi_tasks_table[]={ //just the ones we may use
82 //POWER CLOCK:
83 //{ (void*)&NRF_CLOCK_regs.TASKS_LFCLKSTART , nrf_clock_TASKS_LFCLKSTART},
84 { (void*)&NRF_CLOCK_regs.TASKS_HFCLKSTART , nrf_clock_TASKS_HFCLKSTART},
85 //{ (void*)&NRF_CLOCK_regs.TASKS_HFCLKSTOP , nrf_clock_TASKS_HFCLKSTOP},
86
87 //RADIO:
88 { (void*)&NRF_RADIO_regs.TASKS_TXEN, nrf_radio_tasks_TXEN},
89 { (void*)&NRF_RADIO_regs.TASKS_RXEN, nrf_radio_tasks_RXEN},
90 { (void*)&NRF_RADIO_regs.TASKS_START, nrf_radio_tasks_START},
91 { (void*)&NRF_RADIO_regs.TASKS_STOP, nrf_radio_tasks_STOP},
92 { (void*)&NRF_RADIO_regs.TASKS_DISABLE, nrf_radio_tasks_DISABLE},
93 { (void*)&NRF_RADIO_regs.TASKS_RSSISTART, nrf_radio_tasks_RSSISTART},
94 { (void*)&NRF_RADIO_regs.TASKS_RSSISTOP, nrf_radio_tasks_RSSISTOP},
95 { (void*)&NRF_RADIO_regs.TASKS_BCSTART, nrf_radio_tasks_BCSTART},
96 { (void*)&NRF_RADIO_regs.TASKS_BCSTOP, nrf_radio_tasks_BCSTOP},
97 { (void*)&NRF_RADIO_regs.TASKS_EDSTART, nrf_radio_tasks_EDSTART},
98 { (void*)&NRF_RADIO_regs.TASKS_EDSTOP, nrf_radio_tasks_EDSTOP},
99 { (void*)&NRF_RADIO_regs.TASKS_CCASTART, nrf_radio_tasks_CCASTART},
100 { (void*)&NRF_RADIO_regs.TASKS_CCASTOP, nrf_radio_tasks_CCASTOP},
101
102 //TIMER0:
103 { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[0], nrf_timer0_TASK_CAPTURE_0},
104 { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[1], nrf_timer0_TASK_CAPTURE_1},
105 { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[2], nrf_timer0_TASK_CAPTURE_2},
106 { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[3], nrf_timer0_TASK_CAPTURE_3},
107 // { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[4], nrf_timer0_TASK_CAPTURE_4},
108 // { (void*)&NRF_TIMER_regs[0].TASKS_CAPTURE[5], nrf_timer0_TASK_CAPTURE_5},
109 { (void*)&NRF_TIMER_regs[0].TASKS_CLEAR, nrf_timer0_TASK_CLEAR},
110 { (void*)&NRF_TIMER_regs[0].TASKS_COUNT, nrf_timer0_TASK_COUNT},
111 { (void*)&NRF_TIMER_regs[0].TASKS_START, nrf_timer0_TASK_START},
112 { (void*)&NRF_TIMER_regs[0].TASKS_STOP, nrf_timer0_TASK_STOP},
113 //TIMER1:
114 { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[0], nrf_timer1_TASK_CAPTURE_0},
115 { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[1], nrf_timer1_TASK_CAPTURE_1},
116 { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[2], nrf_timer1_TASK_CAPTURE_2},
117 { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[3], nrf_timer1_TASK_CAPTURE_3},
118 // { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[4], nrf_timer1_TASK_CAPTURE_4},
119 // { (void*)&NRF_TIMER_regs[1].TASKS_CAPTURE[5], nrf_timer1_TASK_CAPTURE_5},
120 { (void*)&NRF_TIMER_regs[1].TASKS_CLEAR, nrf_timer1_TASK_CLEAR},
121 { (void*)&NRF_TIMER_regs[1].TASKS_COUNT, nrf_timer1_TASK_COUNT},
122 { (void*)&NRF_TIMER_regs[1].TASKS_START, nrf_timer1_TASK_START},
123 { (void*)&NRF_TIMER_regs[1].TASKS_STOP, nrf_timer1_TASK_STOP},
124 //TIMER2:
125 { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[0], nrf_timer2_TASK_CAPTURE_0},
126 { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[1], nrf_timer2_TASK_CAPTURE_1},
127 { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[2], nrf_timer2_TASK_CAPTURE_2},
128 { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[3], nrf_timer2_TASK_CAPTURE_3},
129 // { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[4], nrf_timer2_TASK_CAPTURE_4},
130 // { (void*)&NRF_TIMER_regs[2].TASKS_CAPTURE[5], nrf_timer2_TASK_CAPTURE_5},
131 { (void*)&NRF_TIMER_regs[2].TASKS_CLEAR, nrf_timer2_TASK_CLEAR},
132 { (void*)&NRF_TIMER_regs[2].TASKS_COUNT, nrf_timer2_TASK_COUNT},
133 { (void*)&NRF_TIMER_regs[2].TASKS_START, nrf_timer2_TASK_START},
134 { (void*)&NRF_TIMER_regs[2].TASKS_STOP, nrf_timer2_TASK_STOP},
135 //TIMER3:
136 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[0], nrf_timer3_TASK_CAPTURE_0},
137 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[1], nrf_timer3_TASK_CAPTURE_1},
138 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[2], nrf_timer3_TASK_CAPTURE_2},
139 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[3], nrf_timer3_TASK_CAPTURE_3},
140 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[4], nrf_timer3_TASK_CAPTURE_4},
141 { (void*)&NRF_TIMER_regs[3].TASKS_CAPTURE[5], nrf_timer3_TASK_CAPTURE_5},
142 { (void*)&NRF_TIMER_regs[3].TASKS_CLEAR, nrf_timer3_TASK_CLEAR},
143 { (void*)&NRF_TIMER_regs[3].TASKS_COUNT, nrf_timer3_TASK_COUNT},
144 { (void*)&NRF_TIMER_regs[3].TASKS_START, nrf_timer3_TASK_START},
145 { (void*)&NRF_TIMER_regs[3].TASKS_STOP, nrf_timer3_TASK_STOP},
146 //TIMER4:
147 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[0], nrf_timer4_TASK_CAPTURE_0},
148 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[1], nrf_timer4_TASK_CAPTURE_1},
149 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[2], nrf_timer4_TASK_CAPTURE_2},
150 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[3], nrf_timer4_TASK_CAPTURE_3},
151 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[4], nrf_timer4_TASK_CAPTURE_4},
152 { (void*)&NRF_TIMER_regs[4].TASKS_CAPTURE[5], nrf_timer4_TASK_CAPTURE_5},
153 { (void*)&NRF_TIMER_regs[4].TASKS_CLEAR, nrf_timer4_TASK_CLEAR},
154 { (void*)&NRF_TIMER_regs[4].TASKS_COUNT, nrf_timer4_TASK_COUNT},
155 { (void*)&NRF_TIMER_regs[4].TASKS_START, nrf_timer4_TASK_START},
156 { (void*)&NRF_TIMER_regs[4].TASKS_STOP, nrf_timer4_TASK_STOP},
157
158 //RTC:
159 //{ (void*)&(NRF_RTC_regs[0]).TASKS_CLEAR, nrf_rtc0_TASKS_CLEAR},
160 //{ (void*)&(NRF_RTC_regs[0]).TASKS_START, nrf_rtc0_TASKS_START},
161 //{ (void*)&(NRF_RTC_regs[0]).TASKS_STOP , nrf_rtc0_TASKS_STOP},
162 //{ (void*)&(NRF_RTC_regs[0]).TASKS_TRIGOVRFLW , nrf_rtc0_TASKS_TRIGOVRFLW},
163 //{ (void*)&(NRF_RTC_regs[1]).TASKS_CLEAR, nrf_rtc1_TASKS_CLEAR},
164 //{ (void*)&(NRF_RTC_regs[1]).TASKS_START, nrf_rtc1_TASKS_START},
165 //{ (void*)&(NRF_RTC_regs[1]).TASKS_STOP , nrf_rtc1_TASKS_STOP},
166 //{ (void*)&(NRF_RTC_regs[1]).TASKS_TRIGOVRFLW , nrf_rtc1_TASKS_TRIGOVRFLW},
167 //{ (void*)&(NRF_RTC_regs[2]).TASKS_CLEAR, nrf_rtc2_TASKS_CLEAR},
168 //{ (void*)&(NRF_RTC_regs[2]).TASKS_START, nrf_rtc2_TASKS_START},
169 //{ (void*)&(NRF_RTC_regs[2]).TASKS_STOP , nrf_rtc2_TASKS_STOP},
170 //{ (void*)&(NRF_RTC_regs[2]).TASKS_TRIGOVRFLW , nrf_rtc2_TASKS_TRIGOVRFLW},
171
172 //RNG:
173 { (void*)&NRF_RNG_regs.TASKS_START, nrf_rng_task_start},
174 { (void*)&NRF_RNG_regs.TASKS_STOP , nrf_rng_task_stop},
175
176 //ECB
177
178 //AAR
179 { (void*)&NRF_AAR_regs.TASKS_START , nrf_aar_TASK_START},
180
181 //CCM
182 { (void*)&NRF_CCM_regs.TASKS_CRYPT , nrf_ccm_TASK_CRYPT},
183
184 //PPI:
185 { (void*)&NRF_PPI_regs.TASKS_CHG[0].EN, nrf_ppi_TASK_CHG0_EN},
186 { (void*)&NRF_PPI_regs.TASKS_CHG[1].EN, nrf_ppi_TASK_CHG1_EN},
187 { (void*)&NRF_PPI_regs.TASKS_CHG[2].EN, nrf_ppi_TASK_CHG2_EN},
188 { (void*)&NRF_PPI_regs.TASKS_CHG[3].EN, nrf_ppi_TASK_CHG3_EN},
189 { (void*)&NRF_PPI_regs.TASKS_CHG[4].EN, nrf_ppi_TASK_CHG4_EN},
190 { (void*)&NRF_PPI_regs.TASKS_CHG[5].EN, nrf_ppi_TASK_CHG5_EN},
191 { (void*)&NRF_PPI_regs.TASKS_CHG[0].DIS, nrf_ppi_TASK_CHG0_DIS},
192 { (void*)&NRF_PPI_regs.TASKS_CHG[1].DIS, nrf_ppi_TASK_CHG1_DIS},
193 { (void*)&NRF_PPI_regs.TASKS_CHG[2].DIS, nrf_ppi_TASK_CHG2_DIS},
194 { (void*)&NRF_PPI_regs.TASKS_CHG[3].DIS, nrf_ppi_TASK_CHG3_DIS},
195 { (void*)&NRF_PPI_regs.TASKS_CHG[4].DIS, nrf_ppi_TASK_CHG4_DIS},
196 { (void*)&NRF_PPI_regs.TASKS_CHG[5].DIS, nrf_ppi_TASK_CHG5_DIS},
197
198 //EGU:
199 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[0] , nrf_egu_0_TASK_TRIGGER_0},
200 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[1] , nrf_egu_0_TASK_TRIGGER_1},
201 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[2] , nrf_egu_0_TASK_TRIGGER_2},
202 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[3] , nrf_egu_0_TASK_TRIGGER_3},
203 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[4] , nrf_egu_0_TASK_TRIGGER_4},
204 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[5] , nrf_egu_0_TASK_TRIGGER_5},
205 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[6] , nrf_egu_0_TASK_TRIGGER_6},
206 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[7] , nrf_egu_0_TASK_TRIGGER_7},
207 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[8] , nrf_egu_0_TASK_TRIGGER_8},
208 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[9] , nrf_egu_0_TASK_TRIGGER_9},
209 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[10] , nrf_egu_0_TASK_TRIGGER_10},
210 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[11] , nrf_egu_0_TASK_TRIGGER_11},
211 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[12] , nrf_egu_0_TASK_TRIGGER_12},
212 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[13] , nrf_egu_0_TASK_TRIGGER_13},
213 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[14] , nrf_egu_0_TASK_TRIGGER_14},
214 {(void*)&NRF_EGU_regs[0].TASKS_TRIGGER[15] , nrf_egu_0_TASK_TRIGGER_15},
215 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[0] , nrf_egu_1_TASK_TRIGGER_0},
216 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[1] , nrf_egu_1_TASK_TRIGGER_1},
217 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[2] , nrf_egu_1_TASK_TRIGGER_2},
218 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[3] , nrf_egu_1_TASK_TRIGGER_3},
219 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[4] , nrf_egu_1_TASK_TRIGGER_4},
220 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[5] , nrf_egu_1_TASK_TRIGGER_5},
221 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[6] , nrf_egu_1_TASK_TRIGGER_6},
222 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[7] , nrf_egu_1_TASK_TRIGGER_7},
223 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[8] , nrf_egu_1_TASK_TRIGGER_8},
224 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[9] , nrf_egu_1_TASK_TRIGGER_9},
225 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[10] , nrf_egu_1_TASK_TRIGGER_10},
226 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[11] , nrf_egu_1_TASK_TRIGGER_11},
227 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[12] , nrf_egu_1_TASK_TRIGGER_12},
228 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[13] , nrf_egu_1_TASK_TRIGGER_13},
229 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[14] , nrf_egu_1_TASK_TRIGGER_14},
230 {(void*)&NRF_EGU_regs[1].TASKS_TRIGGER[15] , nrf_egu_1_TASK_TRIGGER_15},
231 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[0] , nrf_egu_2_TASK_TRIGGER_0},
232 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[1] , nrf_egu_2_TASK_TRIGGER_1},
233 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[2] , nrf_egu_2_TASK_TRIGGER_2},
234 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[3] , nrf_egu_2_TASK_TRIGGER_3},
235 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[4] , nrf_egu_2_TASK_TRIGGER_4},
236 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[5] , nrf_egu_2_TASK_TRIGGER_5},
237 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[6] , nrf_egu_2_TASK_TRIGGER_6},
238 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[7] , nrf_egu_2_TASK_TRIGGER_7},
239 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[8] , nrf_egu_2_TASK_TRIGGER_8},
240 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[9] , nrf_egu_2_TASK_TRIGGER_9},
241 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[10] , nrf_egu_2_TASK_TRIGGER_10},
242 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[11] , nrf_egu_2_TASK_TRIGGER_11},
243 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[12] , nrf_egu_2_TASK_TRIGGER_12},
244 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[13] , nrf_egu_2_TASK_TRIGGER_13},
245 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[14] , nrf_egu_2_TASK_TRIGGER_14},
246 {(void*)&NRF_EGU_regs[2].TASKS_TRIGGER[15] , nrf_egu_2_TASK_TRIGGER_15},
247 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[0] , nrf_egu_3_TASK_TRIGGER_0},
248 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[1] , nrf_egu_3_TASK_TRIGGER_1},
249 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[2] , nrf_egu_3_TASK_TRIGGER_2},
250 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[3] , nrf_egu_3_TASK_TRIGGER_3},
251 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[4] , nrf_egu_3_TASK_TRIGGER_4},
252 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[5] , nrf_egu_3_TASK_TRIGGER_5},
253 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[6] , nrf_egu_3_TASK_TRIGGER_6},
254 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[7] , nrf_egu_3_TASK_TRIGGER_7},
255 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[8] , nrf_egu_3_TASK_TRIGGER_8},
256 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[9] , nrf_egu_3_TASK_TRIGGER_9},
257 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[10] , nrf_egu_3_TASK_TRIGGER_10},
258 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[11] , nrf_egu_3_TASK_TRIGGER_11},
259 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[12] , nrf_egu_3_TASK_TRIGGER_12},
260 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[13] , nrf_egu_3_TASK_TRIGGER_13},
261 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[14] , nrf_egu_3_TASK_TRIGGER_14},
262 {(void*)&NRF_EGU_regs[3].TASKS_TRIGGER[15] , nrf_egu_3_TASK_TRIGGER_15},
263 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[0] , nrf_egu_4_TASK_TRIGGER_0},
264 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[1] , nrf_egu_4_TASK_TRIGGER_1},
265 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[2] , nrf_egu_4_TASK_TRIGGER_2},
266 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[3] , nrf_egu_4_TASK_TRIGGER_3},
267 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[4] , nrf_egu_4_TASK_TRIGGER_4},
268 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[5] , nrf_egu_4_TASK_TRIGGER_5},
269 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[6] , nrf_egu_4_TASK_TRIGGER_6},
270 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[7] , nrf_egu_4_TASK_TRIGGER_7},
271 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[8] , nrf_egu_4_TASK_TRIGGER_8},
272 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[9] , nrf_egu_4_TASK_TRIGGER_9},
273 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[10] , nrf_egu_4_TASK_TRIGGER_10},
274 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[11] , nrf_egu_4_TASK_TRIGGER_11},
275 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[12] , nrf_egu_4_TASK_TRIGGER_12},
276 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[13] , nrf_egu_4_TASK_TRIGGER_13},
277 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[14] , nrf_egu_4_TASK_TRIGGER_14},
278 {(void*)&NRF_EGU_regs[4].TASKS_TRIGGER[15] , nrf_egu_4_TASK_TRIGGER_15},
279 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[0] , nrf_egu_5_TASK_TRIGGER_0},
280 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[1] , nrf_egu_5_TASK_TRIGGER_1},
281 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[2] , nrf_egu_5_TASK_TRIGGER_2},
282 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[3] , nrf_egu_5_TASK_TRIGGER_3},
283 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[4] , nrf_egu_5_TASK_TRIGGER_4},
284 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[5] , nrf_egu_5_TASK_TRIGGER_5},
285 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[6] , nrf_egu_5_TASK_TRIGGER_6},
286 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[7] , nrf_egu_5_TASK_TRIGGER_7},
287 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[8] , nrf_egu_5_TASK_TRIGGER_8},
288 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[9] , nrf_egu_5_TASK_TRIGGER_9},
289 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[10] , nrf_egu_5_TASK_TRIGGER_10},
290 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[11] , nrf_egu_5_TASK_TRIGGER_11},
291 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[12] , nrf_egu_5_TASK_TRIGGER_12},
292 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[13] , nrf_egu_5_TASK_TRIGGER_13},
293 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[14] , nrf_egu_5_TASK_TRIGGER_14},
294 {(void*)&NRF_EGU_regs[5].TASKS_TRIGGER[15] , nrf_egu_5_TASK_TRIGGER_15},
295
296 //End marker
297 { NULL, NULL }
298 };
299
300 /**
301 * Table to convert from an event_address as programmed by the SW into an
302 * event_type used here to index tables
303 */
304 typedef struct {
305 ppi_event_types_t event_type;
306 void *event_addr;
307 } ppi_event_table_t;
308
309 static const ppi_event_table_t ppi_events_table[] = { //better keep same order as in ppi_event_types_t
310 {RADIO_EVENTS_READY, &NRF_RADIO_regs.EVENTS_READY},
311 {RADIO_EVENTS_ADDRESS, &NRF_RADIO_regs.EVENTS_ADDRESS},
312 {RADIO_EVENTS_PAYLOAD, &NRF_RADIO_regs.EVENTS_PAYLOAD},
313 {RADIO_EVENTS_END, &NRF_RADIO_regs.EVENTS_END},
314 {RADIO_EVENTS_DISABLED,&NRF_RADIO_regs.EVENTS_DISABLED},
315 {RADIO_EVENTS_DEVMATCH,&NRF_RADIO_regs.EVENTS_DEVMATCH},
316 {RADIO_EVENTS_DEVMISS ,&NRF_RADIO_regs.EVENTS_DEVMISS},
317 {RADIO_EVENTS_RSSIEND, &NRF_RADIO_regs.EVENTS_RSSIEND},
318 {RADIO_EVENTS_BCMATCH, &NRF_RADIO_regs.EVENTS_BCMATCH},
319 {RADIO_EVENTS_CRCOK, &NRF_RADIO_regs.EVENTS_CRCOK},
320 {RADIO_EVENTS_CRCERROR,&NRF_RADIO_regs.EVENTS_CRCERROR},
321 {RADIO_EVENTS_FRAMESTART,&NRF_RADIO_regs.EVENTS_FRAMESTART},
322 {RADIO_EVENTS_EDEND, &NRF_RADIO_regs.EVENTS_EDEND},
323 {RADIO_EVENTS_EDSTOPPED, &NRF_RADIO_regs.EVENTS_EDSTOPPED},
324 {RADIO_EVENTS_CCAIDLE, &NRF_RADIO_regs.EVENTS_CCAIDLE},
325 {RADIO_EVENTS_CCABUSY, &NRF_RADIO_regs.EVENTS_CCABUSY},
326 {RADIO_EVENTS_CCASTOPPED, &NRF_RADIO_regs.EVENTS_CCASTOPPED},
327 {RADIO_EVENTS_RATEBOOST, &NRF_RADIO_regs.EVENTS_RATEBOOST},
328 {RADIO_EVENTS_TXREADY, &NRF_RADIO_regs.EVENTS_TXREADY},
329 {RADIO_EVENTS_RXREADY, &NRF_RADIO_regs.EVENTS_RXREADY},
330 {RADIO_EVENTS_MHRMATCH,&NRF_RADIO_regs.EVENTS_MHRMATCH},
331 {RADIO_EVENTS_SYNC, &NRF_RADIO_regs.EVENTS_SYNC},
332 {RADIO_EVENTS_PHYEND, &NRF_RADIO_regs.EVENTS_PHYEND},
333 {RADIO_EVENTS_CTEPRESENT,&NRF_RADIO_regs.EVENTS_CTEPRESENT},
334
335 {TIMER0_EVENTS_COMPARE_0, &NRF_TIMER_regs[0].EVENTS_COMPARE[0]},
336 {TIMER0_EVENTS_COMPARE_1, &NRF_TIMER_regs[0].EVENTS_COMPARE[1]},
337 {TIMER0_EVENTS_COMPARE_2, &NRF_TIMER_regs[0].EVENTS_COMPARE[2]},
338 {TIMER0_EVENTS_COMPARE_3, &NRF_TIMER_regs[0].EVENTS_COMPARE[3]},
339 // {TIMER0_EVENTS_COMPARE_4, &NRF_TIMER_regs[0].EVENTS_COMPARE[4]},
340 // {TIMER0_EVENTS_COMPARE_5, &NRF_TIMER_regs[0].EVENTS_COMPARE[5]},
341
342 {TIMER1_EVENTS_COMPARE_0, &NRF_TIMER_regs[1].EVENTS_COMPARE[0]},
343 {TIMER1_EVENTS_COMPARE_1, &NRF_TIMER_regs[1].EVENTS_COMPARE[1]},
344 {TIMER1_EVENTS_COMPARE_2, &NRF_TIMER_regs[1].EVENTS_COMPARE[2]},
345 {TIMER1_EVENTS_COMPARE_3, &NRF_TIMER_regs[1].EVENTS_COMPARE[3]},
346 // {TIMER1_EVENTS_COMPARE_4, &NRF_TIMER_regs[1].EVENTS_COMPARE[4]},
347 // {TIMER1_EVENTS_COMPARE_5, &NRF_TIMER_regs[1].EVENTS_COMPARE[5]},
348
349 {TIMER2_EVENTS_COMPARE_0, &NRF_TIMER_regs[2].EVENTS_COMPARE[0]},
350 {TIMER2_EVENTS_COMPARE_1, &NRF_TIMER_regs[2].EVENTS_COMPARE[1]},
351 {TIMER2_EVENTS_COMPARE_2, &NRF_TIMER_regs[2].EVENTS_COMPARE[2]},
352 {TIMER2_EVENTS_COMPARE_3, &NRF_TIMER_regs[2].EVENTS_COMPARE[3]},
353 // {TIMER2_EVENTS_COMPARE_4, &NRF_TIMER_regs[2].EVENTS_COMPARE[4]},
354 // {TIMER2_EVENTS_COMPARE_5, &NRF_TIMER_regs[2].EVENTS_COMPARE[5]},
355
356 {RTC0_EVENTS_OVRFLW, &NRF_RTC_regs[0].EVENTS_OVRFLW},
357 {RTC0_EVENTS_COMPARE_0, &NRF_RTC_regs[0].EVENTS_COMPARE[0]},
358 {RTC0_EVENTS_COMPARE_1, &NRF_RTC_regs[0].EVENTS_COMPARE[1]},
359 {RTC0_EVENTS_COMPARE_2, &NRF_RTC_regs[0].EVENTS_COMPARE[2]},
360 {RTC0_EVENTS_COMPARE_3, &NRF_RTC_regs[0].EVENTS_COMPARE[3]},
361
362 {TEMP_EVENTS_DATARDY, &NRF_TEMP_regs.EVENTS_DATARDY},
363
364 //{RNG_EVENTS_VALRDY, &NRF_RNG_regs.EVENTS_VALRDY},
365
366 {CCM_EVENTS_ENDKSGEN, &NRF_CCM_regs.EVENTS_ENDKSGEN},
367 {CCM_EVENTS_ENDCRYPT, &NRF_CCM_regs.EVENTS_ENDCRYPT},
368 {CCM_EVENTS_ERROR, &NRF_CCM_regs.EVENTS_ERROR},
369
370 {RTC1_EVENTS_OVRFLW, &NRF_RTC_regs[1].EVENTS_OVRFLW},
371 {RTC1_EVENTS_COMPARE_0, &NRF_RTC_regs[1].EVENTS_COMPARE[0]},
372 {RTC1_EVENTS_COMPARE_1, &NRF_RTC_regs[1].EVENTS_COMPARE[1]},
373 {RTC1_EVENTS_COMPARE_2, &NRF_RTC_regs[1].EVENTS_COMPARE[2]},
374 {RTC1_EVENTS_COMPARE_3, &NRF_RTC_regs[1].EVENTS_COMPARE[3]},
375
376 {EGU0_EVENTS_TRIGGERED_0, &NRF_EGU_regs[0].EVENTS_TRIGGERED[0]}, /*These are autogenerated (See NRF_EGU.c)*/
377 {EGU0_EVENTS_TRIGGERED_1, &NRF_EGU_regs[0].EVENTS_TRIGGERED[1]},
378 {EGU0_EVENTS_TRIGGERED_2, &NRF_EGU_regs[0].EVENTS_TRIGGERED[2]},
379 {EGU0_EVENTS_TRIGGERED_3, &NRF_EGU_regs[0].EVENTS_TRIGGERED[3]},
380 {EGU0_EVENTS_TRIGGERED_4, &NRF_EGU_regs[0].EVENTS_TRIGGERED[4]},
381 {EGU0_EVENTS_TRIGGERED_5, &NRF_EGU_regs[0].EVENTS_TRIGGERED[5]},
382 {EGU0_EVENTS_TRIGGERED_6, &NRF_EGU_regs[0].EVENTS_TRIGGERED[6]},
383 {EGU0_EVENTS_TRIGGERED_7, &NRF_EGU_regs[0].EVENTS_TRIGGERED[7]},
384 {EGU0_EVENTS_TRIGGERED_8, &NRF_EGU_regs[0].EVENTS_TRIGGERED[8]},
385 {EGU0_EVENTS_TRIGGERED_9, &NRF_EGU_regs[0].EVENTS_TRIGGERED[9]},
386 {EGU0_EVENTS_TRIGGERED_10, &NRF_EGU_regs[0].EVENTS_TRIGGERED[10]},
387 {EGU0_EVENTS_TRIGGERED_11, &NRF_EGU_regs[0].EVENTS_TRIGGERED[11]},
388 {EGU0_EVENTS_TRIGGERED_12, &NRF_EGU_regs[0].EVENTS_TRIGGERED[12]},
389 {EGU0_EVENTS_TRIGGERED_13, &NRF_EGU_regs[0].EVENTS_TRIGGERED[13]},
390 {EGU0_EVENTS_TRIGGERED_14, &NRF_EGU_regs[0].EVENTS_TRIGGERED[14]},
391 {EGU0_EVENTS_TRIGGERED_15, &NRF_EGU_regs[0].EVENTS_TRIGGERED[15]},
392 {EGU1_EVENTS_TRIGGERED_0, &NRF_EGU_regs[1].EVENTS_TRIGGERED[0]},
393 {EGU1_EVENTS_TRIGGERED_1, &NRF_EGU_regs[1].EVENTS_TRIGGERED[1]},
394 {EGU1_EVENTS_TRIGGERED_2, &NRF_EGU_regs[1].EVENTS_TRIGGERED[2]},
395 {EGU1_EVENTS_TRIGGERED_3, &NRF_EGU_regs[1].EVENTS_TRIGGERED[3]},
396 {EGU1_EVENTS_TRIGGERED_4, &NRF_EGU_regs[1].EVENTS_TRIGGERED[4]},
397 {EGU1_EVENTS_TRIGGERED_5, &NRF_EGU_regs[1].EVENTS_TRIGGERED[5]},
398 {EGU1_EVENTS_TRIGGERED_6, &NRF_EGU_regs[1].EVENTS_TRIGGERED[6]},
399 {EGU1_EVENTS_TRIGGERED_7, &NRF_EGU_regs[1].EVENTS_TRIGGERED[7]},
400 {EGU1_EVENTS_TRIGGERED_8, &NRF_EGU_regs[1].EVENTS_TRIGGERED[8]},
401 {EGU1_EVENTS_TRIGGERED_9, &NRF_EGU_regs[1].EVENTS_TRIGGERED[9]},
402 {EGU1_EVENTS_TRIGGERED_10, &NRF_EGU_regs[1].EVENTS_TRIGGERED[10]},
403 {EGU1_EVENTS_TRIGGERED_11, &NRF_EGU_regs[1].EVENTS_TRIGGERED[11]},
404 {EGU1_EVENTS_TRIGGERED_12, &NRF_EGU_regs[1].EVENTS_TRIGGERED[12]},
405 {EGU1_EVENTS_TRIGGERED_13, &NRF_EGU_regs[1].EVENTS_TRIGGERED[13]},
406 {EGU1_EVENTS_TRIGGERED_14, &NRF_EGU_regs[1].EVENTS_TRIGGERED[14]},
407 {EGU1_EVENTS_TRIGGERED_15, &NRF_EGU_regs[1].EVENTS_TRIGGERED[15]},
408 {EGU2_EVENTS_TRIGGERED_0, &NRF_EGU_regs[2].EVENTS_TRIGGERED[0]},
409 {EGU2_EVENTS_TRIGGERED_1, &NRF_EGU_regs[2].EVENTS_TRIGGERED[1]},
410 {EGU2_EVENTS_TRIGGERED_2, &NRF_EGU_regs[2].EVENTS_TRIGGERED[2]},
411 {EGU2_EVENTS_TRIGGERED_3, &NRF_EGU_regs[2].EVENTS_TRIGGERED[3]},
412 {EGU2_EVENTS_TRIGGERED_4, &NRF_EGU_regs[2].EVENTS_TRIGGERED[4]},
413 {EGU2_EVENTS_TRIGGERED_5, &NRF_EGU_regs[2].EVENTS_TRIGGERED[5]},
414 {EGU2_EVENTS_TRIGGERED_6, &NRF_EGU_regs[2].EVENTS_TRIGGERED[6]},
415 {EGU2_EVENTS_TRIGGERED_7, &NRF_EGU_regs[2].EVENTS_TRIGGERED[7]},
416 {EGU2_EVENTS_TRIGGERED_8, &NRF_EGU_regs[2].EVENTS_TRIGGERED[8]},
417 {EGU2_EVENTS_TRIGGERED_9, &NRF_EGU_regs[2].EVENTS_TRIGGERED[9]},
418 {EGU2_EVENTS_TRIGGERED_10, &NRF_EGU_regs[2].EVENTS_TRIGGERED[10]},
419 {EGU2_EVENTS_TRIGGERED_11, &NRF_EGU_regs[2].EVENTS_TRIGGERED[11]},
420 {EGU2_EVENTS_TRIGGERED_12, &NRF_EGU_regs[2].EVENTS_TRIGGERED[12]},
421 {EGU2_EVENTS_TRIGGERED_13, &NRF_EGU_regs[2].EVENTS_TRIGGERED[13]},
422 {EGU2_EVENTS_TRIGGERED_14, &NRF_EGU_regs[2].EVENTS_TRIGGERED[14]},
423 {EGU2_EVENTS_TRIGGERED_15, &NRF_EGU_regs[2].EVENTS_TRIGGERED[15]},
424 {EGU3_EVENTS_TRIGGERED_0, &NRF_EGU_regs[3].EVENTS_TRIGGERED[0]},
425 {EGU3_EVENTS_TRIGGERED_1, &NRF_EGU_regs[3].EVENTS_TRIGGERED[1]},
426 {EGU3_EVENTS_TRIGGERED_2, &NRF_EGU_regs[3].EVENTS_TRIGGERED[2]},
427 {EGU3_EVENTS_TRIGGERED_3, &NRF_EGU_regs[3].EVENTS_TRIGGERED[3]},
428 {EGU3_EVENTS_TRIGGERED_4, &NRF_EGU_regs[3].EVENTS_TRIGGERED[4]},
429 {EGU3_EVENTS_TRIGGERED_5, &NRF_EGU_regs[3].EVENTS_TRIGGERED[5]},
430 {EGU3_EVENTS_TRIGGERED_6, &NRF_EGU_regs[3].EVENTS_TRIGGERED[6]},
431 {EGU3_EVENTS_TRIGGERED_7, &NRF_EGU_regs[3].EVENTS_TRIGGERED[7]},
432 {EGU3_EVENTS_TRIGGERED_8, &NRF_EGU_regs[3].EVENTS_TRIGGERED[8]},
433 {EGU3_EVENTS_TRIGGERED_9, &NRF_EGU_regs[3].EVENTS_TRIGGERED[9]},
434 {EGU3_EVENTS_TRIGGERED_10, &NRF_EGU_regs[3].EVENTS_TRIGGERED[10]},
435 {EGU3_EVENTS_TRIGGERED_11, &NRF_EGU_regs[3].EVENTS_TRIGGERED[11]},
436 {EGU3_EVENTS_TRIGGERED_12, &NRF_EGU_regs[3].EVENTS_TRIGGERED[12]},
437 {EGU3_EVENTS_TRIGGERED_13, &NRF_EGU_regs[3].EVENTS_TRIGGERED[13]},
438 {EGU3_EVENTS_TRIGGERED_14, &NRF_EGU_regs[3].EVENTS_TRIGGERED[14]},
439 {EGU3_EVENTS_TRIGGERED_15, &NRF_EGU_regs[3].EVENTS_TRIGGERED[15]},
440 {EGU4_EVENTS_TRIGGERED_0, &NRF_EGU_regs[4].EVENTS_TRIGGERED[0]},
441 {EGU4_EVENTS_TRIGGERED_1, &NRF_EGU_regs[4].EVENTS_TRIGGERED[1]},
442 {EGU4_EVENTS_TRIGGERED_2, &NRF_EGU_regs[4].EVENTS_TRIGGERED[2]},
443 {EGU4_EVENTS_TRIGGERED_3, &NRF_EGU_regs[4].EVENTS_TRIGGERED[3]},
444 {EGU4_EVENTS_TRIGGERED_4, &NRF_EGU_regs[4].EVENTS_TRIGGERED[4]},
445 {EGU4_EVENTS_TRIGGERED_5, &NRF_EGU_regs[4].EVENTS_TRIGGERED[5]},
446 {EGU4_EVENTS_TRIGGERED_6, &NRF_EGU_regs[4].EVENTS_TRIGGERED[6]},
447 {EGU4_EVENTS_TRIGGERED_7, &NRF_EGU_regs[4].EVENTS_TRIGGERED[7]},
448 {EGU4_EVENTS_TRIGGERED_8, &NRF_EGU_regs[4].EVENTS_TRIGGERED[8]},
449 {EGU4_EVENTS_TRIGGERED_9, &NRF_EGU_regs[4].EVENTS_TRIGGERED[9]},
450 {EGU4_EVENTS_TRIGGERED_10, &NRF_EGU_regs[4].EVENTS_TRIGGERED[10]},
451 {EGU4_EVENTS_TRIGGERED_11, &NRF_EGU_regs[4].EVENTS_TRIGGERED[11]},
452 {EGU4_EVENTS_TRIGGERED_12, &NRF_EGU_regs[4].EVENTS_TRIGGERED[12]},
453 {EGU4_EVENTS_TRIGGERED_13, &NRF_EGU_regs[4].EVENTS_TRIGGERED[13]},
454 {EGU4_EVENTS_TRIGGERED_14, &NRF_EGU_regs[4].EVENTS_TRIGGERED[14]},
455 {EGU4_EVENTS_TRIGGERED_15, &NRF_EGU_regs[4].EVENTS_TRIGGERED[15]},
456 {EGU5_EVENTS_TRIGGERED_0, &NRF_EGU_regs[5].EVENTS_TRIGGERED[0]},
457 {EGU5_EVENTS_TRIGGERED_1, &NRF_EGU_regs[5].EVENTS_TRIGGERED[1]},
458 {EGU5_EVENTS_TRIGGERED_2, &NRF_EGU_regs[5].EVENTS_TRIGGERED[2]},
459 {EGU5_EVENTS_TRIGGERED_3, &NRF_EGU_regs[5].EVENTS_TRIGGERED[3]},
460 {EGU5_EVENTS_TRIGGERED_4, &NRF_EGU_regs[5].EVENTS_TRIGGERED[4]},
461 {EGU5_EVENTS_TRIGGERED_5, &NRF_EGU_regs[5].EVENTS_TRIGGERED[5]},
462 {EGU5_EVENTS_TRIGGERED_6, &NRF_EGU_regs[5].EVENTS_TRIGGERED[6]},
463 {EGU5_EVENTS_TRIGGERED_7, &NRF_EGU_regs[5].EVENTS_TRIGGERED[7]},
464 {EGU5_EVENTS_TRIGGERED_8, &NRF_EGU_regs[5].EVENTS_TRIGGERED[8]},
465 {EGU5_EVENTS_TRIGGERED_9, &NRF_EGU_regs[5].EVENTS_TRIGGERED[9]},
466 {EGU5_EVENTS_TRIGGERED_10, &NRF_EGU_regs[5].EVENTS_TRIGGERED[10]},
467 {EGU5_EVENTS_TRIGGERED_11, &NRF_EGU_regs[5].EVENTS_TRIGGERED[11]},
468 {EGU5_EVENTS_TRIGGERED_12, &NRF_EGU_regs[5].EVENTS_TRIGGERED[12]},
469 {EGU5_EVENTS_TRIGGERED_13, &NRF_EGU_regs[5].EVENTS_TRIGGERED[13]},
470 {EGU5_EVENTS_TRIGGERED_14, &NRF_EGU_regs[5].EVENTS_TRIGGERED[14]},
471 {EGU5_EVENTS_TRIGGERED_15, &NRF_EGU_regs[5].EVENTS_TRIGGERED[15]},
472
473 {TIMER3_EVENTS_COMPARE_0, &NRF_TIMER_regs[3].EVENTS_COMPARE[0]},
474 {TIMER3_EVENTS_COMPARE_1, &NRF_TIMER_regs[3].EVENTS_COMPARE[1]},
475 {TIMER3_EVENTS_COMPARE_2, &NRF_TIMER_regs[3].EVENTS_COMPARE[2]},
476 {TIMER3_EVENTS_COMPARE_3, &NRF_TIMER_regs[3].EVENTS_COMPARE[3]},
477 {TIMER3_EVENTS_COMPARE_4, &NRF_TIMER_regs[3].EVENTS_COMPARE[4]},
478 {TIMER3_EVENTS_COMPARE_5, &NRF_TIMER_regs[3].EVENTS_COMPARE[5]},
479
480 {TIMER4_EVENTS_COMPARE_0, &NRF_TIMER_regs[4].EVENTS_COMPARE[0]},
481 {TIMER4_EVENTS_COMPARE_1, &NRF_TIMER_regs[4].EVENTS_COMPARE[1]},
482 {TIMER4_EVENTS_COMPARE_2, &NRF_TIMER_regs[4].EVENTS_COMPARE[2]},
483 {TIMER4_EVENTS_COMPARE_3, &NRF_TIMER_regs[4].EVENTS_COMPARE[3]},
484 {TIMER4_EVENTS_COMPARE_4, &NRF_TIMER_regs[4].EVENTS_COMPARE[4]},
485 {TIMER4_EVENTS_COMPARE_5, &NRF_TIMER_regs[4].EVENTS_COMPARE[5]},
486
487 {RTC2_EVENTS_OVRFLW, &NRF_RTC_regs[2].EVENTS_OVRFLW},
488 {RTC2_EVENTS_COMPARE_0, &NRF_RTC_regs[2].EVENTS_COMPARE[0]},
489 {RTC2_EVENTS_COMPARE_1, &NRF_RTC_regs[2].EVENTS_COMPARE[1]},
490 {RTC2_EVENTS_COMPARE_2, &NRF_RTC_regs[2].EVENTS_COMPARE[2]},
491 {RTC2_EVENTS_COMPARE_3, &NRF_RTC_regs[2].EVENTS_COMPARE[3]},
492
493 {NUMBER_PPI_EVENTS, NULL} //End marker
494 };
495
496
set_fixed_channel_routes()497 static void set_fixed_channel_routes(){
498 //TODO: add handler function pointers as we add those functions while modelling the different parts
499
500 //Set the fixed channels configuration:
501 // 20 TIMER0->EVENTS_COMPARE[0] RADIO->TASKS_TXEN
502 ppi_evt_to_ch[TIMER0_EVENTS_COMPARE_0].channels_mask |= ( 1 << 20 );
503 ppi_ch_tasks[20].tep_f = nrf_radio_tasks_TXEN; //RADIO->TASKS_TXEN
504
505 // 21 TIMER0->EVENTS_COMPARE[0] RADIO->TASKS_RXEN
506 ppi_evt_to_ch[TIMER0_EVENTS_COMPARE_0].channels_mask |= ( 1 << 21 );
507 ppi_ch_tasks[21].tep_f = nrf_radio_tasks_RXEN; //RADIO->TASKS_RXEN
508
509 // 22 TIMER0->EVENTS_COMPARE[1] RADIO->TASKS_DISABLE
510 ppi_evt_to_ch[TIMER0_EVENTS_COMPARE_1].channels_mask |= ( 1 << 22 );
511 ppi_ch_tasks[22].tep_f = nrf_radio_tasks_DISABLE; //RADIO->TASKS_DISABLE
512
513 // 23 RADIO->EVENTS_BCMATCH AAR->TASKS_START
514 ppi_evt_to_ch[RADIO_EVENTS_BCMATCH].channels_mask |= ( 1 << 23 );
515 ppi_ch_tasks[23].tep_f = nrf_aar_TASK_START; //AAR->TASKS_START
516
517 // 24 RADIO->EVENTS_READY CCM->TASKS_KSGEN
518 ppi_evt_to_ch[RADIO_EVENTS_READY].channels_mask |= ( 1 << 24 );
519 ppi_ch_tasks[24].tep_f = nrf_ccm_TASK_KSGEN; //CCM->TASKS_KSGEN
520
521 // 25 RADIO->EVENTS_ADDRESS CCM->TASKS_CRYPT
522 ppi_evt_to_ch[RADIO_EVENTS_ADDRESS].channels_mask |= ( 1 << 25 );
523 ppi_ch_tasks[25].tep_f = nrf_ccm_TASK_CRYPT; //CCM->TASKS_CRYPT
524
525 // 26 RADIO->EVENTS_ADDRESS TIMER0->TASKS_CAPTURE[1]
526 ppi_evt_to_ch[RADIO_EVENTS_ADDRESS].channels_mask |= ( 1 << 26 );
527 ppi_ch_tasks[26].tep_f = nrf_timer0_TASK_CAPTURE_1; //TIMER0->TASKS_CAPTURE[1]
528
529 // 27 RADIO->EVENTS_END TIMER0->TASKS_CAPTURE[2]
530 ppi_evt_to_ch[RADIO_EVENTS_END].channels_mask |= ( 1 << 27 );
531 ppi_ch_tasks[27].tep_f = nrf_timer0_TASK_CAPTURE_2; //TIMER0->TASKS_CAPTURE[2]
532
533 // 28 RTC0->EVENTS_COMPARE[0] RADIO->TASKS_TXEN
534 ppi_evt_to_ch[RTC0_EVENTS_COMPARE_0].channels_mask |= ( 1 << 28 );
535 ppi_ch_tasks[28].tep_f = nrf_radio_tasks_TXEN; //RADIO->TASKS_TXEN
536
537 // 29 RTC0->EVENTS_COMPARE[0] RADIO->TASKS_RXEN
538 ppi_evt_to_ch[RTC0_EVENTS_COMPARE_0].channels_mask |= ( 1 << 29 );
539 ppi_ch_tasks[29].tep_f = nrf_radio_tasks_RXEN; //RADIO->TASKS_RXEN
540
541 // 30 RTC0->EVENTS_COMPARE[0] TIMER0->TASKS_CLEAR
542 ppi_evt_to_ch[RTC0_EVENTS_COMPARE_0].channels_mask |= ( 1 << 30 );
543 ppi_ch_tasks[30].tep_f = nrf_timer0_TASK_CLEAR; //TIMER0->TASKS_CLEAR
544
545 // 31 RTC0->EVENTS_COMPARE[0] TIMER0->TASKS_START
546 ppi_evt_to_ch[RTC0_EVENTS_COMPARE_0].channels_mask |= ( (uint32_t)1 << 31 );
547 ppi_ch_tasks[31].tep_f = nrf_timer0_TASK_START; //TIMER0->TASKS_START
548 }
549
550 /**
551 * Initialize the PPI model
552 */
nrf_ppi_init()553 void nrf_ppi_init(){
554 memset(&NRF_PPI_regs, 0, sizeof(NRF_PPI_regs));
555 memset(ppi_ch_tasks, 0, sizeof(ppi_ch_tasks));
556 memset(ppi_evt_to_ch, 0, sizeof(ppi_evt_to_ch));
557 set_fixed_channel_routes();
558 }
559
560 /**
561 * Cleanup the PPI model before exiting the program
562 */
nrf_ppi_clean_up()563 void nrf_ppi_clean_up(){
564
565 }
566
567 /**
568 * HW models call this function when they want to signal an event which
569 * may trigger a task
570 */
nrf_ppi_event(ppi_event_types_t event)571 void nrf_ppi_event(ppi_event_types_t event){
572
573 uint32_t ch_mask = ppi_evt_to_ch[event].channels_mask;
574 ch_mask &= NRF_PPI_regs.CHEN;
575
576 if ( ch_mask ){
577 for ( int ch_nbr = __builtin_ffs(ch_mask) - 1;
578 ( ch_mask != 0 ) && ( ch_nbr < NUMBER_PPI_CHANNELS ) ;
579 ch_nbr++ ) {
580 if ( ch_mask & ( 1 << ch_nbr ) ){
581 ch_mask &= ~( (uint64_t) 1 << ch_nbr );
582 if ( ppi_ch_tasks[ch_nbr].tep_f != NULL ){
583 ppi_ch_tasks[ch_nbr].tep_f();
584 }
585 if ( ppi_ch_tasks[ch_nbr].fork_tep_f != NULL ){
586 ppi_ch_tasks[ch_nbr].fork_tep_f();
587 }
588 } //if event is mapped to this channel
589 } //for channels
590 } //if this event is in any channel
591 }
592
593 /**
594 * Find the task in ppi_tasks_table whose address
595 * matches <TEP> and save the task handling function <in dest>
596 *
597 * Helper function for the TEP and FORK_TEP functions
598 */
find_task(void * TEP,dest_f_t * dest,int ch_nbr)599 static void find_task(void *TEP, dest_f_t *dest, int ch_nbr){
600 int tt = 0;
601 while ( ppi_tasks_table[tt].task_addr != NULL ){
602 if ( ppi_tasks_table[tt].task_addr == TEP ){
603 *dest = ppi_tasks_table[tt].dest;
604 return;
605 }
606 tt++;
607 }
608 bs_trace_warning_line_time(
609 "NRF_PPI: The task %p for chnbr %i does not match any modelled task in NRF_PPI.c => it will be ignored\n",
610 TEP, ch_nbr);
611
612 *dest = NULL;
613 }
614
615 /**
616 * Update PPI internal routing status after a
617 * CH[<ch_nbr>].EEP update
618 */
nrf_ppi_regw_sideeffects_EEP(int ch_nbr)619 void nrf_ppi_regw_sideeffects_EEP(int ch_nbr){
620 //To save execution time when an event is raised, we build the
621 //ppi_event_config_table & ppi_channel_config_table out of the registers
622
623 //first remove this channel from all events masks
624 for (int i = 0 ; i < NUMBER_PPI_EVENTS ; i++){
625 ppi_evt_to_ch[i].channels_mask &= ~( 1 << ch_nbr );
626 }
627
628 //then lets try to find which event (if any) is feeding this channel
629 if ( ( ch_nbr < 20 ) && ( (void*)NRF_PPI_regs.CH[ch_nbr].EEP != NULL ) ){
630 int i = 0;
631 while ( ppi_events_table[i].event_type != NUMBER_PPI_EVENTS ){
632 if ( ppi_events_table[i].event_addr == (void*)NRF_PPI_regs.CH[ch_nbr].EEP ) {
633 ppi_evt_to_ch[ppi_events_table[i].event_type].channels_mask |= ( 1 << ch_nbr );
634 return;
635 }
636 i++;
637 }
638 bs_trace_warning_line_time(
639 "NRF_PPI: The event NRF_PPI_regs.CH[%i].EEP(=%p) does not match any modelled event in NRF_PPI.c=> it will be ignored\n",
640 ch_nbr, NRF_PPI_regs.CH[ch_nbr].EEP);
641 }
642 }
643
644 /**
645 * Update PPI internal routing status after a
646 * CH[<ch_nbr>].TEP update
647 */
nrf_ppi_regw_sideeffects_TEP(int ch_nbr)648 void nrf_ppi_regw_sideeffects_TEP(int ch_nbr){
649 //To save execution time when an event is raised, we build the
650 //ppi_event_config_table & ppi_channel_config_table out of the registers
651 if ( ch_nbr < 20 ){
652 if ( (void*)NRF_PPI_regs.CH[ch_nbr].TEP != NULL ){
653 find_task((void*)NRF_PPI_regs.CH[ch_nbr].TEP,
654 &ppi_ch_tasks[ch_nbr].tep_f,
655 ch_nbr);
656 } else {
657 ppi_ch_tasks[ch_nbr].tep_f = NULL;
658 }
659 }
660 }
661 /**
662 * Update PPI internal routing status after a
663 * FORK[<ch_nbr>].TEP update
664 */
nrf_ppi_regw_sideeffects_FORK_TEP(int ch_nbr)665 void nrf_ppi_regw_sideeffects_FORK_TEP(int ch_nbr){
666 if ( (void*)NRF_PPI_regs.FORK[ch_nbr].TEP != NULL ){
667 find_task((void*)NRF_PPI_regs.FORK[ch_nbr].TEP,
668 &ppi_ch_tasks[ch_nbr].fork_tep_f,
669 ch_nbr);
670 } else {
671 ppi_ch_tasks[ch_nbr].fork_tep_f = NULL;
672 }
673 }
674
675 /**
676 * Update PPI CHEN mask after a write to CHENSET
677 * (writes to CHEN do not need sideeffects)
678 */
nrf_ppi_regw_sideeffects_CHENSET()679 void nrf_ppi_regw_sideeffects_CHENSET(){
680 if ( NRF_PPI_regs.CHENSET != 0 ){
681 NRF_PPI_regs.CHEN |= NRF_PPI_regs.CHENSET;
682 NRF_PPI_regs.CHENSET = 0;
683 }
684 }
685
686 /**
687 * Update PPI CHEN mask after a write to CHENCLR
688 * (writes to CHEN do not need sideeffects)
689 */
nrf_ppi_regw_sideeffects_CHENCLR()690 void nrf_ppi_regw_sideeffects_CHENCLR(){
691 if ( NRF_PPI_regs.CHENCLR != 0 ){
692 NRF_PPI_regs.CHEN &= ~NRF_PPI_regs.CHENCLR;
693 NRF_PPI_regs.CHENCLR = 0;
694 }
695 }
696
697 /**
698 * Update PPI CHEN mask after a write to CHENSET or CHENCLR
699 * (writes to CHEN do not need sideeffects)
700 */
nrf_ppi_regw_sideeffects_CHEN()701 void nrf_ppi_regw_sideeffects_CHEN(){
702 //Note that we do not let people read CHEN from the SET and CLR
703 //registers
704 nrf_ppi_regw_sideeffects_CHENSET();
705 nrf_ppi_regw_sideeffects_CHENCLR();
706 }
707
708 /**
709 * If you dont want to bother about individual calls,
710 * when any PPI register is written which changes the configuration of the PPI
711 * call this to update the routing table or cause other sideeffects
712 * This call will inspect all input registers
713 *
714 * (otherwise call the correspondent sideeffect function above for each register
715 * write)
716 */
nrf_ppi_regw_sideeffects()717 void nrf_ppi_regw_sideeffects(){
718
719 for (int ch_nbr = 0; ch_nbr < 32 ; ch_nbr++){
720 if ( ch_nbr < 20 ){
721 nrf_ppi_regw_sideeffects_EEP(ch_nbr);
722 nrf_ppi_regw_sideeffects_TEP(ch_nbr);
723 }
724 nrf_ppi_regw_sideeffects_FORK_TEP(ch_nbr);
725 }
726
727 nrf_ppi_regw_sideeffects_CHEN();
728 }
729
nrf_ppi_regw_sideeffects_TASKS_CHG_DIS(int i)730 void nrf_ppi_regw_sideeffects_TASKS_CHG_DIS(int i){
731 if ( NRF_PPI_regs.TASKS_CHG[i].DIS ) {
732 NRF_PPI_regs.TASKS_CHG[i].DIS = 0;
733 nrf_ppi_TASK_CHG_ENDIS( i, false );
734 }
735 }
736
nrf_ppi_regw_sideeffects_TASKS_CHG_EN(int i)737 void nrf_ppi_regw_sideeffects_TASKS_CHG_EN(int i){
738 if ( NRF_PPI_regs.TASKS_CHG[i].EN ) {
739 NRF_PPI_regs.TASKS_CHG[i].EN = 0;
740 nrf_ppi_TASK_CHG_ENDIS( i, true );
741 }
742 }
743
nrf_ppi_taskw_sideeffects()744 void nrf_ppi_taskw_sideeffects(){
745 int i;
746 for ( i = 0 ; i < 6 ; i++){
747 nrf_ppi_regw_sideeffects_TASKS_CHG_DIS(i);
748 }
749 for ( i = 0 ; i < 6 ; i++){
750 nrf_ppi_regw_sideeffects_TASKS_CHG_EN(i);
751 }
752 }
753