Notes on softpack code examples using the XDMAC with a SAME70

Discussions around product based on ARM Cortex M7 core.
This forum will be discontinued soon.

Moderator: nferre

gpontis
Posts: 8
Joined: Sun Dec 20, 2009 10:52 pm

Notes on softpack code examples using the XDMAC with a SAME70

Wed Oct 25, 2017 5:42 pm

Hi All,

I grabbed the Softpack 1.5 for GNU and incorporated many examples into a new project. The project is based on custom hardware built around a SAME70. It depends heavily on using both SPI controllers, and needs good performance from them. I looked to an implementation based on the DMA controller.

The example code was quite helpful to get started, but also had several limitations that were time-consuming to track down and fix. I am posting some information to hopefully help others that go this path. I should mention that my app is using the SPI heavily, but the same issues would be at play with USART and other peripherals as they have more to do with the XDMAC and example code, than with the peripheral.

First thing, there are three errata concerning the XDMAC at the end of the SAME70 datasheet "Atmel-11296D-ATARM-SAM E70-Datasheet_19-Jan-16". I did not see these in the separately downloadable errata on the website. Get the datasheet and read these. The third errata only affects memory-memory transfers, the first only affects DMA to the TCM. You can't reliably use the TCM as the memory for less than 32b size transfers; so TCM will not mix with SPI, UARTs, and other peripherals using 8 or 16b data.

The second erratum is the big one. It says that there are some problems with 8 or 16b transfers when the source or address is in fixed address mode. For example, if the source is the SPI receive buffer, or if the destination is the SPI transmit buffer. Luckily there is a good workaround. However, the example code does not implement the workaround. The description of the workaround is a little unclear. To be more specific, it requires that if you are using XDMAC_CC_DAM_FIXED_AM, that it be replaced with XDMAC_CC_DAM_UBS_DS_AM. And that XDMAC_CC_SAM_FIXED_AM be replaced with XDMAC_CC_SAM_UBS_DS_AM. Then CSUS and DSUS need to be set to zero. The example code already does this. Specifically for _spid_configureLinkList in spi_dma.c, these are struct members mbr_sus and mbr_dus. The example code does not initialize mbr_ds at all, so stack garbage is being written to the peripheral. This initialization needs to be added and set to 0xffffffff : xdmadTxCfg.mbr_ds = 0xffffffff; and the same Rx.

There are several weaknesses in the example code that are unfortuntate, but not too hard to fix. The most significant of these is that the code uses two global variables to save the DMA channel numbers. In this case, they are spiDmaRxChannel and spiDmaTxChannel. The consequence of this is that it will break if more than one caller attempts to use SPI DMA at the same time. One possible fix is to expand these two globals into arrays, and base the index for the array on the instance of the SPI interface that is being called. The latter info is always available as pSpiHw or pSpid->pSpiHw.

A second factor to consider with the example code is that the DMA configuration is set up and torn down for each transfer. There is a lot of overhead doing this. A better organization might be to separate the one-time initialization and clean-up from the initiation of the transfers.

George
gpontis
Posts: 8
Joined: Sun Dec 20, 2009 10:52 pm

Re: Notes on softpack code examples using the XDMAC with a SAME70

Thu Oct 26, 2017 7:03 pm

There are a few additional problems with the spi_dma.c/h example code that I forgot to mention. One is that the typedef for SpidCmd uses a uint8_t for TxSize, but uint16_t for RxSize. Thus one cannot get the expected results if the actual TxSize is larger than 255. Since the peripheral is capable of 24 bit ublen, these should probably both be uint32_t.

There appears to be a goof-up in _spid_configureLinkList. The example code is setting at least one bit in the top byte of mbr_ubc, which is eventually written to CUBC. However, a macros strips off these bits before setting the ublen. In any case, these upper bits would not be valid for this device. They appear to be bits from the CNDC register.

Some defines from xdmad.h are used to set these invalid bits. The correct version of these bits have slightly different names and come from xdmac.h. The correction that I implemented was to eliminate the ORing of the incorrect bits with the TXSize and RxSize, and instead set them in the CNDC:

xdmaCndc = XDMAC_CNDC_NDVIEW_NDV0 | XDMAC_CNDC_NDE_DSCR_FETCH_DIS | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED;

I did not find these settings to cause a problem with SPI DMA, but changed this for correctness and to avoid later confusion.

Return to “SAM Cortex-M7 MCU”

Who is online

Users browsing this forum: No registered users and 1 guest