My ncs version is v3.1.1 and I'm trying to connect a chip (INTAN)RHD2164 using SPI on the nRF54L15 DK. The special feature is that it needs to sample data at double the rate of DDR on the MISO. According to the official INTAN example, two SPI peripherals are required to complete the data transmission.
I have enabled PWM21 to generate a pseudo-clock with a rate twice that of SCLK and output it The pins are physically connected to the SCK pins of the slave SPI to ensure that DDR sampling works correctly.
I enabled SPIM21(as master, only sending, no MISO) and SPIS00(as slave, only receiving, no MOSI) on the nRF54L15.
The current problem is that the program will permanently freeze after the nrfx_spis_buffers_set is executed (or is in execution), and will never print "222". It seems to be waiting for some kind of receiving signal? It is certain that if only the nrfx_spim_xfer function is called, the correct SPI waveform can be detected by the logic analyzer. However, once both the sending and receiving functions are enabled simultaneously, the above problem will occur. Are there any special conditions for the SPIS reception of nRF54L15 that I have ignored? Looking forward to your reply
SPI pin config (used clock pin):
#define SPIM_INST_IDX 21
#define SCK_PIN (NRF_GPIO_PIN_MAP(1, 11))
#define MOSI_PIN (NRF_GPIO_PIN_MAP(1, 10))
#define CSN_PIN (NRF_GPIO_PIN_MAP(1, 9))
#define SPIS_INST_IDX 00
#define SSCK_PIN (NRF_GPIO_PIN_MAP(2, 6))
#define SMOSI_PIN (NRF_GPIO_PIN_MAP(2, 9))
#define SCSN_PIN (NRF_GPIO_PIN_MAP(2, 5))
my application code:
int spi_init(void)
{
nrfx_err_t status;
spim_config.frequency = NRFX_KHZ_TO_HZ(500); // 500kHz
spim_config.mode = NRF_SPIM_MODE_0;
spim_config.use_hw_ss = true;
status = nrfx_spim_init(&master, &spim_config, spim_handler, NULL);
NRFX_ASSERT(status == NRFX_SUCCESS);
spis_config.mode = NRF_SPIS_MODE_0;
spis_config.bit_order = NRF_SPIS_BIT_ORDER_MSB_FIRST;
spis_config.def = 0xFF;
status = nrfx_spis_init(&slave, &spis_config, spis_handler, NULL);
NRFX_ASSERT(status == NRFX_SUCCESS);
status = nrfx_spis_buffers_set(&slave, NULL, 0, m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
NRFX_ASSERT(status == NRFX_SUCCESS);
nrfx_spim_xfer_desc_t spim_xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buffer, sizeof(m_tx_buffer),
m_rx_buffer, sizeof(m_rx_buffer));
status = nrfx_spim_xfer(&master, &spim_xfer_desc, 0);
NRFX_ASSERT(status == NRFX_SUCCESS);
transfer_sequence_spi_dma();
}
static void spim_handler(nrfx_spim_evt_t const * p_event, void * p_context)
{
printf("spim_handler evt_type=%d\n", p_event->type);
spim_xfer_done = true;
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
}
}
static void spis_handler(nrfx_spis_evt_t const * p_event, void * p_context)
{
printf("spis_handler evt_type=%d\n", p_event->evt_type);
if (p_event->evt_type == NRFX_SPIS_XFER_DONE) {
spis_xfer_done = true;
}
}
void transfer_sequence_spi_dma(void)
{
nrfx_err_t err;
static uint8_t m_tx_buffer[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
uint8_t m_rx_buffer[16];
// Prepare SPIS RX (start listening first)
spis_xfer_done = false;
printf("111\n");
err = nrfx_spis_buffers_set(&slave, m_tx_buffer, 4, m_rx_buffer, 4);
if (err != NRFX_SUCCESS) {
printf("SPIS buffer set error[%d]\n", err);
return;
}
printf("222\n");
// Start SPIM TX (will pull CS low, trigger Pseudo-SCLK via DPPI)
spim_xfer_done = false;
nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TRX(&m_tx_buffer, 4, &m_rx_buffer, 4);
err = nrfx_spim_xfer(&master, &xfer, 0);
if (err != NRFX_SUCCESS) {
printf("SPIM transfer error[%d]\n", err);
return;
}
// Wait for completion (poll or use semaphores in real app)
while (!spim_xfer_done || !spis_xfer_done) {
k_sleep(K_MSEC(1)); // Avoid busy-wait; use events
}
// De-interleave received data
for (int i = 0; i < 16; i++) {
uint16_t word_A, word_B;
extract_ddr_words(m_rx_buffer[i], &word_A, &word_B);
// Process word_A and word_B
}
printf("Transfer complete\n");
}
