Get stuck on while (! spi_xfer_done) when using spim

Hi all,

I had a problem using the spim function of nrf52832 to drive st25r3911, and now I'm pretty sure it's the problem here in spi.

here is the code for transmission:

uint8_t nrf_spi_tx_rx(const uint8_t *txData, uint8_t *rxData, uint8_t len)
{
    uint8_t tx[256];
    uint8_t rx[256];
    
    if (txData != NULL)
    {
        memcpy(tx, txData, len);
    }

    spi_xfer_done = false;
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, tx, len, (rxData != NULL) ? rxData : rx, len));
    while (!spi_xfer_done)
    {
    }
    return 0;
}

and when st25r3911 triggers an interrupt, the following code is called:

void st25r3911Isr(void)
{
    st25r3911CheckForReceivedInterrupts();

    if (NULL != st25r3911interrupt.callback)
        st25r3911interrupt.callback;
}

void st25r3911CheckForReceivedInterrupts(void)
{
    uint8_t iregs[ST25R3911_INT_REGS_LEN];
    uint32_t irqStatus;

    ST_MEMSET(iregs, (uint8_t)ST25R3911_IRQ_MASK_ALL, ST25R3911_INT_REGS_LEN);

    /* In case the IRQ is Edge (not Level) triggered read IRQs until done */
    while (platformGpioIsHigh(ST25R391X_INT_PIN))
    {
        st25r3911ReadMultipleRegisters(ST25R3911_REG_IRQ_MAIN, iregs, sizeof(iregs));

        irqStatus = (uint32_t)iregs[0];
        irqStatus |= (uint32_t)iregs[1] << 8;
        irqStatus |= (uint32_t)iregs[2] << 16;
        /* forward all interrupts, even masked ones to application. */
        st25r3911interrupt.status |= irqStatus;
    }
}

void st25r3911ReadMultipleRegisters(uint8_t reg, uint8_t *val, uint8_t length)
{
#if !defined(ST25R391X_COM_SINGLETXRX)
    uint8_t cmd = (reg | ST25R3911_READ_MODE);
    uint8_t *tmp;
    
    tmp = (uint8_t *)malloc(sizeof(uint8_t) * (length + 1));
    /* Since the result comes one byte later, let's first transmit the adddress with discarding the result */
    // platformSpiTxRx(&cmd, NULL, ST25R3911_CMD_LEN);
    // platformSpiTxRx(NULL, val, length);
    platformSpiTxRx(&cmd, tmp, ST25R3911_CMD_LEN + length);
    ST_MEMCPY(val, &tmp[ST25R3911_CMD_LEN], length);
    free(tmp);


    platformSpiDeselect();
    platformUnprotectST25R391xComm();
    return;
}

PlatformSpiTxRx () in the code is equivalent to nrf_spi_tx_rx ();

Then spi will send and receive data normally, but no other code will be executed when it is executed here, so it seems to be stuck in this place:

In addition, I used the logic analyzer to capture the data at this stage:

Where D4 is the interrupt signal, and the others from d0 to d3 are: cs,mosi,miso,clk;

As you can see from the data, after executing the 0x57 instruction, I received the data 0x028000 from miso, but then the program got stuck, and I couldn't find any reason.

  • Hi,

    I have found the cause of the problem, which is the problem of interrupt priority.

    In the sdk_config, there are three interrupt priorities related to spi, namely nrfx_spim_default_config_irq_priority,nrfx_spi_default_config_irq_priority and spi_default_config_irq_priority. since the third is at the bottom of the comparison, the priority levels I have been adjusting are the first two. however, I only found out today that the third is the main parameter in the setting. after I adjusted the third priority level to 5 (the priority of external interrupt is 6), this problem did not occur.

  • Hi 

    Good to hear you found the problem!

    Kenneth is currently out in Christmas holiday, but if you have more questions to this case he will be back next week. 

    Best regards
    Torbjørn

Related