diff --git a/applications/sdp/mspi/src/hrt/hrt.c b/applications/sdp/mspi/src/hrt/hrt.c index 5b1ecdfa141..2408131917f 100644 --- a/applications/sdp/mspi/src/hrt/hrt.c +++ b/applications/sdp/mspi/src/hrt/hrt.c @@ -183,24 +183,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 f65987333b4..ccf6a2312d7 100644 --- a/applications/sdp/mspi/src/hrt/hrt.h +++ b/applications/sdp/mspi/src/hrt/hrt.h @@ -85,6 +85,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; @@ -105,6 +108,9 @@ typedef struct { /** @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 06c2213567e..73beccacddc 100644 --- a/applications/sdp/mspi/src/main.c +++ b/applications/sdp/mspi/src/main.c @@ -167,8 +167,11 @@ static void xfer_execute(nrfe_mspi_xfer_packet_t *xfer_packet, uint8_t *buffer) xfer_params.counter_value = 4; xfer_params.ce_vio = ce_vios[nrfe_mspi_xfer_config.ce_index]; xfer_params.ce_hold = nrfe_mspi_xfer_config.hold_ce; - xfer_params.ce_polarity = nrfe_mspi_xfer_config.ce_polarities[nrfe_mspi_xfer_config.ce_index]; + xfer_params.ce_polarity = + nrfe_mspi_xfer_config.ce_polarities[nrfe_mspi_xfer_config.ce_index]; xfer_params.bus_widths = io_modes[nrfe_mspi_xfer_config.io_mode]; + xfer_params.cpp_mode = nrfe_mspi_xfer_config.cpp; + xfer_params.clk_vio = pin_to_vio_map[NRFE_MSPI_SCK_PIN_NUMBER]; /* Fix position of command if command length is < BITS_IN_WORD, * so that leading zeros would not be printed instead of data bits. @@ -212,6 +215,19 @@ static void xfer_execute(nrfe_mspi_xfer_packet_t *xfer_packet, uint8_t *buffer) 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 (nrfe_mspi_xfer_config.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)); }