diff --git a/applications/sdp/mspi/src/hrt/hrt-nrf54l15.s b/applications/sdp/mspi/src/hrt/hrt-nrf54l15.s index 7e91a57dc3cb..50ca5a6d9e7a 100644 --- a/applications/sdp/mspi/src/hrt/hrt-nrf54l15.s +++ b/applications/sdp/mspi/src/hrt/hrt-nrf54l15.s @@ -228,23 +228,23 @@ hrt_write: beq a3,a2,.L26 li a5,32 div a5,a5,a4 - j .L43 + j .L42 .L22: lbu a4,81(s0) - j .L20 -.L19: + j .L24 +.L23: lbu a4,83(s0) - j .L20 -.L21: + j .L24 +.L25: lbu a5,8(a5) -.L43: +.L42: #APP csrw 3022, a5 #NO_APP - lbu a4,86(s0) + lbu a4,87(s0) li a5,1 sll a5,a5,a4 - lbu a4,88(s0) + lbu a4,89(s0) slli a5,a5,16 srli a5,a5,16 bne a4,zero,.L29 @@ -272,18 +272,8 @@ hrt_write: addi a2,sp,3 addi a0,s0,60 call hrt_tx - lbu a5,89(s0) - beq a5,zero,.L31 -.L32: - #APP - csrr a5, 3022 - #NO_APP - andi a5,a5,0xff - bne a5,zero,.L32 - #APP - csrw 2010, 0 - #NO_APP -.L31: + lbu a5,94(s0) + bne a5,zero,.L31 li a5,16384 addi a5,a5,1 #APP @@ -291,15 +281,19 @@ hrt_write: csrw 3017, 0 csrw 2000, 0 #NO_APP - lbu a5,87(s0) +.L32: + #APP + csrw 2005, 0 + #NO_APP + lbu a5,88(s0) bne a5,zero,.L19 - lbu a4,86(s0) + lbu a4,87(s0) li a5,1 sll a5,a5,a4 - lbu a4,88(s0) + lbu a4,89(s0) slli a5,a5,16 srli a5,a5,16 - bne a4,zero,.L34 + bne a4,zero,.L35 #APP csrs 3008, a5 #NO_APP @@ -310,13 +304,49 @@ hrt_write: jr ra .L26: lbu a5,9(a5) - j .L43 + j .L42 .L29: #APP csrs 3008, a5 #NO_APP j .L30 -.L34: +.L31: + #APP + csrr a5, 3022 + #NO_APP + andi a5,a5,0xff + bne a5,zero,.L31 + #APP + csrw 2000, 0 + #NO_APP + li a5,16384 + addi a5,a5,1 + #APP + csrw 3019, a5 + #NO_APP + lbu a5,94(s0) + li a4,1 + bne a5,a4,.L33 + lbu a4,86(s0) + sll a5,a5,a4 + slli a5,a5,16 + srli a5,a5,16 + #APP + csrc 3008, a5 + #NO_APP + j .L32 +.L33: + li a3,3 + bne a5,a3,.L32 + lbu a5,86(s0) + sll a4,a4,a5 + slli a4,a4,16 + srli a4,a4,16 + #APP + csrs 3008, a4 + #NO_APP + j .L32 +.L35: #APP csrc 3008, a5 #NO_APP diff --git a/applications/sdp/mspi/src/hrt/hrt.c b/applications/sdp/mspi/src/hrt/hrt.c index 147cff6ddf48..44f2467a231e 100644 --- a/applications/sdp/mspi/src/hrt/hrt.c +++ b/applications/sdp/mspi/src/hrt/hrt.c @@ -191,24 +191,32 @@ void hrt_write(hrt_xfer_t *hrt_xfer_params) hrt_tx(&hrt_xfer_params->xfer_data[HRT_FE_DATA], hrt_xfer_params->bus_widths.data, &counter_running, hrt_xfer_params->counter_value); - if (hrt_xfer_params->eliminate_last_pulse) { - - /* Wait until the last word is sent */ + /* Hardware issue workaround, + * additional clock edge when transmitting in modes other than MSPI_CPP_MODE_0. + * modes 1 and 3: Disable clock before the last pulse and perform last clock edge manualy. + * mode 2: Add one pulse more to the last word in message, and disable clock before the last + * pulse. + */ + if (hrt_xfer_params->cpp_mode == MSPI_CPP_MODE_0) { + nrf_vpr_csr_vio_shift_ctrl_buffered_set(&write_final_shift_ctrl_cfg); + nrf_vpr_csr_vio_out_buffered_reversed_word_set(0x00); + nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); + } else { while (nrf_vpr_csr_vio_shift_cnt_out_get() != 0) { } + nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); - /* This is a partial solution to surplus clock edge problem in modes 1 and 3. - * This solution works only for counter values above 20. - */ - nrf_vpr_csr_vtim_simple_wait_set(0, false, 0); - } + nrf_vpr_csr_vio_shift_ctrl_buffered_set(&write_final_shift_ctrl_cfg); - /* Final configuration */ - nrf_vpr_csr_vio_shift_ctrl_buffered_set(&write_final_shift_ctrl_cfg); - nrf_vpr_csr_vio_out_buffered_reversed_word_set(0x00); + if (hrt_xfer_params->cpp_mode == MSPI_CPP_MODE_1) { + nrf_vpr_csr_vio_out_clear_set(BIT(hrt_xfer_params->clk_vio)); + } else if (hrt_xfer_params->cpp_mode == MSPI_CPP_MODE_3) { + nrf_vpr_csr_vio_out_or_set(BIT(hrt_xfer_params->clk_vio)); + } + } - /* Stop counter */ - nrf_vpr_csr_vtim_count_mode_set(0, NRF_VPR_CSR_VTIM_COUNT_STOP); + /* Reset counter 0*/ + nrf_vpr_csr_vtim_simple_counter_set(0, 0); /* Disable CE */ if (!hrt_xfer_params->ce_hold) { diff --git a/applications/sdp/mspi/src/hrt/hrt.h b/applications/sdp/mspi/src/hrt/hrt.h index e5a576da8dd2..4468f10edac9 100644 --- a/applications/sdp/mspi/src/hrt/hrt.h +++ b/applications/sdp/mspi/src/hrt/hrt.h @@ -89,6 +89,9 @@ typedef struct { */ uint16_t counter_value; + /** @brief Index of clock VIO pin */ + uint8_t clk_vio; + /** @brief Index of CE VIO pin */ uint8_t ce_vio; @@ -98,17 +101,15 @@ typedef struct { /** @brief Chip enable pin polarity in enabled state. */ enum mspi_ce_polarity ce_polarity; - /** @brief When true clock signal makes 1 transition less. - * It is required for spi modes 1 and 3 due to hardware issue. - */ - bool eliminate_last_pulse; - /** @brief Tx mode mask for csr dir register */ uint16_t tx_direction_mask; /** @brief Rx mode mask for csr dir register */ uint16_t rx_direction_mask; + /** @brief Due to hardware issues hrt module needs to know about selected spi mode */ + enum mspi_cpp_mode cpp_mode; + } hrt_xfer_t; /** @brief Write. diff --git a/applications/sdp/mspi/src/main.c b/applications/sdp/mspi/src/main.c index 1d64d10a03f3..df2af4ee0a19 100644 --- a/applications/sdp/mspi/src/main.c +++ b/applications/sdp/mspi/src/main.c @@ -147,25 +147,21 @@ static void configure_clock(enum mspi_cpp_mode cpp_mode) case MSPI_CPP_MODE_0: { vio_config.clk_polarity = 0; WRITE_BIT(out, pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER], VPRCSR_NORDIC_OUT_LOW); - xfer_params.eliminate_last_pulse = false; break; } case MSPI_CPP_MODE_1: { vio_config.clk_polarity = 1; WRITE_BIT(out, pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER], VPRCSR_NORDIC_OUT_LOW); - xfer_params.eliminate_last_pulse = true; break; } case MSPI_CPP_MODE_2: { vio_config.clk_polarity = 1; WRITE_BIT(out, pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER], VPRCSR_NORDIC_OUT_HIGH); - xfer_params.eliminate_last_pulse = false; break; } case MSPI_CPP_MODE_3: { vio_config.clk_polarity = 0; WRITE_BIT(out, pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER], VPRCSR_NORDIC_OUT_HIGH); - xfer_params.eliminate_last_pulse = true; break; } } @@ -181,8 +177,10 @@ static void xfer_execute(nrfe_mspi_xfer_packet_msg_t *xfer_packet) xfer_params.counter_value = 4; xfer_params.ce_vio = ce_vios[device->ce_index]; xfer_params.ce_hold = nrfe_mspi_xfer_config.hold_ce; + xfer_params.cpp_mode = device->cpp; xfer_params.ce_polarity = device->ce_polarity; xfer_params.bus_widths = io_modes[device->io_mode]; + xfer_params.clk_vio = pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER]; /* Fix position of command and address if command/address length is < BITS_IN_WORD, * so that leading zeros would not be printed instead of data bits. @@ -239,6 +237,19 @@ static void xfer_execute(nrfe_mspi_xfer_packet_msg_t *xfer_packet) adjust_tail(&xfer_params.xfer_data[HRT_FE_DATA], xfer_params.bus_widths.data, xfer_packet->num_bytes * BITS_IN_BYTE); + /* Hardware issue workaround for MSPI_CPP_MODE_2, + * additional clock edge when transmitting in modes other than MSPI_CPP_MODE_0. + * add one pulse more to the last word in message, and disable clock before the last pulse. + */ + if (device->cpp == MSPI_CPP_MODE_2) { + for (uint8_t i = 0; i < HRT_FE_MAX; i++) { + if (xfer_params.xfer_data[HRT_FE_DATA - i].word_count != 0) { + xfer_params.xfer_data[HRT_FE_DATA - i].last_word_clocks++; + break; + } + } + } + nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, VEVIF_IRQN(HRT_VEVIF_IDX_WRITE)); }