From e775e1452444bd2ff1b42ffa3f47137fc23f37cc Mon Sep 17 00:00:00 2001 From: Jakub Zymelka Date: Wed, 27 Nov 2024 09:41:27 +0100 Subject: [PATCH] applications: sdp: mspi: Add IPC solution to SDP MSPI application Add IPC solution based on icmsg to application for FLPR core to communicate with SDP MSPI driver. Signed-off-by: Jakub Zymelka --- .../nrf54l15dk_nrf54l15_cpuflpr.overlay | 52 ++++++ applications/sdp/mspi/prj.conf | 2 + applications/sdp/mspi/sample.yaml | 7 +- applications/sdp/mspi/src/hrt/hrt.c | 57 ++++--- applications/sdp/mspi/src/hrt/hrt.h | 7 - applications/sdp/mspi/src/main.c | 154 +++++++++++++++--- applications/sdp/mspi/sysbuild.conf | 2 +- 7 files changed, 221 insertions(+), 60 deletions(-) diff --git a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay index 4afa34f53f35..c3c8081a6be0 100644 --- a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay +++ b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay @@ -4,6 +4,58 @@ * 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"; }; diff --git a/applications/sdp/mspi/prj.conf b/applications/sdp/mspi/prj.conf index 79f89305ca0d..5db8be05d329 100644 --- a/applications/sdp/mspi/prj.conf +++ b/applications/sdp/mspi/prj.conf @@ -1 +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 index 5e17c3454469..a3c84c2d6056 100644 --- a/applications/sdp/mspi/sample.yaml +++ b/applications/sdp/mspi/sample.yaml @@ -5,11 +5,10 @@ common: integration_platforms: - nrf54l15dk/nrf54l15/cpuflpr tests: - applications.sdp.mspi.icmsg: + applications.sdp.mspi: build_only: true sysbuild: true platform_allow: nrf54l15dk/nrf54l15/cpuflpr tags: ci_build sysbuild mspi - extra_configs: - - CONFIG_IPC_SERVICE=y - - CONFIG_IPC_SERVICE_BACKEND_ICMSG=y + required_snippets: + - sdp-mspi diff --git a/applications/sdp/mspi/src/hrt/hrt.c b/applications/sdp/mspi/src/hrt/hrt.c index 0c06b725f30c..a987eea4ac12 100644 --- a/applications/sdp/mspi/src/hrt/hrt.c +++ b/applications/sdp/mspi/src/hrt/hrt.c @@ -6,8 +6,7 @@ #include "hrt.h" #include #include - -#define TOP 4 +#include void write_single_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t counter_top, uint8_t word_size, bool ce_enable_state, bool hold_ce) @@ -17,13 +16,15 @@ void write_single_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t co /* Configuration step */ uint16_t dir = nrf_vpr_csr_vio_dir_get(); - nrf_vpr_csr_vio_dir_set(dir | PIN_DIR_OUT_MASK(D0_PIN) | PIN_DIR_OUT_MASK(CS_PIN) | - PIN_DIR_OUT_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_dir_set(dir | PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); uint16_t out = nrf_vpr_csr_vio_out_get(); - nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(D0_PIN) | PIN_OUT_HIGH_MASK(CS_PIN) | - PIN_OUT_LOW_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER)) | + PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); nrf_vpr_csr_vio_mode_out_t out_mode = { .mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE, @@ -60,8 +61,9 @@ void write_single_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t co /* Enable CS */ out = nrf_vpr_csr_vio_out_get(); - out &= ~PIN_OUT_HIGH_MASK(CS_PIN); - out |= ce_enable_state ? PIN_OUT_HIGH_MASK(CS_PIN) : PIN_OUT_LOW_MASK(CS_PIN); + out &= ~PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); + out |= ce_enable_state ? PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) + : PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); nrf_vpr_csr_vio_out_set(out); /* Start counter */ @@ -83,9 +85,11 @@ void write_single_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t co /* Deselect slave */ if (!hold_ce) { out = nrf_vpr_csr_vio_out_get(); - out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); - out |= ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) : PIN_OUT_HIGH_MASK(CS_PIN); - out |= PIN_OUT_LOW_MASK(SCLK_PIN); + out &= ~(PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); + out |= ce_enable_state ? PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) + : PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); + out |= PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER)); nrf_vpr_csr_vio_out_set(out); } @@ -102,15 +106,21 @@ void write_quad_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t coun /* Configuration step */ uint16_t dir = nrf_vpr_csr_vio_dir_get(); - nrf_vpr_csr_vio_dir_set(dir | PIN_DIR_OUT_MASK(D0_PIN) | PIN_DIR_OUT_MASK(D1_PIN) | - PIN_DIR_OUT_MASK(D2_PIN) | PIN_DIR_OUT_MASK(D3_PIN) | - PIN_DIR_OUT_MASK(CS_PIN) | PIN_DIR_OUT_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_dir_set(dir | PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ1_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ2_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ3_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); uint16_t out = nrf_vpr_csr_vio_out_get(); - nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(D0_PIN) | PIN_OUT_LOW_MASK(D1_PIN) | - PIN_OUT_LOW_MASK(D2_PIN) | PIN_OUT_LOW_MASK(D3_PIN) | - PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_LOW_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER)) | + PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ1_PIN_NUMBER)) | + PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ2_PIN_NUMBER)) | + PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ3_PIN_NUMBER)) | + PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); nrf_vpr_csr_vio_mode_out_t out_mode = { .mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE, @@ -147,8 +157,9 @@ void write_quad_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t coun /* Enable CS */ out = nrf_vpr_csr_vio_out_get(); - out &= ~PIN_OUT_HIGH_MASK(CS_PIN); - out |= ce_enable_state ? PIN_OUT_HIGH_MASK(CS_PIN) : PIN_OUT_LOW_MASK(CS_PIN); + out &= ~PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); + out |= ce_enable_state ? PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) + : PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); nrf_vpr_csr_vio_out_set(out); /* Start counter */ @@ -170,9 +181,11 @@ void write_quad_by_word(volatile uint32_t *data, uint8_t data_len, uint32_t coun /* Deselect slave */ if (!hold_ce) { out = nrf_vpr_csr_vio_out_get(); - out &= ~(PIN_OUT_HIGH_MASK(CS_PIN) | PIN_OUT_HIGH_MASK(SCLK_PIN)); - out |= ce_enable_state ? PIN_OUT_LOW_MASK(CS_PIN) : PIN_OUT_HIGH_MASK(CS_PIN); - out |= PIN_OUT_LOW_MASK(SCLK_PIN); + out &= ~(PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) | + PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); + out |= ce_enable_state ? PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)) + : PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); + out |= PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER)); nrf_vpr_csr_vio_out_set(out); } diff --git a/applications/sdp/mspi/src/hrt/hrt.h b/applications/sdp/mspi/src/hrt/hrt.h index f8011aee23e4..baf20c99348d 100644 --- a/applications/sdp/mspi/src/hrt/hrt.h +++ b/applications/sdp/mspi/src/hrt/hrt.h @@ -10,13 +10,6 @@ #include #include -#define SCLK_PIN 0 -#define D0_PIN 1 -#define D1_PIN 2 -#define D2_PIN 3 -#define D3_PIN 4 -#define CS_PIN 5 - /* Max word size. */ #define MAX_WORD_SIZE NRF_VPR_CSR_VIO_SHIFT_CNT_OUT_BUFFERED_MAX diff --git a/applications/sdp/mspi/src/main.c b/applications/sdp/mspi/src/main.c index 45603fb7fe06..cb1f33be23c3 100644 --- a/applications/sdp/mspi/src/main.c +++ b/applications/sdp/mspi/src/main.c @@ -4,14 +4,17 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -#include "./hrt/hrt.h" +#include "hrt/hrt.h" -#include #include +#include +#include + #include #include #include +#include #include #define MAX_DATA_LEN 256 @@ -48,6 +51,85 @@ volatile uint32_t *data_to_send; volatile uint8_t data_len; volatile uint8_t ce_hold; +static struct ipc_ept ep; +static atomic_t ipc_atomic_sem = ATOMIC_INIT(0); + +void process_packet(const void *data, size_t len); + +static void ep_bound(void *priv) +{ + atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_EP_BOUNDED); +} + +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_PINS: { + nrfe_mspi_pinctrl_soc_pin_t *pins_cfg = (nrfe_mspi_pinctrl_soc_pin_t *)buffer; + + for (uint8_t i = 0; i < NRFE_MSPI_PINS_MAX; i++) { + uint32_t psel = NRF_GET_PIN(pins_cfg->pin[i]); + uint32_t fun = NRF_GET_FUN(pins_cfg->pin[i]); + NRF_GPIO_Type *reg = nrf_gpio_pin_port_decode(&psel); + /* TODO: Process pinctrl config data */ + } + break; + } + case NRFE_MSPI_CONFIG_CTRL: { + struct mspi_cfg *cfg = (struct mspi_cfg *)buffer; + /* TODO: Process controller config data */ + break; + } + case NRFE_MSPI_CONFIG_DEV: { + struct mspi_dev_cfg *cfg = (struct mspi_dev_cfg *)buffer; + /* TODO: Process device config data */ + break; + } + case NRFE_MSPI_CONFIG_XFER: { + struct mspi_xfer *cfg = (struct mspi_xfer *)buffer; + /* TODO: Process xfer config data */ + break; + } + case NRFE_MSPI_TX: + case NRFE_MSPI_TXRX: { + struct mspi_xfer_packet *packet = (struct mspi_xfer_packet *)buffer; + + if (packet->dir == MSPI_RX) { + /* TODO: Process received data */ + } else if (packet->dir == MSPI_TX) { + /* TODO: Send data */ + } + break; + } + default: + response.opcode = NRFE_MSPI_WRONG_OPCODE; + break; + } + + ipc_service_send(&ep, (const void *)&response.opcode, sizeof(response)); +} + void configure_clock(enum mspi_cpp_mode cpp_mode) { nrf_vpr_csr_vio_config_t vio_config = { @@ -55,27 +137,27 @@ void configure_clock(enum mspi_cpp_mode cpp_mode) .stop_cnt = 0, }; - nrf_vpr_csr_vio_dir_set(PIN_DIR_OUT_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_dir_set(PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); switch (cpp_mode) { case MSPI_CPP_MODE_0: { vio_config.clk_polarity = 0; - nrf_vpr_csr_vio_out_set(PIN_OUT_LOW_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); break; } case MSPI_CPP_MODE_1: { vio_config.clk_polarity = 1; - nrf_vpr_csr_vio_out_set(PIN_OUT_LOW_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); break; } case MSPI_CPP_MODE_2: { vio_config.clk_polarity = 1; - nrf_vpr_csr_vio_out_set(PIN_OUT_HIGH_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); break; } case MSPI_CPP_MODE_3: { vio_config.clk_polarity = 0; - nrf_vpr_csr_vio_out_set(PIN_OUT_HIGH_MASK(SCLK_PIN)); + nrf_vpr_csr_vio_out_set(PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); break; } } @@ -143,8 +225,47 @@ __attribute__((interrupt)) void hrt_handler_write_quad(void) ce_hold); } +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 + + 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 (!atomic_test_and_clear_bit(&ipc_atomic_sem, NRFE_MSPI_EP_BOUNDED)) { + } + + return 0; +} + int main(void) { + int ret = 0; + + ret = backend_init(); + if (ret < 0) { + return 0; + } + IRQ_DIRECT_CONNECT(HRT_VEVIF_IDX_WRITE_SINGLE, HRT_IRQ_PRIORITY, hrt_handler_write_single, 0); nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE_SINGLE), true); @@ -154,25 +275,6 @@ int main(void) nrf_vpr_csr_rtperiph_enable_set(true); - nrf_gpio_pin_dir_t dir = NRF_GPIO_PIN_DIR_OUTPUT; - nrf_gpio_pin_input_t input = NRF_GPIO_PIN_INPUT_DISCONNECT; - nrf_gpio_pin_pull_t pull = NRF_GPIO_PIN_NOPULL; - nrf_gpio_pin_drive_t drive = NRF_GPIO_PIN_E0E1; - - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, SCLK_PIN), &dir, &input, &pull, &drive, NULL); - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, D0_PIN), &dir, &input, &pull, &drive, NULL); - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, D1_PIN), &dir, &input, &pull, &drive, NULL); - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, D2_PIN), &dir, &input, &pull, &drive, NULL); - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, D3_PIN), &dir, &input, &pull, &drive, NULL); - nrfy_gpio_reconfigure(NRF_GPIO_PIN_MAP(2, CS_PIN), &dir, &input, &pull, &drive, NULL); - - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, SCLK_PIN), NRF_GPIO_PIN_SEL_VPR); - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, D0_PIN), NRF_GPIO_PIN_SEL_VPR); - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, D1_PIN), NRF_GPIO_PIN_SEL_VPR); - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, D2_PIN), NRF_GPIO_PIN_SEL_VPR); - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, D3_PIN), NRF_GPIO_PIN_SEL_VPR); - nrfy_gpio_pin_control_select(NRF_GPIO_PIN_MAP(2, CS_PIN), NRF_GPIO_PIN_SEL_VPR); - mspi_dev_configs.ce_polarity = MSPI_CE_ACTIVE_LOW; mspi_dev_configs.io_mode = MSPI_IO_MODE_SINGLE; mspi_dev_configs.cmd_length = 32; diff --git a/applications/sdp/mspi/sysbuild.conf b/applications/sdp/mspi/sysbuild.conf index ffa5894f2abd..69adb10f63b5 100644 --- a/applications/sdp/mspi/sysbuild.conf +++ b/applications/sdp/mspi/sysbuild.conf @@ -1,2 +1,2 @@ -# SB_CONFIG_VPR_LAUNCHER=n +SB_CONFIG_VPR_LAUNCHER=n SB_CONFIG_PARTITION_MANAGER=n