Skip to content

Commit 4b32dad

Browse files
masz-nordiccarlescufi
authored andcommitted
applications: sdp: gpio: add Hard RealTime IRQ code
Move code that is timing critical to `hrt.c`. That source code is used to generate `hrt.s`, which is versioned explicitly to detect changes in generated assembly. JIRA: NRFX-6357 Signed-off-by: Marcin Szymczyk <[email protected]>
1 parent b2fbe42 commit 4b32dad

File tree

5 files changed

+131
-34
lines changed

5 files changed

+131
-34
lines changed

applications/sdp/gpio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ project(emulated_gpio)
1212
sdp_assembly_generate("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c")
1313

1414
target_sources(app PRIVATE src/main.c)
15+
target_sources(app PRIVATE src/hrt/hrt.s)
1516
target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG app PRIVATE src/backend/backend_icmsg.c)
1617
target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICBMSG app PRIVATE src/backend/backend_icmsg.c)
1718
target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX app PRIVATE src/backend/backend_mbox.c)

applications/sdp/gpio/src/hrt/hrt.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,26 @@
33
*
44
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55
*/
6-
6+
#include "hrt.h"
77
#include <hal/nrf_vpr_csr_vio.h>
88

9-
void set_direction(void)
9+
extern volatile uint16_t irq_arg;
10+
11+
void hrt_set_bits(void)
1012
{
11-
nrf_vpr_csr_vio_dir_set(0xA);
12-
nrf_vpr_csr_vio_dir_set(0xB);
13-
nrf_vpr_csr_vio_dir_set(0xC);
13+
uint16_t outs = nrf_vpr_csr_vio_out_get();
14+
15+
nrf_vpr_csr_vio_out_set(outs | irq_arg);
16+
}
17+
18+
void hrt_clear_bits(void)
19+
{
20+
uint16_t outs = nrf_vpr_csr_vio_out_get();
21+
22+
nrf_vpr_csr_vio_out_set(outs & ~irq_arg);
1423
}
1524

16-
void set_output(void)
25+
void hrt_toggle_bits(void)
1726
{
18-
nrf_vpr_csr_vio_out_set(0xA);
19-
nrf_vpr_csr_vio_dir_set(0xB);
20-
nrf_vpr_csr_vio_dir_set(0xC);
27+
nrf_vpr_csr_vio_out_toggle_set(irq_arg);
2128
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef _HRT_H__
8+
#define _HRT_H__
9+
10+
void hrt_set_bits(void);
11+
12+
void hrt_clear_bits(void);
13+
14+
void hrt_toggle_bits(void);
15+
16+
#endif /* _HRT_H__ */
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.file "hrt.c"
2+
.option nopic
3+
.attribute arch, "rv32e1p9_m2p0_c2p0_zicsr2p0"
4+
.attribute unaligned_access, 0
5+
.attribute stack_align, 4
6+
.text
7+
.section .text.hrt_set_bits,"ax",@progbits
8+
.align 1
9+
.globl hrt_set_bits
10+
.type hrt_set_bits, @function
11+
hrt_set_bits:
12+
#APP
13+
csrr a4, 3008
14+
#NO_APP
15+
lui a5,%hi(irq_arg)
16+
lhu a5,%lo(irq_arg)(a5)
17+
or a5,a5,a4
18+
slli a5,a5,16
19+
srli a5,a5,16
20+
#APP
21+
csrw 3008, a5
22+
#NO_APP
23+
ret
24+
.size hrt_set_bits, .-hrt_set_bits
25+
.section .text.hrt_clear_bits,"ax",@progbits
26+
.align 1
27+
.globl hrt_clear_bits
28+
.type hrt_clear_bits, @function
29+
hrt_clear_bits:
30+
#APP
31+
csrr a4, 3008
32+
#NO_APP
33+
lui a5,%hi(irq_arg)
34+
lhu a5,%lo(irq_arg)(a5)
35+
not a5,a5
36+
and a5,a5,a4
37+
slli a5,a5,16
38+
srli a5,a5,16
39+
#APP
40+
csrw 3008, a5
41+
#NO_APP
42+
ret
43+
.size hrt_clear_bits, .-hrt_clear_bits
44+
.section .text.hrt_toggle_bits,"ax",@progbits
45+
.align 1
46+
.globl hrt_toggle_bits
47+
.type hrt_toggle_bits, @function
48+
hrt_toggle_bits:
49+
lui a5,%hi(irq_arg)
50+
lhu a5,%lo(irq_arg)(a5)
51+
#APP
52+
csrw 3024, a5
53+
#NO_APP
54+
ret
55+
.size hrt_toggle_bits, .-hrt_toggle_bits

applications/sdp/gpio/src/main.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66

77
#include "./backend/backend.h"
8+
#include "./hrt/hrt.h"
9+
810
#include <zephyr/kernel.h>
911
#include <zephyr/drivers/gpio.h>
1012
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
@@ -13,6 +15,16 @@
1315
#include <hal/nrf_vpr_csr_vio.h>
1416
#include <haly/nrfy_gpio.h>
1517

18+
#define HRT_IRQ_PRIORITY 2
19+
#define HRT_VEVIF_IDX_GPIO_CLEAR 17
20+
#define HRT_VEVIF_IDX_GPIO_SET 18
21+
#define HRT_VEVIF_IDX_GPIO_TOGGLE 19
22+
23+
#define VEVIF_IRQN(vevif) VEVIF_IRQN_1(vevif)
24+
#define VEVIF_IRQN_1(vevif) VPRCLIC_##vevif##_IRQn
25+
26+
volatile uint16_t irq_arg;
27+
1628
static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
1729
{
1830
if (flags & GPIO_PULL_UP) {
@@ -93,25 +105,6 @@ static int gpio_nrfe_pin_configure(uint8_t port, uint16_t pin, uint32_t flags)
93105
return 0;
94106
}
95107

96-
static void gpio_nrfe_port_set_bits_raw(uint16_t set_mask)
97-
{
98-
uint16_t outs = nrf_vpr_csr_vio_out_get();
99-
100-
nrf_vpr_csr_vio_out_set(outs | set_mask);
101-
}
102-
103-
static void gpio_nrfe_port_clear_bits_raw(uint16_t clear_mask)
104-
{
105-
uint16_t outs = nrf_vpr_csr_vio_out_get();
106-
107-
nrf_vpr_csr_vio_out_set(outs & ~clear_mask);
108-
}
109-
110-
static void gpio_nrfe_port_toggle_bits(uint16_t toggle_mask)
111-
{
112-
nrf_vpr_csr_vio_out_toggle_set(toggle_mask);
113-
}
114-
115108
void process_packet(nrfe_gpio_data_packet_t *packet)
116109
{
117110
if (packet->port != 2) {
@@ -124,15 +117,18 @@ void process_packet(nrfe_gpio_data_packet_t *packet)
124117
break;
125118
}
126119
case NRFE_GPIO_PIN_CLEAR: {
127-
gpio_nrfe_port_clear_bits_raw(packet->pin);
120+
irq_arg = packet->pin;
121+
nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_CLEAR));
128122
break;
129123
}
130124
case NRFE_GPIO_PIN_SET: {
131-
gpio_nrfe_port_set_bits_raw(packet->pin);
125+
irq_arg = packet->pin;
126+
nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_SET));
132127
break;
133128
}
134129
case NRFE_GPIO_PIN_TOGGLE: {
135-
gpio_nrfe_port_toggle_bits(packet->pin);
130+
irq_arg = packet->pin;
131+
nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_TOGGLE));
136132
break;
137133
}
138134
default: {
@@ -141,6 +137,26 @@ void process_packet(nrfe_gpio_data_packet_t *packet)
141137
}
142138
}
143139

140+
#define HRT_CONNECT(vevif, handler) \
141+
IRQ_DIRECT_CONNECT(vevif, HRT_IRQ_PRIORITY, handler, 0); \
142+
nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, VEVIF_IRQN(vevif), true)
143+
144+
145+
__attribute__ ((interrupt)) void hrt_handler_clear_bits(void)
146+
{
147+
hrt_clear_bits();
148+
}
149+
150+
__attribute__ ((interrupt)) void hrt_handler_set_bits(void)
151+
{
152+
hrt_set_bits();
153+
}
154+
155+
__attribute__ ((interrupt)) void hrt_handler_toggle_bits(void)
156+
{
157+
hrt_toggle_bits();
158+
}
159+
144160
int main(void)
145161
{
146162
int ret = 0;
@@ -150,9 +166,11 @@ int main(void)
150166
return 0;
151167
}
152168

153-
if (!nrf_vpr_csr_rtperiph_enable_check()) {
154-
nrf_vpr_csr_rtperiph_enable_set(true);
155-
}
169+
HRT_CONNECT(HRT_VEVIF_IDX_GPIO_CLEAR, hrt_handler_clear_bits);
170+
HRT_CONNECT(HRT_VEVIF_IDX_GPIO_SET, hrt_handler_set_bits);
171+
HRT_CONNECT(HRT_VEVIF_IDX_GPIO_TOGGLE, hrt_handler_toggle_bits);
172+
173+
nrf_vpr_csr_rtperiph_enable_set(true);
156174

157175
while (true) {
158176
k_cpu_idle();

0 commit comments

Comments
 (0)