Why is SPI_CLK set floating after each call to adi_spi_ReadWrite()? It should be left high.

I'm using the ADSP-SC573.

I have selected SPI mode 3 (SPI_CLK shall be idle high). But between each call to adi_spi_ReadWrite() the SPI_CLK is set set floating, it is not driven high. I have tried to add a pull-up resistor on the board and can see that this makes SPI_CLK stay high.

But how do I fix this without needing to add an external pullup on SPI_CLK?

End one more thing. The chip select goes low at the same time the SCLK goes high. It is possible for the slave to interpret this as a rising edge and will mess up the clocks.

The code responsible for this is located in adi_spi_bf6xx.c on row 3908. It just turns the SPI off!!! Why?

This is my setup for the SPI:

    if (adi_spi_Open(SPI_DEVICE_NUMBER, &SpiMemory, sizeof(SpiMemory), &spiHandle)) break;

    // Device in master of the SPI interface
    if (adi_spi_SetMaster(spiHandle, true)) break;

    if (adi_spi_SetTransceiverMode(spiHandle, ADI_SPI_TXRX_MODE)) break;

    // Use interrupt. We will only clock out one 16-bit word so interrupt usage will not be any trouble
    //if (adi_spi_EnableDmaMode(spiHandle, false)) break;
    if (adi_spi_EnableDmaMode(spiHandle, true)) break;

    // SPI slave select in controlled by hardware not software
    if (adi_spi_SetHwSlaveSelect(spiHandle, false)) break;

    // Use driver slave select
    if (adi_spi_ManualSlaveSelect(spiHandle, false)) break;

    // Send zeros if TX SPI underflows
    if (adi_spi_SetTransmitUnderflow(spiHandle, true)) break;

    // Select mode 3 (CLK idle high, sample on rising edge, data changes on falling edge)
    if (adi_spi_SetClockPolarity(spiHandle, false)) break;

    if (adi_spi_SetClockPhase(spiHandle, true)) break;

    // Setup SPI clock
    uint32_t fsysclk;
    uint32_t fsclk0; 
    uint32_t fsclk1;

    if (adi_pwr_GetSystemFreq(0, &fsysclk, &fsclk0, &fsclk1)) break;
    uint16_t spiClockRate = ((float) fsclk0 / SPI_CLOCK_FREQUENCY_HZ) - 0.5f; // 0.5f is for rounding before truncating
    if (adi_spi_SetClock(spiHandle, spiClockRate)) break;

    // Designate the SPI slave select pin
    if (adi_spi_SetSlaveSelect(spiHandle, SLAVE_SELECT_PIN)) break;

    // SPI data transfers are 16 bit
    if (adi_spi_SetWordSize(spiHandle, ADI_SPI_TRANSFER_16BIT)) break;

    if (adi_spi_SetTxWatermark(spiHandle, ADI_SPI_WATERMARK_50, ADI_SPI_WATERMARK_DISABLE, ADI_SPI_WATERMARK_DISABLE)) break;

    if (adi_spi_SetRxWatermark(spiHandle, ADI_SPI_WATERMARK_50, ADI_SPI_WATERMARK_DISABLE, ADI_SPI_WATERMARK_DISABLE)) break;

    // No callback
    if (adi_spi_RegisterCallback(spiHandle, 0, 0)) break;



Added screen shot of chip select timing vs clock timing.
[edited by: masip at 6:45 AM (GMT -4) on 31 Aug 2021]
  • 0
    •  Analog Employees 
    on Sep 3, 2021 1:43 PM

    Hello,

    We are looking into this query. We will get back to you early next week

    Best Regards,

    Santhakumari.K

  • +1
    •  Analog Employees 
    on Sep 8, 2021 11:19 AM

    Hi,

    Thank you for notifying this observation to us.

    To simulate the issue, we have made a SPI setup communication between SPI2 as master and SPI0 as slave in ADSP-SC573EZKIT where master and slave are doing transfer in both directions simultaneously.

    We have configured CPOL as 1 and CPHASE as 1,so clock should be high at idle state and sampling occurs at rising edge of SPI clock. And for every completion of data transfer/API call, driver is written in the way that it disables SPI in PostTransceiverCompleted function as you said. Disabling of SPI makes clock line floating (goes to low) between adi_spi_readwrite calls.

    SPI0 slave reads the MOSI line and SPI2 master reads the MISO line at rising edge. While running SPI in the above mentioned clock configuration, enabling of SPI(next call of adi_spi_readwrite) switch clock line from floating line(low) to high idle state. When CS goes low, slave and Master now choose this rising edge for sampling and reads the wrong data,store them in Rx buffers as you exactly probed. We faced the data mismatch error in Rx buffers when compared to Master Tx and slave Tx buffers.

    But this can be solved by switching slave select control from software to hardware. We didn't face any data error while doing data transfer.

    Please try and let us know how you are getting on.

    Best Regards,
    Santhakumari.K

  • Thank you. It looks like this was the solution.