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.

Related