nuttx icon indicating copy to clipboard operation
nuttx copied to clipboard

SPI/DMA issue with ws2812 driver

Open bertvoldenuit opened this issue 2 years ago • 4 comments

At each transfer, there is a TERR (transfer error) on the RX channel. I tried to put the MISO pin on idle/high/low but it has no effect.

According to SAMD21 Errata:

1.7.2 Linked Descriptor

When at least one channel using linked descriptors is already active, enabling another DMA channel (with or without
linked descriptors) can result in a channel Fetch Error (FERR) or an incorrect descriptor fetch.
This occurs if the channel number of the channel being enabled is lower than the channel already active.

Workaround

When enabling a DMA channel while other channels using linked descriptors are already active, the channel number
of the new channel enabled must be greater than the other channel numbers.`

In the spi driver, in the description and in the code it is always Tx and then Rx except in one place where it is Rx and then Tx which could lead in the FERR according to Errata

I think it would be better to swap Rx/Tx in the following code:

static void spi_dma_setup(struct sam_spidev_s *priv)
{
  /* Allocate a pair of DMA channels */

    priv->dma_rx = sam_dmachannel(DMACH_FLAG_STEPSEL_PERIPH|
                                DMACH_FLAG_BEATSIZE_BYTE |
                                DMACH_FLAG_MEM_INCREMENT |
                                DMACH_FLAG_PERIPH_RXTRIG(priv->dma_rx_trig)); 
    priv->dma_tx = sam_dmachannel(DMACH_FLAG_STEPSEL_PERIPH|
                                DMACH_FLAG_BEATSIZE_BYTE |
                                DMACH_FLAG_MEM_INCREMENT |
                                DMACH_FLAG_PERIPH_TXTRIG(priv->dma_tx_trig));
                               
}

into

static void spi_dma_setup(struct sam_spidev_s *priv)
{
  /* Allocate a pair of DMA channels */

  priv->dma_tx = sam_dmachannel(DMACH_FLAG_STEPSEL_PERIPH|
                                DMACH_FLAG_BEATSIZE_BYTE |
                                DMACH_FLAG_MEM_INCREMENT |
                                DMACH_FLAG_PERIPH_TXTRIG(priv->dma_tx_trig));

  priv->dma_rx = sam_dmachannel(DMACH_FLAG_STEPSEL_PERIPH|
                                DMACH_FLAG_BEATSIZE_BYTE |
                                DMACH_FLAG_MEM_INCREMENT |
                                DMACH_FLAG_PERIPH_RXTRIG(priv->dma_rx_trig));                                
}

I can make a PR but it does not change anything in my case, I still get TERR.

Could disabling the DMAC_INT_TERR interrupt be a way around? when I disable it nsh is not showing up.

bertvoldenuit avatar Nov 26 '23 19:11 bertvoldenuit

@bertvoldenuit I think the modification makes sense, please submit the PR anyway.

BTW, maybe you are getting the TERR for some other reason, this kind of analysis is hard to do, maybe you could ask form help from in the Microchip forum, although they know nothing about NuttX, they could give you more some hints about that could be causing the issue.

@pkarashchenko do you have some other suggestion?

acassis avatar Nov 27 '23 15:11 acassis

@bertvoldenuit any news about this SAMD21 issue?

acassis avatar Dec 01 '23 14:12 acassis

I am still blocked. I will ask Microchip and do the PR.

bertvoldenuit avatar Dec 02 '23 18:12 bertvoldenuit

I did the PR.

Here is a link to the Microchip forum where I posted the issue: https://forum.microchip.com/s/topic/a5C3l000000BsKQEA0/t393153

bertvoldenuit avatar Dec 02 '23 21:12 bertvoldenuit