Skip to content
This repository was archived by the owner on Oct 23, 2025. It is now read-only.

Commit 09035df

Browse files
committed
dppi: Add NRF_DPPI.h, NRF_DPPI.c and nrf_dppi.c files
Add DPPI in order to be able to model the NRF53 HW. Signed-off-by: Sletnes Bjørlo, Aurora <[email protected]>
1 parent a47e326 commit 09035df

File tree

3 files changed

+403
-0
lines changed

3 files changed

+403
-0
lines changed

src/HW_models/NRF_DPPI.c

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/*
2+
* Copyright (c) 2020 Oticon A/S
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include "NRF_DPPI.h"
7+
#include <stdlib.h>
8+
#include "bs_tracing.h"
9+
#include <string.h>
10+
11+
/*
12+
* DPPI — Distributed programmable peripheral interconnect
13+
* https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fkeyfeatures_html5.html&cp=4_0_0
14+
*
15+
*/
16+
17+
NRF_DPPIC_Type NRF_DPPI_regs; ///< The DPPI registers
18+
19+
/**
20+
* DPPI module own TASKs handlers
21+
*/
22+
void nrf_dppi_TASK_CHG_ENDIS( int groupnbr, bool enable /*false=disable task*/ )
23+
{
24+
if ( enable )
25+
{
26+
bs_trace_raw_time(9, "dppi: Channel group %i enabled\n", groupnbr);
27+
NRF_DPPI_regs.CHEN |= NRF_DPPI_regs.CHG[groupnbr];
28+
} else
29+
{
30+
bs_trace_raw_time(9 ,"dppi: Channel group %i disable\n", groupnbr);
31+
NRF_DPPI_regs.CHEN &= ~NRF_DPPI_regs.CHG[groupnbr];
32+
}
33+
//Note of the author: From the spec I cannot guess if these tasks will affect
34+
//CHEN or a separate hidden register
35+
}
36+
37+
void nrf_dppi_TASK_CHG0_EN() { nrf_dppi_TASK_CHG_ENDIS(0,true); }
38+
void nrf_dppi_TASK_CHG1_EN() { nrf_dppi_TASK_CHG_ENDIS(1,true); }
39+
void nrf_dppi_TASK_CHG2_EN() { nrf_dppi_TASK_CHG_ENDIS(2,true); }
40+
void nrf_dppi_TASK_CHG3_EN() { nrf_dppi_TASK_CHG_ENDIS(3,true); }
41+
void nrf_dppi_TASK_CHG4_EN() { nrf_dppi_TASK_CHG_ENDIS(4,true); }
42+
void nrf_dppi_TASK_CHG5_EN() { nrf_dppi_TASK_CHG_ENDIS(5,true); }
43+
void nrf_dppi_TASK_CHG0_DIS(){ nrf_dppi_TASK_CHG_ENDIS(0,false); }
44+
void nrf_dppi_TASK_CHG1_DIS(){ nrf_dppi_TASK_CHG_ENDIS(1,false); }
45+
void nrf_dppi_TASK_CHG2_DIS(){ nrf_dppi_TASK_CHG_ENDIS(2,false); }
46+
void nrf_dppi_TASK_CHG3_DIS(){ nrf_dppi_TASK_CHG_ENDIS(3,false); }
47+
void nrf_dppi_TASK_CHG4_DIS(){ nrf_dppi_TASK_CHG_ENDIS(4,false); }
48+
void nrf_dppi_TASK_CHG5_DIS(){ nrf_dppi_TASK_CHG_ENDIS(5,false); }
49+
50+
/*Forward declaration*/
51+
struct subscr_list_elem;
52+
53+
//Element of linked list of subscribers
54+
typedef struct subscr_list_elem
55+
{
56+
dest_f_t task_function;
57+
struct subscr_list_elem * p_next;
58+
} subscr_list_elem_t;
59+
60+
//Table with TASKs subscribing to all channels
61+
static subscr_list_elem_t* dppi_subscriber_list[NUMBER_DPPI_CHANNELS];
62+
63+
//Function for checking if an element is in the subscriber linked list
64+
static bool subscriber_list_check(dest_f_t task_function, subscr_list_elem_t ** pp_head)
65+
{
66+
if (*pp_head == NULL)
67+
{
68+
return false;
69+
}
70+
71+
subscr_list_elem_t *p_last_elem = *pp_head;
72+
bool in_list = (p_last_elem->task_function == task_function);
73+
74+
while (p_last_elem->p_next != NULL)
75+
{
76+
if (p_last_elem->task_function == task_function)
77+
{
78+
in_list = true;
79+
}
80+
p_last_elem = p_last_elem->p_next;
81+
}
82+
83+
return in_list;
84+
}
85+
86+
//Function for appending an element to the subscriber linked list
87+
static void subscriber_list_append(subscr_list_elem_t ** pp_head, dest_f_t task_function)
88+
{
89+
if (!subscriber_list_check(task_function, pp_head))
90+
{
91+
struct subscr_list_elem* p_elem = (struct subscr_list_elem*) malloc(sizeof(struct subscr_list_elem));
92+
p_elem->task_function = task_function;
93+
p_elem->p_next = (*pp_head);
94+
*pp_head = p_elem;
95+
}
96+
}
97+
98+
//Function for removing an element from the subscriber linked list
99+
static void subscriber_list_remove(subscr_list_elem_t ** pp_head, dest_f_t task_function)
100+
{
101+
if(subscriber_list_check(task_function, pp_head))
102+
{
103+
struct subscr_list_elem* temp = (struct subscr_list_elem*) malloc(sizeof(struct subscr_list_elem));
104+
temp = *pp_head;
105+
subscr_list_elem_t *prev;
106+
107+
if (temp != NULL && temp->task_function == task_function)
108+
{
109+
*pp_head = temp->p_next;
110+
free(temp);
111+
return;
112+
}
113+
114+
while (temp != NULL && temp->task_function != task_function)
115+
{
116+
prev = temp;
117+
temp = temp->p_next;
118+
}
119+
120+
if (temp == NULL)
121+
{
122+
free(temp);
123+
return;
124+
}
125+
126+
prev->p_next = temp->p_next;
127+
free(temp);
128+
}
129+
}
130+
131+
/**
132+
* Update the subscriber list by adding the task to the specified channel
133+
*/
134+
void nrf_dppi_subscriber_add(uint8_t channel, dest_f_t function)
135+
{
136+
subscriber_list_append(&dppi_subscriber_list[channel], function);
137+
}
138+
139+
/**
140+
* Update the subscriber list by removing the task from all channels
141+
*/
142+
void nrf_dppi_subscriber_remove(dest_f_t function)
143+
{
144+
for(int i=0; i < NUMBER_DPPI_CHANNELS; i++)
145+
{
146+
subscriber_list_remove(&dppi_subscriber_list[i], function);
147+
}
148+
}
149+
150+
/**
151+
* Publish to a channel by triggering all tasks subscribing to the channel
152+
*/
153+
void nrf_dppi_publish(uint8_t channel)
154+
{
155+
struct subscr_list_elem* temp = (struct subscr_list_elem*) malloc(sizeof(struct subscr_list_elem));
156+
temp = dppi_subscriber_list[channel];
157+
subscr_list_elem_t *prev;
158+
159+
while (temp != NULL)
160+
{
161+
temp->task_function();
162+
prev = temp;
163+
temp = temp->p_next;
164+
}
165+
166+
free(temp);
167+
}
168+
169+
170+
/**
171+
* Initialize the DPPI model
172+
*/
173+
void nrf_dppi_init()
174+
{
175+
memset(&NRF_DPPI_regs, 0, sizeof(NRF_DPPI_regs));
176+
memset(dppi_subscriber_list, 0, sizeof(dppi_subscriber_list));
177+
}
178+
179+
/**
180+
* Cleanup the DPPI model before exiting the program
181+
*/
182+
void nrf_dppi_clean_up()
183+
{
184+
for(int i=0; i < NUMBER_DPPI_CHANNELS; i++)
185+
{
186+
struct subscr_list_elem* current = dppi_subscriber_list[i];
187+
struct subscr_list_elem* next;
188+
189+
while (current != NULL)
190+
{
191+
next = current->p_next;
192+
free(current);
193+
current = next;
194+
}
195+
dppi_subscriber_list[i] = NULL;
196+
}
197+
}
198+
199+
200+
/**
201+
* Update DPPI CHEN mask after a write to CHENSET
202+
* (writes to CHEN do not need sideeffects)
203+
*/
204+
void nrf_dppi_regw_sideeffects_CHENSET()
205+
{
206+
if ( NRF_DPPI_regs.CHENSET != 0 )
207+
{
208+
NRF_DPPI_regs.CHEN |= NRF_DPPI_regs.CHENSET;
209+
NRF_DPPI_regs.CHENSET = 0;
210+
}
211+
}
212+
213+
/**
214+
* Update DPPI CHEN mask after a write to CHENCLR
215+
* (writes to CHEN do not need sideeffects)
216+
*/
217+
void nrf_dppi_regw_sideeffects_CHENCLR()
218+
{
219+
if ( NRF_DPPI_regs.CHENCLR != 0 )
220+
{
221+
NRF_DPPI_regs.CHEN &= ~NRF_DPPI_regs.CHENCLR;
222+
NRF_DPPI_regs.CHENCLR = 0;
223+
}
224+
}

src/HW_models/NRF_DPPI.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2020 Oticon A/S
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#ifndef _NRF_HW_MODEL_DPPI_H
7+
#define _NRF_HW_MODEL_DPPI_H
8+
9+
#include "nrfx.h"
10+
11+
#ifdef __cplusplus
12+
extern "C"{
13+
#endif
14+
15+
extern NRF_DPPIC_Type NRF_DPPI_regs;
16+
#define NUMBER_DPPI_CHANNELS 32
17+
18+
typedef void (*dest_f_t)(void); //typedef for function pointer
19+
20+
void nrf_dppi_subscriber_add(uint8_t channel, dest_f_t function);
21+
void nrf_dppi_subscriber_remove(dest_f_t function);
22+
void nrf_dppi_publish(uint8_t channel);
23+
24+
void nrf_dppi_init();
25+
void nrf_dppi_clean_up();
26+
27+
void nrf_dppi_TASK_CHG0_EN();
28+
void nrf_dppi_TASK_CHG1_EN();
29+
void nrf_dppi_TASK_CHG2_EN();
30+
void nrf_dppi_TASK_CHG3_EN();
31+
void nrf_dppi_TASK_CHG4_EN();
32+
void nrf_dppi_TASK_CHG5_EN();
33+
void nrf_dppi_TASK_CHG0_DIS();
34+
void nrf_dppi_TASK_CHG1_DIS();
35+
void nrf_dppi_TASK_CHG2_DIS();
36+
void nrf_dppi_TASK_CHG3_DIS();
37+
void nrf_dppi_TASK_CHG4_DIS();
38+
void nrf_dppi_TASK_CHG5_DIS();
39+
40+
void nrf_dppi_regw_sideeffects_CHENSET();
41+
void nrf_dppi_regw_sideeffects_CHENCLR();
42+
43+
#ifdef __cplusplus
44+
}
45+
#endif
46+
47+
#endif

0 commit comments

Comments
 (0)