SPI-DMA on K70: RX DMA channel always interrupts as if it's set to INTHALF

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI-DMA on K70: RX DMA channel always interrupts as if it's set to INTHALF

743 Views
mb_apt
Contributor I

I am writing a completely non-blocking SPI-DMA driver that uses "current MAJOR loop iteration count" (TCDn_CITER) of RX DMA channel "reaching 0" (INTMAJOR set in DMA_TCDn_CSR register to generate DMA interrupt for RX DMA channel) as indicator that SPI transfer has completed (to kick off task wake semaphore). What I am observing however is that when RX DMA channel interrupt is generated TCDn_CITER is always ~1/2 of TCDn_BITER indicating that it's always generating interrupt as if it's set to INTHALF (which is not the case). I also tried forcing it to INTHALF and saw the exact same thing happen indicating that no matter whether you set INTMAJOR or INTHALF it will always operate as if it's set to INTHALF. To get around this problem I simply double the number of bytes i am expecting to receive for TCDn_CITER and TCDn_CITER when I setup the RX DMA channel and it starts to work flawlessly (tested by writing and reading back to verify Megabytes to SPI NOR Flash).

Any idea why it's doing what it's doing?

Below is more details about my SPI-DMA setup.

SPI settings:

Both RX and TX FIFOs enabled (disabling makes no difference on described problem)

Global DMA settings:

Both DMA channel and group arbitration is set to operate in round-robin fashion.

Minor loop is enabled.

RX DMA channel is 10. TX DMA channel is 12.

TX DMA channel:

Channel enabled and linked to SPI TX of appropriate SPI channel.

CITER = *transfer length*

BITER = *transfer length*

NBYTES = 4

SADDR = *pointer to uint32_t array*

SOFF = 4

SLAST = 0

DADDR = *SPI PUSHR of appropriate SPI channel*

DOFF = 0

DLAST = 0

ATTR = 32-bit and no SMOD for both source and destination

CSR = INTMAJOR | DREQ

RX DMA channel:

Channel enabled and linked to SPI RX of appropriate SPI channel.

CITER = *receive length* (described problem is fixed by doubling of *receive length*)

BITER = *receive length* (described problem is fixed by doubling of *receive length*)

NBYTES = 1

SADDR = *SPI POPR of appropriate SPI channel*

SOFF = 0

SLAST = 0

DADDR = *pointer to uint8_t array*

DOFF = 1

DLAST = 0

ATTR = 8-bit and no MOD for both source and destination

CSR = INTMAJOR | DREQ

Transfer is started by:

MCR of SPI channel = HALT | CLR_TXF | CLR_RXF

RSER of SPI channel = TFFF_RE | TFFF_DIRS | RFDF_RE | RFDF_DIRS

SR of SPI channel = EOQF | TCF

MCR of SPI channel &= ~HALT

DMA0->SERQ = *RX DMA channel number*

DMA0->SERQ = *TX DMA channel number*

*wait for wake semaphore*

MCR of SPI channel |= HALT

Transfer is completed when:

RX DMA channel generates and interrupt and task is awaken via semaphore

EDIT: Tested it on 1N96B and 3N96B K70 devices with the same behavior. We don't have 4N96B on any of our K70-TWR kits.

EDIT: Triggering off of TX DMA channel interrupt (INTMAJOR) does not have the same problem with CITER = ~1/2 BITER. However, you'd think it's safer to trigger off of RX DMA channel which guarantees that all of the data is finished both transmitting and receiving (simultaneous SPI TX and RX, TX byte count = RX byte count).

EDIT: Changing around TX and RX DMA channel numbers has no impact.

Labels (1)
Tags (3)
0 Kudos
2 Replies

462 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I have checked the errata of K70, the issue is not mentioned in errata. Have you checked the DMA_ES to know if any error happen?

BR

XiangJun Rong

0 Kudos

462 Views
mb_apt
Contributor I

Hi XiangJun,

No error flags in DMA_ES are set and nothing out of the ordinary observed in any DMA registers.

Regards

0 Kudos