From 269fed3fba329fcff1d221217db6a7f30dd01e1b Mon Sep 17 00:00:00 2001 From: Jakub Zymelka Date: Fri, 13 Dec 2024 16:21:32 +0100 Subject: [PATCH] applications: sdp: mspi: Add RX path to SDP MSPI Add RX path to SDP MSPI FLPR app implementation Signed-off-by: Jakub Zymelka --- applications/sdp/mspi/CMakeLists.txt | 8 +- .../boards/nrf54l15dk_nrf54l15_cpuflpr.conf | 21 +- .../nrf54l15dk_nrf54l15_cpuflpr.overlay | 18 +- applications/sdp/mspi/src/hrt/hrt.c | 279 ++++++++++++++++++ applications/sdp/mspi/src/hrt/hrt.h | 10 +- applications/sdp/mspi/src/hrt/hrt.s | 147 +++++++++ applications/sdp/mspi/src/main.c | 111 +++++-- drivers/mspi/mspi_nrfe.c | 25 +- include/drivers/mspi/nrfe_mspi.h | 2 +- snippets/sdp/mspi/app.conf | 8 + snippets/sdp/mspi/soc/nrf54l15_cpuapp.overlay | 51 +++- 11 files changed, 614 insertions(+), 66 deletions(-) diff --git a/applications/sdp/mspi/CMakeLists.txt b/applications/sdp/mspi/CMakeLists.txt index 3bf82cf56770..91d87f09f869 100644 --- a/applications/sdp/mspi/CMakeLists.txt +++ b/applications/sdp/mspi/CMakeLists.txt @@ -9,11 +9,11 @@ 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") +#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.c) -add_dependencies(app asm_check) +#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 index 4a8a0c4d05c6..3a8b91d83e57 100644 --- a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf +++ b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.conf @@ -7,9 +7,9 @@ CONFIG_LOG=n CONFIG_I2C=n CONFIG_WATCHDOG=n CONFIG_GPIO=n -CONFIG_PINCTRL=n +CONFIG_PINCTRL=y CONFIG_SPI=n -CONFIG_SERIAL=n +CONFIG_SERIAL=y CONFIG_FLASH=n # Power management @@ -18,7 +18,7 @@ CONFIG_PM=n # Interrupts CONFIG_DYNAMIC_INTERRUPTS=n CONFIG_IRQ_OFFLOAD=n -CONFIG_GEN_SW_ISR_TABLE=n +CONFIG_GEN_SW_ISR_TABLE=y # Memory protection CONFIG_THREAD_STACK_INFO=n @@ -26,15 +26,15 @@ CONFIG_THREAD_CUSTOM_DATA=n CONFIG_FPU=n # Boot -CONFIG_BOOT_BANNER=n +CONFIG_BOOT_BANNER=y CONFIG_NCS_BOOT_BANNER=n # Console -CONFIG_CONSOLE=n -CONFIG_UART_CONSOLE=n -CONFIG_STDOUT_CONSOLE=n -CONFIG_PRINTK=n -CONFIG_EARLY_CONSOLE=n +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_STDOUT_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_EARLY_CONSOLE=y # Build CONFIG_SIZE_OPTIMIZATIONS=y @@ -45,4 +45,5 @@ CONFIG_SYS_CLOCK_EXISTS=n CONFIG_OUTPUT_DISASSEMBLY=y CONFIG_COMMON_LIBC_MALLOC=n -CONFIG_COMPILER_OPT="-fshort-enums" \ No newline at end of file +# additional compiler flags +CONFIG_COMPILER_OPT="-fshort-enums" diff --git a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay index c3c8081a6be0..2602dafa878f 100644 --- a/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay +++ b/applications/sdp/mspi/boards/nrf54l15dk_nrf54l15_cpuflpr.overlay @@ -10,12 +10,12 @@ #address-cells = <1>; #size-cells = <1>; - sram_tx: memory@2003c000 { - reg = <0x2003c000 0x0800>; + sram_tx: memory@2003a000 { + reg = <0x2003a000 0x0800>; }; - sram_rx: memory@2003c800 { - reg = <0x2003c800 0x0800>; + sram_rx: memory@2003a800 { + reg = <0x2003a800 0x0800>; }; }; }; @@ -33,16 +33,16 @@ }; &cpuflpr_rram { - reg = <0x17a000 DT_SIZE_K(12)>; + reg = <0x178000 DT_SIZE_K(20)>; }; &cpuflpr_code_partition { - reg = <0x0 DT_SIZE_K(12)>; + reg = <0x0 DT_SIZE_K(20)>; }; &cpuflpr_sram { - reg = <0x2003d000 DT_SIZE_K(12)>; - ranges = <0x0 0x2003d000 0x3000>; + reg = <0x2003b000 DT_SIZE_K(20)>; + ranges = <0x0 0x2003b000 0x5000>; }; &cpuflpr_vevif_rx { @@ -85,7 +85,7 @@ }; &uart30 { - status = "disabled"; + status = "okay"; }; &pwm20 { diff --git a/applications/sdp/mspi/src/hrt/hrt.c b/applications/sdp/mspi/src/hrt/hrt.c index f2cd22ac5efe..6fc1bbafc789 100644 --- a/applications/sdp/mspi/src/hrt/hrt.c +++ b/applications/sdp/mspi/src/hrt/hrt.c @@ -8,6 +8,7 @@ #include #include #include +#include void hrt_write(volatile struct hrt_ll_xfer xfer_ll_params) { @@ -105,3 +106,281 @@ void hrt_write(volatile struct hrt_ll_xfer xfer_ll_params) /* Stop counter */ nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); } + +void hrt_read(volatile struct hrt_ll_xfer xfer_ll_params) +{ +// uint16_t dir; +// uint16_t out; +// nrf_vpr_csr_vio_config_t config; +// nrf_vpr_csr_vio_mode_out_t out_mode = { +// .mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE, +// .frame_width = 1, +// }; + +// NRFX_ASSERT(xfer_ll_params.word_size <= MAX_WORD_SIZE); + +// volatile uint32_t cnt1_val = (2 * xfer_ll_params.counter_top + 1); + +// /* Configuration step */ +// dir = nrf_vpr_csr_vio_dir_get(); +// nrf_vpr_csr_vio_dir_set(dir | PIN_DIR_OUT_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER))); + +// out = nrf_vpr_csr_vio_out_get(); +// nrf_vpr_csr_vio_out_set(out | PIN_OUT_LOW_MASK(VIO(NRFE_MSPI_DQ0_PIN_NUMBER))); + +// nrf_vpr_csr_vio_mode_out_set(&out_mode); +// nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_SHIFT); + +// nrf_vpr_csr_vio_config_get(&config); +// config.input_sel = true; /* set up D0 as output, sample on D1 as input */ +// nrf_vpr_csr_vio_config_set(&config); + +// /* Counter settings */ +// nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_RELOAD); +// nrf_vpr_csr_vtim_count_mode_set(1, NRF_VPR_CSR_VTIM_COUNT_RELOAD); + +// /* CNT0 should count every clock cycle for 96MHz, CNT1 every other clock cycle to capture +// * the data) */ +// nrf_vpr_csr_vtim_simple_counter_top_set(0, 3 * xfer_ll_params.counter_top); +// nrf_vpr_csr_vtim_simple_counter_top_set( +// 1, 2*(xfer_ll_params.counter_top+1)-1 ); /* Trigger data capture every two clock cycles */ + +// /* Set number of shifts before OUTB needs to be updated. +// * First shift needs to be increased by 1. +// */ +// nrf_vpr_csr_vio_shift_cnt_out_set(xfer_ll_params.word_size); +// nrf_vpr_csr_vio_shift_cnt_out_buffered_set(xfer_ll_params.word_size - 1); +// nrf_vpr_csr_vio_shift_cnt_in_set(xfer_ll_params.word_size - 1); + +// /* Enable CS */ +// out = nrf_vpr_csr_vio_out_get(); +// out &= ~PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); +// out |= xfer_ll_params.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 both counters */ +// nrf_vpr_csr_vtim_combined_counter_set( +// (xfer_ll_params.counter_top +// << VPRCSR_NORDIC_CNT_CNT0_Pos) + /* counter_top for capture on the posedge */ +// (cnt1_val +// << VPRCSR_NORDIC_CNT_CNT1_Pos)); /* 2*counter_top+1 for capture on negedge */ + +// /* Send data */ +// // for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { +// // nrf_vpr_csr_vio_out_buffered_reversed_byte_set(0xdeadbeef); +// // } + +// // /* Clear all bits, wait until the last word is sent */ +// // nrf_vpr_csr_vio_out_buffered_set(0); + +// /* Read data */ +// for (uint8_t i = 0; i < xfer_ll_params.data_len; i++) { +// nrf_vpr_csr_vtim_simple_wait_set(0, 0, 0); + +// xfer_ll_params.data_ptr[i] = nrf_vpr_csr_vio_in_buffered_reversed_byte_get(); +// // printf("xfer_ll_params.data_ptr[%d] = 0x%08x\n", i, xfer_ll_params.data_ptr[i]); +// } + +// /* Clear all bits, wait until the last word is sent */ +// nrf_vpr_csr_vio_out_buffered_set(0); + +// /* Final configuration */ +// out_mode.mode = NRF_VPR_CSR_VIO_SHIFT_NONE; +// nrf_vpr_csr_vio_mode_out_buffered_set(&out_mode); +// nrf_vpr_csr_vio_mode_in_buffered_set(NRF_VPR_CSR_VIO_MODE_IN_CONTINUOUS); + +// /* Deselect slave */ +// if (!xfer_ll_params.ce_hold) { +// out = nrf_vpr_csr_vio_out_get(); +// if (xfer_ll_params.ce_enable_state) { +// out &= ~PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); +// } else { +// out |= PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_CS0_PIN_NUMBER)); +// } +// out &= ~(PIN_OUT_HIGH_MASK(VIO(NRFE_MSPI_SCK_PIN_NUMBER))); + +// nrf_vpr_csr_vio_out_set(out); +// } + +// /* Stop counters */ +// nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); +// nrf_vpr_csr_vtim_count_mode_set(1, NRF_VPR_CSR_VTIM_COUNT_STOP); +} + +// void HMR_SINGLE (uint32_t address, uint32_t bytelength, uint32_t *dest, uint32_t cnttop) +// { +// volatile int i; +// volatile uint32_t prep_lastframes; +// volatile uint32_t prep_lastadjust; +// volatile uint32_t prep_end; +// volatile uint32_t prep_end_m1; +// volatile uint32_t bytelength_1_0; +// volatile uint32_t indata1; +// volatile uint32_t indata; +// volatile uint32_t addrperf; +// volatile uint32_t prep_outmode; +// volatile uint32_t prep_inmode; +// volatile uint32_t cnt1_val; +// volatile uint32_t B0, B1, B2; +// volatile uint32_t orig_val; +// volatile uint32_t new_val; + +// B0= ((address&0x3f0000)>>16); +// B1= (address&0xff00) >> 8; +// B2= (address&0xff); +// cnt1_val = (2*cnttop+1); + +// addrperf = B0 |(B1<<8)|(B2<<16); +// i=0; +// bytelength_1_0 = bytelength & 0x3; +// prep_lastframes = bytelength_1_0 << 3; //# Remaining QSPI 1-bit frames after the last full word +// prep_lastadjust = 32 - prep_lastframes; //# Right bitshift adjustment of the last incomplete word +// if (prep_lastframes!=0) { +// prep_lastframes = prep_lastframes-1; +// prep_outmode = OUTMODE_MODE_MODE2; +// prep_inmode = INMODE_MODE_MODE2; // SHIFT +// } else { +// prep_outmode = OUTMODE_MODE_NORMAL; +// prep_inmode = INMODE_MODE_NORMAL; // CONTINOUS +// } +// prep_end = bytelength >> 2; //# How many full 32bit words should be read +// prep_end_m1 = prep_end-1; + + +// csr_write(VPRCSR_NORDIC_DIR, (0x1<> prep_lastadjust; +// dest[i] = indata; +// i++; +// } +// // exit the function +// //delay_ms(6); +// return ; +// } + diff --git a/applications/sdp/mspi/src/hrt/hrt.h b/applications/sdp/mspi/src/hrt/hrt.h index e3156c80d4ef..01385d120eb1 100644 --- a/applications/sdp/mspi/src/hrt/hrt.h +++ b/applications/sdp/mspi/src/hrt/hrt.h @@ -83,10 +83,18 @@ struct hrt_ll_xfer { /** @brief Write. * - * Function to be used to write data on SPI. + * Function to be used to write data on MSPI. * * @param[in] xfer_ll_params Low level transfer parameters. */ void hrt_write(volatile struct hrt_ll_xfer xfer_ll_params); +/** @brief Read. + * + * Function to be used to read data from MSPI. + * + * @param[in] xfer_ll_params Low level transfer parameters. + */ +void hrt_read(volatile struct hrt_ll_xfer xfer_ll_params); + #endif /* _HRT_H__ */ diff --git a/applications/sdp/mspi/src/hrt/hrt.s b/applications/sdp/mspi/src/hrt/hrt.s index 0682c7b3b234..849b046d5691 100644 --- a/applications/sdp/mspi/src/hrt/hrt.s +++ b/applications/sdp/mspi/src/hrt/hrt.s @@ -134,6 +134,7 @@ hrt_write: csrw 3016, a3 #NO_APP j .L11 +<<<<<<< HEAD .L9: lw a3,16(a0) .L24: @@ -168,3 +169,149 @@ hrt_write: and a5,a5,a3 j .L26 .size hrt_write, .-hrt_write +======= + .size write_quad_by_word, .-write_quad_by_word + .section .text.read_single_by_word,"ax",@progbits + .align 1 + .globl read_single_by_word + .type read_single_by_word, @function +read_single_by_word: + lbu a5,0(a0) + addi sp,sp,-4 + slli a5,a5,1 + addi a5,a5,1 + sw a5,0(sp) + #APP + csrr a5, 3009 + #NO_APP + slli a5,a5,16 + srli a5,a5,16 + ori a4,a5,2 + #APP + csrw 3009, a4 + #NO_APP + andi a5,a5,-5 + #APP + csrw 3009, a5 + csrr a4, 3008 + #NO_APP + li a5,65536 + addi a3,a5,-1 + and a4,a4,a3 + #APP + csrw 3008, a4 + #NO_APP + addi a5,a5,4 + #APP + csrw 3043, a5 + csrw 3045, 2 + csrr a5, 1996 + #NO_APP + andi a5,a5,17 + ori a5,a5,256 + #APP + csrw 1996, a5 + csrw 2000, 2 + csrw 2001, 2 + #NO_APP + lbu a5,0(a0) + andi a5,a5,0xff + #APP + csrr a4, 2003 + #NO_APP + li a2,-65536 + and a4,a4,a2 + or a5,a5,a4 + #APP + csrw 2003, a5 + #NO_APP + lw a5,0(sp) + #APP + csrr a4, 2003 + #NO_APP + addi a5,a5,-1 + and a4,a4,a3 + slli a5,a5,16 + or a5,a5,a4 + #APP + csrw 2003, a5 + #NO_APP + lbu a5,1(a0) + #APP + csrw 3021, a5 + csrr a5, 3008 + #NO_APP + lbu a3,10(a0) + slli a5,a5,16 + srli a5,a5,16 + ori a4,a5,32 + beq a3,zero,.L19 + andi a5,a5,-33 + slli a4,a5,16 + srli a4,a4,16 +.L19: + #APP + csrw 3008, a4 + #NO_APP + lbu a4,0(a0) + lw a5,0(sp) + slli a5,a5,16 + add a5,a5,a4 + #APP + csrw 2002, a5 + #NO_APP + li a2,65536 + li a5,0 + addi a2,a2,-1 +.L20: + lbu a4,8(a0) + bgtu a4,a5,.L21 + li a5,65536 + #APP + csrw 3043, a5 + csrw 3045, 0 + #NO_APP + lbu a5,9(a0) + bne a5,zero,.L22 + #APP + csrr a5, 3008 + #NO_APP + lbu a3,10(a0) + slli a5,a5,16 + srli a5,a5,16 + ori a4,a5,32 + beq a3,zero,.L24 + andi a5,a5,-33 + slli a4,a5,16 + srli a4,a4,16 +.L24: + andi a4,a4,-2 + #APP + csrw 3008, a4 + #NO_APP +.L22: + #APP + csrw 2000, 0 + csrw 2001, 0 + #NO_APP + addi sp,sp,4 + jr ra +.L21: + #APP + csrr a4, 3021 + #NO_APP + andi a4,a4,1 + beq a4,zero,.L21 + #APP + csrr a3, 3018 + #NO_APP + lw a4,4(a0) + slli a1,a5,2 + and a3,a3,a2 + add a4,a4,a1 + addi a5,a5,1 + sw a3,0(a4) + andi a5,a5,0xff + j .L20 + .size read_single_by_word, .-read_single_by_word +>>>>>>> 784011ca31 (applications: sdp: mspi: Add RX path to SDP MSPI) diff --git a/applications/sdp/mspi/src/main.c b/applications/sdp/mspi/src/main.c index a3688f630fab..90f72076ac5a 100644 --- a/applications/sdp/mspi/src/main.c +++ b/applications/sdp/mspi/src/main.c @@ -18,6 +18,8 @@ #include #include +#include +#include /************************************************* * DEFINES @@ -26,6 +28,7 @@ #define DATA_PINS_MAX 8 #define HRT_IRQ_PRIORITY 2 +#define HRT_VEVIF_IDX_READ 17 #define HRT_VEVIF_IDX_WRITE 18 #define PINCTL_PIN_NUM_MASK 0x0fU @@ -101,32 +104,14 @@ static volatile struct hrt_ll_xfer xfer_ll_params; static struct ipc_ept ep; static atomic_t ipc_atomic_sem = ATOMIC_INIT(0); -/************************************************* - * GLOBAL FUNCTION PROTOTYPES - *************************************************/ - -__attribute__((interrupt)) void hrt_handler_write(void); - -int main(void); - /************************************************* * LOCAL FUNCTION PROTOTYPES *************************************************/ -static struct xfer_io_mode_cfg get_io_modes(enum mspi_io_mode mode); - -static void ep_bound(void *priv); - -static void process_packet(const void *data, size_t len, void *priv); - static void ll_prepare_transfer(enum base_io_mode xfer_mode, uint32_t data_length); - static void configure_clock(enum mspi_cpp_mode cpp_mode); - static void prepare_and_send_data(); - -static void process_packet(const void *data, size_t len); - +static void prepare_and_read_data(uint8_t *read_data, uint8_t data_length); static int backend_init(void); /************************************************* @@ -138,6 +123,11 @@ __attribute__((interrupt)) void hrt_handler_write(void) hrt_write(xfer_ll_params); } +__attribute__((interrupt)) void hrt_handler_read(void) +{ + hrt_read(xfer_ll_params); +} + int main(void) { int ret = backend_init(); @@ -146,6 +136,9 @@ int main(void) return 0; } + IRQ_DIRECT_CONNECT(HRT_VEVIF_IDX_READ, HRT_IRQ_PRIORITY, hrt_handler_read, 0); + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_READ), true); + IRQ_DIRECT_CONNECT(HRT_VEVIF_IDX_WRITE, HRT_IRQ_PRIORITY, hrt_handler_write, 0); nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE), true); @@ -231,9 +224,8 @@ static struct xfer_io_mode_cfg get_io_modes(enum mspi_io_mode mode) static void ep_bound(void *priv) { - (void)priv; - atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_EP_BOUNDED); + printf("Ep bounded\n"); } static void ll_prepare_transfer(enum base_io_mode xfer_mode, uint32_t data_length) @@ -431,10 +423,15 @@ static void process_packet(const void *data, size_t len, void *priv) { (void)priv; (void)len; + uint16_t dir; uint16_t out; nrfe_mspi_flpr_response_t response; + uint8_t opcode = *(uint8_t *)data; + uint32_t num_bytes = 0; + + printf("opcode: %d\n", opcode); response.opcode = opcode; @@ -481,6 +478,7 @@ static void process_packet(const void *data, size_t len, void *priv) } nrf_vpr_csr_vio_dir_set(dir); nrf_vpr_csr_vio_out_set(0); + break; } case NRFE_MSPI_CONFIG_CTRL: { @@ -488,14 +486,20 @@ static void process_packet(const void *data, size_t len, void *priv) response.opcode = cfg->opcode; nrfe_mspi_cfg = cfg->cfg; + break; } case NRFE_MSPI_CONFIG_DEV: { nrfe_mspi_dev_cfg_t *cfg = (nrfe_mspi_dev_cfg_t *)data; + response.opcode = cfg->opcode; nrfe_mspi_dev_cfg = cfg->cfg; + // printf("io_mode: %d, ce_polarity: %d, read_cmd: 0x%x, write_cmd: 0x%x,\ncmd_length: %d, addr_length: %d, tx_dummy: %d, rx_dummy: %d\n", + // cfg->cfg.io_mode, cfg->cfg.ce_polarity, cfg->cfg.read_cmd, cfg->cfg.write_cmd, cfg->cfg.cmd_length, cfg->cfg.addr_length, cfg->cfg.tx_dummy, cfg->cfg.rx_dummy); + configure_clock(nrfe_mspi_dev_cfg.cpp); + break; } case NRFE_MSPI_CONFIG_XFER: { @@ -503,6 +507,10 @@ static void process_packet(const void *data, size_t len, void *priv) response.opcode = xfer->opcode; nrfe_mspi_xfer = xfer->xfer; + + printf("CONFIG_XFER: cmd_length: %d, addr_length: %d, tx_dummy: %d, rx_dummy: %d\n", + nrfe_mspi_xfer.cmd_length, nrfe_mspi_xfer.addr_length, nrfe_mspi_xfer.tx_dummy, nrfe_mspi_xfer.rx_dummy); + break; } case NRFE_MSPI_TX: @@ -511,20 +519,71 @@ static void process_packet(const void *data, size_t len, void *priv) response.opcode = packet->opcode; nrfe_mspi_xfer_packet = packet->packet; + num_bytes = nrfe_mspi_xfer_packet.num_bytes; + + printf("Sending cmd: 0x%x, addr: 0x%x, data: %d bytes, cmd_length: %d, addr_length: %d\n", + nrfe_mspi_xfer_packet.cmd, nrfe_mspi_xfer_packet.address, + nrfe_mspi_xfer_packet.num_bytes, nrfe_mspi_xfer.cmd_length, nrfe_mspi_xfer.addr_length); + + if (nrfe_mspi_xfer_packet.dir == MSPI_RX) { + + if (nrfe_mspi_xfer_packet.num_bytes > 0) { + prepare_and_read_data(nrfe_mspi_xfer_packet.data_buf, nrfe_mspi_xfer_packet.num_bytes); + } + } else if (nrfe_mspi_xfer_packet.dir == MSPI_TX) { + + packet++; + uint8_t * data_buf = (uint8_t *)((uint8_t *)data + sizeof(nrfe_mspi_xfer_packet_t)); + + printf("addr packet: %p, data_buf: %p\n", packet, data_buf); - if (packet->packet.dir == MSPI_RX) { - /* TODO: Jira ticket: NRFX-6877 Process received data */ - } else if (packet->packet.dir == MSPI_TX) { prepare_and_send_data(); + } else { + printf("Invalid transfer direction: %d\n", nrfe_mspi_xfer_packet.dir); } break; } default: - response.opcode = NRFE_MSPI_WRONG_OPCODE; + opcode = NRFE_MSPI_WRONG_OPCODE; break; } - ipc_service_send(&ep, (const void *)&response.opcode, sizeof(response)); + uint8_t response_buffer[sizeof(opcode) + num_bytes]; + response_buffer[0] = opcode; + memcpy(&response_buffer[1], (uint8_t *)((uint8_t *)data + sizeof(nrfe_mspi_xfer_packet_t)), num_bytes); + + ipc_service_send(&ep, (const void *)response_buffer, sizeof(response_buffer)); +} + +void prepare_and_read_data(uint8_t *data, uint8_t data_length) +{ + xfer_ll_params.ce_hold = true; + + uint32_t address = 0x12345678; + uint32_t command = 0x09abcdef; + + nrf_barrier_rw(); + nrf_barrier_w(); + + if (nrfe_mspi_xfer.cmd_length > 0) { + /* Send command */ + xfer_ll_params.data = (uint8_t *)&command; + + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE)); + } + + if (nrfe_mspi_xfer.addr_length > 0) { + /* Send address */ + xfer_ll_params.data = (uint8_t *)&address; + + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE)); + } + + /* Read data */ + xfer_ll_params.data = data; + xfer_ll_params.ce_hold = false; + + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE)); } static int backend_init(void) diff --git a/drivers/mspi/mspi_nrfe.c b/drivers/mspi/mspi_nrfe.c index ffffcc16b848..4fc8cc1aff53 100644 --- a/drivers/mspi/mspi_nrfe.c +++ b/drivers/mspi/mspi_nrfe.c @@ -15,7 +15,7 @@ #include #endif #include -LOG_MODULE_REGISTER(mspi_nrfe, CONFIG_MSPI_LOG_LEVEL); +LOG_MODULE_REGISTER(mspi_nrfe, LOG_LEVEL_DBG); #include #include @@ -392,6 +392,12 @@ static int api_config(const struct mspi_dt_spec *spec) return ret; } + LOG_DBG("channel_num %d, op_mode %d, duplex %d, dqs_support %d, sw_multi_periph %d,\n ce_group %p, num_ce_gpios %d, num_periph %d, max_freq %d, re_init %d", + config->channel_num, config->op_mode, config->duplex, + config->dqs_support, config->sw_multi_periph, config->ce_group, + config->num_ce_gpios, config->num_periph, config->max_freq, + config->re_init); + /* Send controller configuration to FLPR */ return send_config(NRFE_MSPI_CONFIG_CTRL, (const void *)config, sizeof(struct mspi_cfg)); @@ -478,6 +484,9 @@ static int api_dev_config(const struct device *dev, const struct mspi_dev_id *de memcpy((void *)&drv_data->dev_cfg, (void *)cfg, sizeof(drv_data->dev_cfg)); drv_data->dev_id = *dev_id; + LOG_DBG("io_mode: %d, rx_dummy: %d, tx_dummy: %d, read_cmd: 0x%x, write_cmd: 0x%x,\ncmd_length: %d, addr_length: %d, freq: %d", + cfg->io_mode, cfg->rx_dummy, cfg->tx_dummy, cfg->read_cmd, cfg->write_cmd, cfg->cmd_length, cfg->addr_length, cfg->freq); + return send_config(NRFE_MSPI_CONFIG_DEV, (void *)cfg, sizeof(struct mspi_dev_cfg)); } @@ -510,6 +519,13 @@ static int xfer_packet(struct mspi_xfer_packet *packet, uint32_t timeout) memcpy((void *)&buffer[1], (void *)packet, struct_size); memcpy((void *)(&buffer[1] + struct_size), (void *)packet->data_buf, packet->num_bytes); + LOG_DBG("packet struct size: %d", struct_size); + + LOG_DBG("%s packet cmd: 0x%x, addr: 0x%x, size: %d", packet->dir == MSPI_RX ? "RX" : "TX", + packet->cmd, packet->address, packet->num_bytes); + LOG_HEXDUMP_DBG(packet->data_buf, packet->num_bytes, "Packet data:"); + LOG_HEXDUMP_DBG(buffer, len, "Packet buffer:"); + rc = mspi_ipc_data_send(opcode, buffer, len); if (rc < 0) { LOG_ERR("%d: Packet transfer error: %d", __LINE__, rc); @@ -596,6 +612,11 @@ static int api_transceive(const struct device *dev, const struct mspi_dev_id *de drv_data->xfer = *req; + LOG_DBG("async: %d, xfer_mode: %d, tx_dummy: %d, rx_dummy: %d, cmd_length: %d, addr_length: %d,\nhold_ce: %d, priority: %d, packets: %p, num_packet: %d, timeout: %d", + req->async, req->xfer_mode, req->tx_dummy, req->rx_dummy, + req->cmd_length, req->addr_length, req->hold_ce, req->priority, + req->packets, req->num_packet, req->timeout); + rc = send_config(NRFE_MSPI_CONFIG_XFER, (void *)&drv_data->xfer, sizeof(struct mspi_xfer)); if (rc < 0) { LOG_ERR("Send xfer config error: %d", rc); @@ -735,7 +756,7 @@ static int check_pins_config(const struct pinctrl_dev_config *config, uint8_t id return -ENOTSUP; } break; - case NRF_FUN_SDP_MSPI_DQ4: /* Only single and QSPI modes are supported */ + case NRF_FUN_SDP_MSPI_DQ4: if (psel != NRFE_MSPI_DQ4_PIN_NUMBER) { LOG_ERR("Wrong DQ4 GPIO pin number: %d! Needs to be = %d.", psel, NRFE_MSPI_DQ4_PIN_NUMBER); diff --git a/include/drivers/mspi/nrfe_mspi.h b/include/drivers/mspi/nrfe_mspi.h index a2d8e6ce1635..1065d73e6f30 100644 --- a/include/drivers/mspi/nrfe_mspi.h +++ b/include/drivers/mspi/nrfe_mspi.h @@ -25,7 +25,7 @@ extern "C" { #define NRFE_MSPI_DQ5_PIN_NUMBER 6 #define NRFE_MSPI_DQ6_PIN_NUMBER 7 #define NRFE_MSPI_DQ7_PIN_NUMBER 8 -#define NRFE_MSPI_CS0_PIN_NUMBER 9 +#define NRFE_MSPI_CS0_PIN_NUMBER 5 #define NRFE_MSPI_PINS_MAX 10 #else diff --git a/snippets/sdp/mspi/app.conf b/snippets/sdp/mspi/app.conf index 0bf532300b85..a47e24f21578 100644 --- a/snippets/sdp/mspi/app.conf +++ b/snippets/sdp/mspi/app.conf @@ -2,3 +2,11 @@ CONFIG_MSPI=y CONFIG_MBOX=y CONFIG_IPC_SERVICE=y CONFIG_IPC_SERVICE_BACKEND_ICMSG=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_STDOUT_CONSOLE=y +CONFIG_PRINTK=y +CONFIG_EARLY_CONSOLE=y + +# additional compiler flags +CONFIG_COMPILER_OPT="-fshort-enums" diff --git a/snippets/sdp/mspi/soc/nrf54l15_cpuapp.overlay b/snippets/sdp/mspi/soc/nrf54l15_cpuapp.overlay index c2630b8a2bbe..a4b86e128a17 100644 --- a/snippets/sdp/mspi/soc/nrf54l15_cpuapp.overlay +++ b/snippets/sdp/mspi/soc/nrf54l15_cpuapp.overlay @@ -10,26 +10,25 @@ #address-cells = <1>; #size-cells = <1>; - cpuflpr_code_partition: image@17a000 { - reg = <0x17a000 DT_SIZE_K(12)>; + cpuflpr_code_partition: image@178000 { + reg = <0x178000 DT_SIZE_K(20)>; }; - sram_rx: memory@2003c000 { - reg = <0x2003c000 0x0800>; + sram_rx: memory@2003a000 { + reg = <0x2003a000 0x0800>; }; - sram_tx: memory@2003c800 { - reg = <0x2003c800 0x0800>; + sram_tx: memory@2003a800 { + reg = <0x2003a800 0x0800>; }; }; - - cpuflpr_sram_code_data: memory@2003d000 { + cpuflpr_sram_code_data: memory@2003b000 { compatible = "mmio-sram"; - reg = <0x2003d000 DT_SIZE_K(12)>; + reg = <0x2003b000 DT_SIZE_K(20)>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x2003d000 0x3000>; + ranges = <0x0 0x2003b000 0x5000>; }; }; @@ -46,12 +45,12 @@ }; &cpuapp_rram { - reg = <0x0 DT_SIZE_K(1512)>; + reg = <0x0 DT_SIZE_K(1504)>; }; &cpuapp_sram { - reg = <0x20000000 DT_SIZE_K(244)>; - ranges = <0x0 0x20000000 0x3d000>; + reg = <0x20000000 DT_SIZE_K(232)>; + ranges = <0x0 0x20000000 0x3a000>; }; &cpuflpr_vpr { @@ -104,10 +103,36 @@ }; }; +/delete-node/ &mx25r64; + &sdp_mspi { clock-frequency = ; pinctrl-0 = <&sdp_mspi_default>; pinctrl-1 = <&sdp_mspi_sleep>; pinctrl-names = "default", "sleep"; status = "okay"; + mx25r64: mx25r6435f@0 { + compatible = "jedec,mspi-nor"; + status = "okay"; + reg = <0>; + jedec-id = [c2 28 17]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 48 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + size = <67108864>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + + mspi-max-frequency = ; + mspi-io-mode = "MSPI_IO_MODE_SINGLE"; + mspi-data-rate = "MSPI_DATA_RATE_SINGLE"; + mspi-hardware-ce-num = <1>; + mspi-cpp-mode = "MSPI_CPP_MODE_0"; + mspi-endian = "MSPI_BIG_ENDIAN"; + mspi-ce-polarity = "MSPI_CE_ACTIVE_LOW"; + }; };