Post Go back to editing

Correct approach for transferring a packed struct via SPI in DMA mode

Thread Summary

The user inquires about the cache management in the 'SPIDMAMode_21569' example for ADSP-2156x EZ-KIT, specifically if the example is correct and how to handle struct transfers. The final answer confirms that buffer start addresses and lengths should be aligned to cache lines to ensure cache coherence. The user also explores using unions or non-cached memory sections for struct transfers, with the support engineer noting that both methods are approximately equivalent in terms of performance and cache management.
AI Generated Content
Category: Datasheet/Specs
Product Number: ADSP-21569

Hello,

since the demo project "SPIDMAMode_21569" contained in "ADSP-2156x_EZ-KIT-Rel1.0.1" package shows us the implementation of a DMA transfer of byte arrays between two SPI ports in an ultra-simple way, wanting to implement the transfer of an entire packed struct I was asking myself the following questions:

1) Is provided example in "SPIDMAMode_21569" correct, from a cache-management point of view?

The only reference I see regarding cache in such example is the TX/RX buffer declaration and PDMA descriptors list:

Apart from the fact that I don't fully understand the need of aligning descriptor lists to a cache line, I see that no one is concerned with invalidating the data cache or flushing it, consequently I was wondering about who's taking care of cache coherence?

2) Assuming "SPIDMAMode_21569" example is correct, how do you expect me to round the size of a struct to fill the entire cache line?

ADI_CACHE_ROUND_UP_SIZE() macro works quite well with arrays, but not with structs; unless I declare a byte array of the size of my packed struct rounding it up to fill the entire cache line, then cast that memory area to the datatype of my structure...... seems a bit convoluted, am I missing something?

Thanks in advance to anyone who wants to contribute.

Edit Notes

fixed
[edited by: SpoonMan999 at 5:39 PM (GMT -4) on 8 Apr 2025]
Parents
  • Would you be so kind to give me your point of view on this topic too? Thanks in advance for your kindful support. Bow tone1

  • Hi,

    Regarding "Is provided example in "SPIDMAMode_21569" correct, from a cache-management point of view?"

    >> Aligning buffer memory to cache line boundaries ensures that cache maintenance operations apply to the buffer memory alone, and not operate on unrelated data that may inadvertently share memory space on that cache line.
    This may not be an issue for most applications, but it can cause problems if adjoining, misaligned memory is also being accessed or written off-core, possibly by DMA or by another processor core.

    Cache is handled in "adi_pdma_Configuration" API were cache is invalidated to avoid conflicts. You can verify this configuration in both "adi_spi_DMAWrite" and "adi_spi_DMARead" APIs

    Regards
    Nandini C

  • if I understand correctly then you are saying that the two solutions are approximately equivalent?

  • Hi,

    Yes, your understanding is correct. In simple terms, when caching is enabled, flushing or invalidation is performed. If caching is disabled, the API is still called, but it checks on conditional basis it will flush and invalidate depending on the configuration of cache.

    Regards,
    Nandini C

  • Sorry  but I forgot to ask you a confirmation about question (1): if my understanding is correct, aligning source/destination buffers to cache boundaries AND filling up the whole cache line are both mandatory requirements for both PDMA and MDMA transfers?

  • Hi,

    Yes, it is recommended for applications with cache enabled to take special care when allocating memory for buffer transactions. Problems can arise when buffers are not aligned to cache line boundaries. Aligning buffer memory to cache line boundaries ensures that cache maintenance operations apply only to the intended buffer memory and do not affect unrelated data that may inadvertently share the same cache line. While this may not impact most applications, it can cause problems if adjoining, misaligned memory is also being accessed or written off-core, possibly by DMA or by another processor core.

    For more information, please refer the below mentioned CCES help path.
    CrossCore® Embedded Studio 2.12.0 > System Run-Time Documentation > Device Drivers User Guide > Low-Level Driver API Reference > Buffer Alignment and Cache Considerations

    Regards,
    Nandini C

  • Thanks Nandini, my question was very specific: we must align buffer START only, or we must align both START and LENGTH? Since I see many examples just aligning buffers using ADI_CACHE_ALIGN, but I suspect if length is not filling up the whole cache line something unexpected will happen during any DMA transfer, sooner or later.

  • Hi,

    Yes, for reliable MDMA/PDMA transfers in systems with cache enabled, it is important to make sure that both the start address and length of the buffer are aligned to cache line boundaries. This helps ensure that cache operations (like flush or invalidate) only affect the buffer, and not any nearby memory, which could lead to unexpected issues or data corruption.

    The recommended approach is to allocate buffer memory in multiples of the cache line size, even if part of the buffer remains unused. This precaution helps ensure safe and predictable behaviour during DMA operations.

    The above information is available in the CCES help we shared in your previous mail.
    CrossCore® Embedded Studio 2.12.0 > System Run-Time Documentation > Device Drivers User Guide > Low-Level Driver API Reference > Buffer Alignment and Cache Considerations

    Regards,
    Nandini C

  • And what about aligning descriptor lists to a cache line? Is this also required by the DMA controller to ensure descriptors "instructions" are swapped to physical memory when DMA operation start? So, example is wrong and also descriptors require using ADI_CACHE_ROUND_UP_SIZE?

    Finding myself experimenting again today on the MemCopyListMode demo for ADSP-21569, I can confirm that in such demo code the comments on source/destination buffers are the following:

    while source/destination descriptors are NOT aligned.

    Just for your information.

  • Hi,

    Configuring the descriptor list will be enough and using ADI_CACHE_ROUND_UP_SIZE for descriptors is not necessary since the descriptor list is already cache aligned (ADI_CACHE_ALIGN _Pragma("align 64")).

    Regards,
    Nandini C

  • Referring to MemCopyListMode demo:

    Descriptors are packed by definition, but not aligned nor padded to fill entire cache line.

  • Hi,

    The cache alignment would be necessary for large buffer transactions, where handling large amounts of data could lead to stale or missed data in the buffer. For smaller transfers, it may not affect the data transactions if you are flushing the buffers properly. If your application requires cache alignment, you can configure the buffers and descriptors as per the SPI DMA example.

    Regards,
    Nandini C

Reply
  • Hi,

    The cache alignment would be necessary for large buffer transactions, where handling large amounts of data could lead to stale or missed data in the buffer. For smaller transfers, it may not affect the data transactions if you are flushing the buffers properly. If your application requires cache alignment, you can configure the buffers and descriptors as per the SPI DMA example.

    Regards,
    Nandini C

Children
No Data