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.

Parents
  • Hello,

    Sorry to say, but I don't see any reason why this should fail. You can find some nrfx spim examples here for comparison:
    https://github.com/zephyrproject-rtos/hal_nordic/tree/master/nrfx/samples/src 

    The nrf_drv_spi_transfer() is one abstraction layer higher than using the nrfx api directly.

    Kenneth

  • Hi,

    To supplement today's findings, according to the timing diagram in the manual below,

    we can see that both endtxand endrxshould be generated by events in spi sending, so I compared the timing diagrams in spi sending and found that some of them are different.

    The actual waveform is missing the waveform generated by the endtx/endrx event.

    The code that refers to this part of the code is in the spim_xfer() function

    I think the code has executed the code in position 1, but it is stuck in position 2, because the second position is followed by a pull up of the cs pin.

    The next direction I want to look for is what caused the code to get stuck in the second position, or what caused the endtx and endrx events not to occur.

    -----------------------------------------------------------------------------------------------------------------

    here is the latest findings, the spim didn't trigger the stoped event when end event is triggered, so the code is stuck in the left arrow.

  • Hello,

    Any way you can recreate this on a DK and send the project here so I can test also?

    I can't see any obvious reason why this should fail, other than there is actually an spim interrupt handler enabled that clear the event for you.

    Kenneth

Reply Children
Related