diff --git a/applications/sdp/mspi/CMakeLists.txt b/applications/sdp/mspi/CMakeLists.txt new file mode 100644 index 000000000000..b12e2765ad7a --- /dev/null +++ b/applications/sdp/mspi/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(sdp_mspi) + +#sdp_assembly_generate("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") +#sdp_assembly_check("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") +#sdp_assembly_prepare_install("${CMAKE_SOURCE_DIR}/src/hrt/hrt.c") + +target_sources(app PRIVATE src/main.c) +# target_sources(app PRIVATE src/hrt/hrt.s) + +#add_dependencies(app asm_check) diff --git a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf new file mode 100644 index 000000000000..6c1b7543e212 --- /dev/null +++ b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf @@ -0,0 +1,46 @@ +# Single-threaded +CONFIG_MULTITHREADING=n +CONFIG_KERNEL_MEM_POOL=n +CONFIG_LOG=n + +# Drivers and peripherals +CONFIG_I2C=n +CONFIG_WATCHDOG=n +CONFIG_GPIO=n +CONFIG_PINCTRL=n +CONFIG_SPI=n +CONFIG_SERIAL=n +CONFIG_FLASH=n + +# Power management +CONFIG_PM=n + +# Interrupts +CONFIG_DYNAMIC_INTERRUPTS=n +CONFIG_IRQ_OFFLOAD=n +CONFIG_GEN_SW_ISR_TABLE=n + +# Memory protection +CONFIG_THREAD_STACK_INFO=n +CONFIG_THREAD_CUSTOM_DATA=n +CONFIG_FPU=n + +# Boot +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n + +# Console +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_STDOUT_CONSOLE=n +CONFIG_PRINTK=n +CONFIG_EARLY_CONSOLE=n + +# Build +CONFIG_SIZE_OPTIMIZATIONS=y + +# No timer support in the kernel +CONFIG_SYS_CLOCK_EXISTS=n + +CONFIG_OUTPUT_DISASSEMBLY=y +CONFIG_COMMON_LIBC_MALLOC=n diff --git a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay new file mode 100644 index 000000000000..c3c8081a6be0 --- /dev/null +++ b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + soc { + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + sram_tx: memory@2003c000 { + reg = <0x2003c000 0x0800>; + }; + + sram_rx: memory@2003c800 { + reg = <0x2003c800 0x0800>; + }; + }; + }; + + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icmsg"; + tx-region = <&sram_tx>; + rx-region = <&sram_rx>; + mboxes = <&cpuflpr_vevif_rx 16>, <&cpuflpr_vevif_tx 20>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + }; +}; + +&cpuflpr_rram { + reg = <0x17a000 DT_SIZE_K(12)>; +}; + +&cpuflpr_code_partition { + reg = <0x0 DT_SIZE_K(12)>; +}; + +&cpuflpr_sram { + reg = <0x2003d000 DT_SIZE_K(12)>; + ranges = <0x0 0x2003d000 0x3000>; +}; + +&cpuflpr_vevif_rx { + status = "okay"; + interrupts = <16 NRF_DEFAULT_IRQ_PRIORITY>; + nordic,tasks = <1>; + nordic,tasks-mask = <0x00010000>; +}; + +&cpuflpr_vevif_tx { + status = "okay"; +}; + +&gpio0 { + status = "disabled"; +}; + +&gpio1 { + status = "disabled"; +}; + +&gpio2 { + status = "disabled"; +}; + +&gpiote20 { + status = "disabled"; +}; + +&gpiote30 { + status = "disabled"; +}; + +&grtc { + status = "disabled"; +}; + +&uart20 { + status = "disabled"; +}; + +&uart30 { + status = "disabled"; +}; + +&pwm20 { + status = "disabled"; +}; diff --git a/applications/sdp/mspi/prj.conf b/applications/sdp/mspi/prj.conf new file mode 100644 index 000000000000..5db8be05d329 --- /dev/null +++ b/applications/sdp/mspi/prj.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y +CONFIG_IPC_SERVICE_BACKEND_ICMSG=y diff --git a/applications/sdp/mspi/sample.yaml b/applications/sdp/mspi/sample.yaml new file mode 100644 index 000000000000..7110afc78c91 --- /dev/null +++ b/applications/sdp/mspi/sample.yaml @@ -0,0 +1,14 @@ +sample: + name: SDP GPIO application + description: SDP GPIO application +common: + integration_platforms: + - nrf54l15dk/nrf54l15/cpuflpr +tests: + applications.sdp.mspi: + build_only: true + sysbuild: true + platform_allow: nrf54l15dk/nrf54l15/cpuflpr + tags: ci_build sysbuild mspi + # required_snippets: + # - sdp-mspi diff --git a/applications/sdp/mspi/src/hrt/hrt.c b/applications/sdp/mspi/src/hrt/hrt.c new file mode 100644 index 000000000000..b7b2fc1339ce --- /dev/null +++ b/applications/sdp/mspi/src/hrt/hrt.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include "hrt.h" +#include + +extern volatile uint16_t irq_arg; + +void hrt_set_bits(void) +{ + 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 hrt_toggle_bits(void) +{ + nrf_vpr_csr_vio_out_toggle_set(irq_arg); +} diff --git a/applications/sdp/mspi/src/hrt/hrt.h b/applications/sdp/mspi/src/hrt/hrt.h new file mode 100644 index 000000000000..53b54822e042 --- /dev/null +++ b/applications/sdp/mspi/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/mspi/src/hrt/hrt.s b/applications/sdp/mspi/src/hrt/hrt.s new file mode 100644 index 000000000000..1279d5c6f479 --- /dev/null +++ b/applications/sdp/mspi/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/mspi/src/main.c b/applications/sdp/mspi/src/main.c new file mode 100644 index 000000000000..3b5f5a000ea3 --- /dev/null +++ b/applications/sdp/mspi/src/main.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "hrt/hrt.h" + +#include +#include +#include +#include +#include + +static struct ipc_ept ep; +static volatile uint32_t bound_sem; + +void process_packet(const void *data, size_t len); + +static void ep_bound(void *priv) +{ + bound_sem = 1; +} + +static void ep_recv(const void *data, size_t len, void *priv) +{ + (void)priv; + + process_packet(data, len); +} + +static struct ipc_ept_cfg ep_cfg = { + .cb = { + .bound = ep_bound, + .received = ep_recv, + }, +}; + +void process_packet(const void *data, size_t len) +{ + (void)len; + nrfe_mspi_flpr_response_t response; + uint8_t *buffer = (uint8_t *)data; + uint8_t opcode = *buffer++; + + response.opcode = opcode; + + switch (opcode) { + case NRFE_MSPI_CONFIG_CTRL: { + struct mspi_cfg cfg; + + memcpy(&cfg, buffer, sizeof(cfg)); + /* TODO: Process controller config data */ + break; + } + case NRFE_MSPI_CONFIG_DEV: { + struct mspi_dev_cfg cfg; + + memcpy(&cfg, buffer, sizeof(cfg)); + /* TODO: Process device config data */ + break; + } + case NRFE_MSPI_CONFIG_XFER: { + struct mspi_xfer cfg; + + memcpy(&cfg, buffer, sizeof(cfg)); + /* TODO: Process xfer config data */ + break; + } + case NRFE_MSPI_XFER: { + struct mspi_xfer_packet packet; + + memcpy(&packet, buffer, sizeof(packet)); + + if (packet.dir == MSPI_RX) { + response.opcode = NRFE_MSPI_RX; + /* TODO: Process received data */ + } else if (packet.dir == MSPI_TX) { + response.opcode = NRFE_MSPI_TX; + /* TODO: Send data */ + } + break; + } + default: + response.opcode = NRFE_MSPI_WRONG_OPCODE; + break; + } + + if (ipc_service_send(&ep, (const void *)&response.opcode, sizeof(response))) { + /* printf("IPC send error: %d\n", ret); */ + } +} + +static int backend_init(void) +{ + int ret = 0; + const struct device *ipc0_instance; + volatile uint32_t delay = 0; + +#if !defined(CONFIG_SYS_CLOCK_EXISTS) + /* Wait a little bit for IPC service to be ready on APP side */ + while (delay < 1000) { + delay++; + } +#endif + + bound_sem = 0; + ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0)); + + ret = ipc_service_open_instance(ipc0_instance); + if ((ret < 0) && (ret != -EALREADY)) { + return ret; + } + + ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg); + if (ret < 0) { + return ret; + } + + /* Wait for endpoint to be bound */ + while (bound_sem == 0) { + }; + bound_sem = 0; + + return 0; +} + +int main(void) +{ + int ret = 0; + + ret = backend_init(); + if (ret < 0) { + return 0; + } + + /* nrf_vpr_csr_rtperiph_enable_set(true); */ + + while (true) { + k_cpu_idle(); + } + + return 0; +} diff --git a/applications/sdp/mspi/sysbuild.conf b/applications/sdp/mspi/sysbuild.conf new file mode 100644 index 000000000000..69adb10f63b5 --- /dev/null +++ b/applications/sdp/mspi/sysbuild.conf @@ -0,0 +1,2 @@ +SB_CONFIG_VPR_LAUNCHER=n +SB_CONFIG_PARTITION_MANAGER=n