Post Go back to editing

adi_spi_DMAWrite() taking too long (more in general, ADI SPI driver functions are slow)

Category: Software
Product Number: ADSP-21569
Software Version: CCES 2.12.1 (but I already tested that CCES 3.0.2 is the same)

Back for the second episode of my series.

I have therefore expanded the project code illustrated in the first post of this series (here: SPI slave mode shifting 1s on MISO pin during adi_spi_DMARead() operation - Q&A - ADSP-2156x - EngineerZone) to get one step closer to the real-world application I'm going to develop.

In my application idea, master SPI is going to transfer N bytes to the slave, then slave SPI is going to transfer M bytes back to the master, all in a single transaction (by transaction I mean that, from SPI masters' point of view, the whole data exchange would be equivalent to a single transfer of N+M bytes).

To simulate this new scenario, I then applied the following changes to the code:

  • in main() function, I switched to software slave select mode, then I asserted slave select line right before DMA write call (let me say in the meantime that adi_spi_SoftwareAssert() is really a poor naming choice for a function dealing with slave select line driving....):

  • I modified data buffer lengths and added a third buffer for slaves' response data:

  <--- in SPIDMAMode.h, replacing DESC_BUFFER_SIZE macro

 <--- in SPIDMAMode.c

  • I modified PrepareDataBuffers() function to initialize SrcData with REQUEST_LEN bytes of dummy data and padding it with RESPONSE_LEN bytes used to retrieve response data back from the SPI slave, and I added a second PrepareResponseBuffer() function that will be used later by the SPI slave to simulate the slave is preparing something to send back to the master:

  • I modified PrepareDescriptors() function basically to make it consistent with applied changes to source/destination buffers lengths:

  • Then, finally, I modified interrupt callback as follows, also passing SPI handlers as callback parameter:

 <--- new callback code

 <--- changes in main() to pass SPI handlers as callback parameters.

Keeping SPI clock to around 1.3 MHz as in my previous post the result is exactly as expected:

but later when trying to raise clock frequency just a little bit to around 1.6MHz, this is what starts to happen:

clearly meaning that adi_spi_DMAWrite() inside Callback() is taking too long while disabling/enabling SPI slave peripheral.

This is what emerges by "looping the SPI dance forever" then analyzing the situation with statistical profiling:

So, the question is: how can I improve this behavior? There's no solution other than stop using ADI SPI driver and switching to a lower-level approach?

Thanks in advance to anyone who wants to contribute

Edit Notes

broken link, fixed?
[edited by: SpoonMan999 at 1:50 PM (GMT -4) on 20 Mar 2025]
Parents
  • Hi,

    Thank you for your question. I am reviewing the information you provided and may come back with follow up questions. I appreciate your patience as I work on your query. 

    Regards,

    Nandini C

  • Hi,

    We understand that you want to transfer data between the master and slave using SPI. Initially, data should be transmitted from the master to the slave, and once that is finished, the transmission should occur in the opposite direction, from the slave to the master. The issue you are encountering is that the data transfer from slave to master is not functioning correctly when the SPI clock is set to 1.6MHz but works fine when the clock is set to 1.3MHz. You suspect that latency may be causing this issue. Could you please confirm if this is correct?

    Additionally, we have the following questions to narrow down the issue.

    1) Could you confirm whether the callback execution time is the same for both 1.3MHz and 1.6MHz SPI clock frequencies?
    2) Are there any error bits enabled in the SPI/DMA status register? Can you please share screenshot of register browser window.
    3) Are the SPI modules properly disabled before being reconfigured for slave transmission and master reception?
    4) Just to ensure this behavior, is it possible to configure the API outside of the callback and check if the issue still persists.

    Regards,
    Nandini C

  • Hi,

    Thank you. Can you please share the project file, so that we can try to replicate and assist you better on this.

    Regards,
    Nandini C

  • Hi,
    Thank you for sharing the example code. We are checking the code and will get back to you early in the next week.
    Regards,
    Nandini C
  • Hi,

    We are checking internally regarding your query and will get back to you as soon as possible.

    Regards,
    Nandini C

  • Hi,

    We checked on your requirement with the example you have shared, after the analysis we understood you want to transmit 10 bytes from master and slave receives 8 bytes. Once 8 bytes transmission is completed, you want to configure slave to transmit 2 bytes to master in a single transaction.

    If this is your exact requirement, then unfortunately we would like to point that this will be an issue as slave callback will be hit priorly to the master callback. And also, reconfiguration within the callback is not recommended as it can delay the return from the callback, leading to missed ISR events and latencies. As the slave is being reconfigured while the master is trying to transmit the last 2 bytes, during higher clock speed Slave reconfiguration happens too late i.e. Slave is not ready before the last 2 bytes are clocked out, causing the slave transmission data to be shifted and depending on timing, data mismatch or data corruption could occur which may lead to Master receiving garbage or stale data.

    In lower frequency, the slave may get enough time to reconfigure to transmit data, so it appears to align with master clock. Though it is working it is not recommended to reconfigure the slave while master is transmitting data within a callback.

    So, we would like to suggest a different approach by using two descriptors each for Master and Slave transmission and reception which can accommodate your requirement where the master transmit, and slave receive completes and then Slave and Master are reconfigured to transmit and receive the 2 bytes outside the callback.

    Please let us know if the above suggestion aligns with your requirement so that we can proceed on assisting with recommendation.

    Regards,
    Nandini C

  • Hello   and thanks for your response.

    Yes, your understanding of what I was trying to do is correct, and the key point resides in the following sentence:

    In lower frequency, the slave may get enough time to reconfigure to transmit data, so it appears to align with master clock.

    This is basically pointing out that slave reconfiguration is taking too long, and this is the limitation I would like to overcome. 1us for slave reconfiguration looks to last in a lifetime compared to e.g. 25Mbps bit clock period. The question was exactly this, why adi_spi_DMAWrite() is taking so much time, and how to overcome this inefficiency?

  • Hi ,

    As mentioned in our previous email, it is not recommended to reconfigure the slave while the master is transmitting. Therefore, the behaviour you are observing with adi_spi_DMAWrite() is expected.

    As you are already aware, for full-duplex communication, we recommend using the adi_spi_DMATransceiver() API on both the master and slave sides. This API enables both the TXCTL and RXCTL of the corresponding SPI and activates the SPI interface, allowing for simultaneous transmission and reception of data.


    Regards,
    Nandini C

  • Sorry but I cannot see the difference between invoking adi_spi_DMATransceiver() instead of adi_spi_DMAWrite() while the master is transmitting.

  • Hi,

    When using the adi_spi_DMATransceiver() API, we recommend appending two zeros at the end of the master’s transmit buffer and eight zeros at the beginning of the slave’s transmit buffer. This will ensure that data is transmitted and received between the master and slave over 10 clock cycles.
    If the above approach is not feasible, we suggest waiting for the master to complete its data transmission and for the slave to successfully receive it. Once the transfer is completed, you can reconfigure the master to receive and slave to transmit the data using "adi_spi_DMARead()" and "adi_spi_DMAWrite()" APIs. Configure two descriptors for both the master and slave for transmission and reception. Additionally, we recommend reconfiguring the SPI outside of the callback function to ensure proper operation.

    Regards,
    Nandini C

  • Hi Nandini,

    Thank you for your response.

    Unfortunately, I am not satisfied with the explanation provided, as it does not offer any technical details regarding why adi_spi_DMAWrite() is taking too long, since "reconfiguration within the callback is not recommended as it can delay the return from the callback, leading to missed ISR events and latencies" is not an explanation about why SPI reconfiguration is taking that long, which is the core of the problem for which I asked for help.

    Avoiding long operations inside an interrupt callback because it may lead to missed ISR events is a general principle, not specifically related to SPI or Analog Devices.

    Anyway, I'm sorry but if for any reason you cannot reply to the topic, I cannot as well continue to reiterate my request indefinitely.

    Thanks for your understanding.

Reply
  • Hi Nandini,

    Thank you for your response.

    Unfortunately, I am not satisfied with the explanation provided, as it does not offer any technical details regarding why adi_spi_DMAWrite() is taking too long, since "reconfiguration within the callback is not recommended as it can delay the return from the callback, leading to missed ISR events and latencies" is not an explanation about why SPI reconfiguration is taking that long, which is the core of the problem for which I asked for help.

    Avoiding long operations inside an interrupt callback because it may lead to missed ISR events is a general principle, not specifically related to SPI or Analog Devices.

    Anyway, I'm sorry but if for any reason you cannot reply to the topic, I cannot as well continue to reiterate my request indefinitely.

    Thanks for your understanding.

Children
No Data