cancel
Showing results for 
Search instead for 
Did you mean: 

How do you stop SPI DMA circular transfers in a G474RE

Greg Horler
Associate III

I am using a NUCLEO64-G474RE as an SPI master with DMA (Rx and Tx in circular mode) to interface an ADC CHIP. I am receiving data reliably but wish to stop  and start the SPI/DMA . 

I have used CubeMx to generate the initilisation code and HAL_SPI_TransmitReceive_DMA( ) to start sampling. However I cannot stop the reception.

I have read the relevant sections of RM0440. The only reference to stopping the SPI/DMA is on page 1745 where it states

  1. Disable DMA streams for TX and Rx in the DMA registers, if the streams are used.
  2. Disable the SPI by following the SPI disable proceedure as follows (this is on Page 1743)
      Wait until FTLVL[1:0] = 00 (NO MORE DATA TO TRANSMIT)
      Wait until BSY=0 (THE LAST DATA FRAME IS PROCESSED)
      Disable the SPI (SPE =0);
      Read data until FRLVL[1:0] = 00 (read all the received data)
  3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the SPI_CR2 register, if DMA Tx and/or DMA Rx are used.


I could find no reference to the term "streams" in the DMA section of the data sheet, what are they?

My effort is below, what am I doing wrong? Many thanks in advance.

/* stop the SPI-DMA process */

HAL_SPI_DMAStop(&hspi3); // Disable DMA streams if used what and how???
__nop();

while (((SPI3->SR)&(3<<11))) {}; // Wait until FTLVL[1:0] = 00 (no more data to transmit)

while (((SPI3->SR)&(1<<7))) {}; // Wait until BSY = 0 (the last data frame is processed)

SPI3->CR1 &= ~(1<<7); // Disable the SPI (SPE = 0)

do{
dummy = SPI3->DR; // Keep doing dummy reads of the SPI3 data register
dummy = SPI3->SR; // (this line allows the FRLVL bits to be observed)
} while(((SPI3->SR)&(3<<9))); // until FRLVL[1:0] = 0 i.e. all data received

SPI3->CR2 &= ~(11); // Disable DMA Rx and Tx buffers TXDMAEN = RXDMAEN = 0

GDH
19 REPLIES 19

> I could find no reference to the term "streams" in the DMA section of the data sheet, what are they?

This portion is copypasted from manual of an STM32 with dual-port DMA, you have single-port DMA so you can read "stream" as "channel".

I don't use Cube/HAL. If you want anything which is not clicked simply in CubeMX or for what is there no clear example, you may want avoid Cube/HAL too.

Cube/HAL is open source so you can find out what its functions do for yourself.

> My effort is below, what am I doing wrong?

Why do you think you do something wrong?

JW

LCE
Principal

I can't really help much, haven't used SPI on a G4.

But with DMA stream they mean DMA channel. Check your SPI MSP init, that's where HAL / Cube links your peripheral to 2 different DMA streams / channels for TX & RX.
The used DMA channels are linked by pointers in the SPI handle (your source: "hspi3").

And do yourself (and us...) a favor and use the register bit defines somewhere in
?\Drivers\CMSIS\Device\ST\STM32G4xx\Include\stm32g4??xx.h:

SPI3->CR1 &= ~(SPI_CR1_SPE);

BTW, I just see in my G4 reference manual, the SPI enable bit is bit 6, not 7.

Thanks for the clarification re streams and channels. Why ST authors could not have added a sentence for clarity baffles me?

Why do I think I'm doing something wrong? Just because something works does not mean it has been done properly, hence the need to reach out to those more knowledgable.

GDH

Well spotted, thanks.

Thanks also for pointing out the use of bit definitions.

GDH
Greg Horler
Associate III

JW and LCE, thanks for taking the time to reply.

I am now able to start and stop the spi/dma via a USB-CDC VCOM channel and log the data I receive. In running the system I have noted a peculiar annomaly in the data, a picture (.jpg) of which is attached. While this does not happen often, and the occurence is intermittent, it is a BIG issue, re reliability and self diagnosis; this concerns me.

The format of the data I recieve from my dual synchronous adc is shown in the attached.pdf, effectively 4 bytes as follows 0000 xxxx xxxx xxxx yyyy yyyy yyyyy 0000  where x is a 12 bit sample (chn A)  >> 0 and y a 12 bit sample (chn B) << 4.

It would appear that aperiodically there is a glitch in synchronisation of the mapping from the spi fifo to the dma? This results in the 4 byte data being barrel-shifted by a byte, hence corrupting the values received. Do you have any idea what can be causing this, and if you do, how do I fix it please? I can confirm from oscilloscope measurement that the SPI signals on the bus are correct, are not displaying any errors and accurately reflect the value of the analoue signals being measured.

Thanks in advance.

GDH

> Why do I think I'm doing something wrong? Just because something works does not mean it has been done properly, hence the need to reach out to those more knowledgable.

No, sorry, I meant, what is the expectation, what is the observed behaviour and how exactly did you observe that.

JW

LCE
Principal

What's the ADC sampling rate, with how many channels?

What's the Uart's baud rate?

Even 1 channel 10 kHz 12-bit ADC with 115k2 Uart won't show you all data...

Jan, hi. The real reason for reaching out is due to the byte skipping issue as I described in my previous post, do take a look at the pictures. The intermittent shifting of bytes or nibbles manifests itself as gross errors when we come to plot the data (in pseudo real time or from a log file). I've tried to get help on explaining this "shifting" behaviour and what is causing it, (ST ticket, but no solution yet) so I can understand and  tackle the root cause. However I'm being pressurised to release this instrument and as such I was looking for a means of mitigation. I have devised a work-around that involves expressing channel A and B samples as uint16_t's. Channel A should be less than or equal to 0xFFFF, channel B should be greater than 0xFF; if either of these conditions are not met then I can drop the packet, and then reset and restart the spi dma.

I am able to stop the spi/dma but it won't reinitialise, meaning that when I restart the byte shift remains. The only way I can clear it is with a hard-reset?

Any thoughts please?

GDH