diff --git a/applications/sdp/gpio/CMakeLists.txt b/applications/sdp/gpio/CMakeLists.txt index ebe612ff77c3..ae182d38491a 100644 --- a/applications/sdp/gpio/CMakeLists.txt +++ b/applications/sdp/gpio/CMakeLists.txt @@ -12,6 +12,7 @@ project(emulated_gpio) sdp_assembly_generate("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") target_sources(app PRIVATE src/main.c) +target_sources(app PRIVATE src/hrt/hrt.s) target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICMSG app PRIVATE src/backend/backend_icmsg.c) target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_ICBMSG app PRIVATE src/backend/backend_icmsg.c) target_sources_ifdef(CONFIG_GPIO_NRFE_EGPIO_BACKEND_MBOX app PRIVATE src/backend/backend_mbox.c) diff --git a/applications/sdp/gpio/src/hrt/hrt.c b/applications/sdp/gpio/src/hrt/hrt.c index 7670a38d04e6..b7b2fc1339ce 100644 --- a/applications/sdp/gpio/src/hrt/hrt.c +++ b/applications/sdp/gpio/src/hrt/hrt.c @@ -3,19 +3,26 @@ * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ - +#include "hrt.h" #include -void set_direction(void) +extern volatile uint16_t irq_arg; + +void hrt_set_bits(void) { - nrf_vpr_csr_vio_dir_set(0xA); - nrf_vpr_csr_vio_dir_set(0xB); - nrf_vpr_csr_vio_dir_set(0xC); + uint16_t outs = nrf_vpr_csr_vio_out_get(); + + nrf_vpr_csr_vio_out_set(outs | irq_arg); +} + +void hrt_clear_bits(void) +{ + uint16_t outs = nrf_vpr_csr_vio_out_get(); + + nrf_vpr_csr_vio_out_set(outs & ~irq_arg); } -void set_output(void) +void hrt_toggle_bits(void) { - nrf_vpr_csr_vio_out_set(0xA); - nrf_vpr_csr_vio_dir_set(0xB); - nrf_vpr_csr_vio_dir_set(0xC); + nrf_vpr_csr_vio_out_toggle_set(irq_arg); } diff --git a/applications/sdp/gpio/src/hrt/hrt.h b/applications/sdp/gpio/src/hrt/hrt.h new file mode 100644 index 000000000000..53b54822e042 --- /dev/null +++ b/applications/sdp/gpio/src/hrt/hrt.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef _HRT_H__ +#define _HRT_H__ + +void hrt_set_bits(void); + +void hrt_clear_bits(void); + +void hrt_toggle_bits(void); + +#endif /* _HRT_H__ */ diff --git a/applications/sdp/gpio/src/hrt/hrt.s b/applications/sdp/gpio/src/hrt/hrt.s new file mode 100644 index 000000000000..1279d5c6f479 --- /dev/null +++ b/applications/sdp/gpio/src/hrt/hrt.s @@ -0,0 +1,55 @@ + .file "hrt.c" + .option nopic + .attribute arch, "rv32e1p9_m2p0_c2p0_zicsr2p0" + .attribute unaligned_access, 0 + .attribute stack_align, 4 + .text + .section .text.hrt_set_bits,"ax",@progbits + .align 1 + .globl hrt_set_bits + .type hrt_set_bits, @function +hrt_set_bits: + #APP + csrr a4, 3008 + #NO_APP + lui a5,%hi(irq_arg) + lhu a5,%lo(irq_arg)(a5) + or a5,a5,a4 + slli a5,a5,16 + srli a5,a5,16 + #APP + csrw 3008, a5 + #NO_APP + ret + .size hrt_set_bits, .-hrt_set_bits + .section .text.hrt_clear_bits,"ax",@progbits + .align 1 + .globl hrt_clear_bits + .type hrt_clear_bits, @function +hrt_clear_bits: + #APP + csrr a4, 3008 + #NO_APP + lui a5,%hi(irq_arg) + lhu a5,%lo(irq_arg)(a5) + not a5,a5 + and a5,a5,a4 + slli a5,a5,16 + srli a5,a5,16 + #APP + csrw 3008, a5 + #NO_APP + ret + .size hrt_clear_bits, .-hrt_clear_bits + .section .text.hrt_toggle_bits,"ax",@progbits + .align 1 + .globl hrt_toggle_bits + .type hrt_toggle_bits, @function +hrt_toggle_bits: + lui a5,%hi(irq_arg) + lhu a5,%lo(irq_arg)(a5) + #APP + csrw 3024, a5 + #NO_APP + ret + .size hrt_toggle_bits, .-hrt_toggle_bits diff --git a/applications/sdp/gpio/src/main.c b/applications/sdp/gpio/src/main.c index 8fdf18083961..5afad4675610 100644 --- a/applications/sdp/gpio/src/main.c +++ b/applications/sdp/gpio/src/main.c @@ -5,6 +5,8 @@ */ #include "./backend/backend.h" +#include "./hrt/hrt.h" + #include #include #include @@ -13,6 +15,16 @@ #include #include +#define HRT_IRQ_PRIORITY 2 +#define HRT_VEVIF_IDX_GPIO_CLEAR 17 +#define HRT_VEVIF_IDX_GPIO_SET 18 +#define HRT_VEVIF_IDX_GPIO_TOGGLE 19 + +#define VEVIF_IRQN(vevif) VEVIF_IRQN_1(vevif) +#define VEVIF_IRQN_1(vevif) VPRCLIC_##vevif##_IRQn + +volatile uint16_t irq_arg; + static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) { if (flags & GPIO_PULL_UP) { @@ -93,25 +105,6 @@ static int gpio_nrfe_pin_configure(uint8_t port, uint16_t pin, uint32_t flags) return 0; } -static void gpio_nrfe_port_set_bits_raw(uint16_t set_mask) -{ - uint16_t outs = nrf_vpr_csr_vio_out_get(); - - nrf_vpr_csr_vio_out_set(outs | set_mask); -} - -static void gpio_nrfe_port_clear_bits_raw(uint16_t clear_mask) -{ - uint16_t outs = nrf_vpr_csr_vio_out_get(); - - nrf_vpr_csr_vio_out_set(outs & ~clear_mask); -} - -static void gpio_nrfe_port_toggle_bits(uint16_t toggle_mask) -{ - nrf_vpr_csr_vio_out_toggle_set(toggle_mask); -} - void process_packet(nrfe_gpio_data_packet_t *packet) { if (packet->port != 2) { @@ -124,15 +117,18 @@ void process_packet(nrfe_gpio_data_packet_t *packet) break; } case NRFE_GPIO_PIN_CLEAR: { - gpio_nrfe_port_clear_bits_raw(packet->pin); + irq_arg = packet->pin; + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_CLEAR)); break; } case NRFE_GPIO_PIN_SET: { - gpio_nrfe_port_set_bits_raw(packet->pin); + irq_arg = packet->pin; + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_SET)); break; } case NRFE_GPIO_PIN_TOGGLE: { - gpio_nrfe_port_toggle_bits(packet->pin); + irq_arg = packet->pin; + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_GPIO_TOGGLE)); break; } default: { @@ -141,6 +137,26 @@ void process_packet(nrfe_gpio_data_packet_t *packet) } } +#define HRT_CONNECT(vevif, handler) \ + IRQ_DIRECT_CONNECT(vevif, HRT_IRQ_PRIORITY, handler, 0); \ + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, VEVIF_IRQN(vevif), true) + + +__attribute__ ((interrupt)) void hrt_handler_clear_bits(void) +{ + hrt_clear_bits(); +} + +__attribute__ ((interrupt)) void hrt_handler_set_bits(void) +{ + hrt_set_bits(); +} + +__attribute__ ((interrupt)) void hrt_handler_toggle_bits(void) +{ + hrt_toggle_bits(); +} + int main(void) { int ret = 0; @@ -150,9 +166,11 @@ int main(void) return 0; } - if (!nrf_vpr_csr_rtperiph_enable_check()) { - nrf_vpr_csr_rtperiph_enable_set(true); - } + HRT_CONNECT(HRT_VEVIF_IDX_GPIO_CLEAR, hrt_handler_clear_bits); + HRT_CONNECT(HRT_VEVIF_IDX_GPIO_SET, hrt_handler_set_bits); + HRT_CONNECT(HRT_VEVIF_IDX_GPIO_TOGGLE, hrt_handler_toggle_bits); + + nrf_vpr_csr_rtperiph_enable_set(true); while (true) { k_cpu_idle();