Skip to main content
ESale.2
Associate II
December 28, 2020
Question

SPI DMA variable data length

  • December 28, 2020
  • 7 replies
  • 4095 views

Hi,

I'm working with stm32H743zi (Nucleo-144) ,

I have a device that transmitting data via SPI to my stm32H7, the problem is that the device sending data with a variable length that I have no idea about it and there is no way to receive the length before .. the only thing that I know is the maximum data length that could be received

so I decided to work with the CS porting it to an EXTI (interrupt), and according to that I will turn on/off the dma receiving

I will define a static buffer with the maximum data size , then for every interrupt I will use the two commands:

HAL_SPI_DMAStop(&hspi1)

//TODO: need to memcpy the buffer to another one

//start a new recieving

HAL_SPI_Receive_DMA(&hspi1, mybuff, maximum_size)

the question is, how I could pull the data from the DMA buffer after DMA stop and I need to know the total count of bytes that have been used in the given buffer

I appreciate your suggestions ...

This topic has been closed for replies.

7 replies

TDK
December 28, 2020

> how I could pull the data from the DMA buffer after DMA stop and I need to know the total count of bytes that have been used in the given buffer

Well, the data is still in memory, you just pull it from the buffer.

The amount of data in the buffer is (maximum_size - NDTR) where NDTR is in the DMA stream's NDTR register.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ESale.2
ESale.2Author
Associate II
December 28, 2020

Thanks you for your reply,

I tried to reach the NDTR without success, can you please write down a piece of code so it will help me to understand your suggestion ?

TDK
December 28, 2020

hspi->hdmarx->Instance->NDTR

"If you feel a post has answered your question, please click ""Accept as Solution""."
ESale.2
ESale.2Author
Associate II
December 28, 2020

it wouldn't compile when i do:

uint16_t data_count = max_data_size - hspi1.hdmarx->Instance->NDTR;

waclawek.jan
Super User
December 28, 2020

Which SPI and DMA?

In CubeH7, as there are 3 different DMA types, Instance in DMA_HandleTypeDef is void*

I don't Cube so I don't know what's the official stance on this, but probably you have to typecast to the appropriate DMA type.

[EDIT] Inspecting CubeH7 I stumbled upon __HAL_DMA_GET_COUNTER() https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h#L1166

which appears to be the incantation you are looking for.

JW

ESale.2
ESale.2Author
Associate II
December 29, 2020

it's SPI1 DMA1_Stream0

I tried to use the __HAL_DMA_GET_COUNTER(), from some reason the cpu crashes and entering a fault handler, is there a specific configuration that i need to do before using it ?

Thanks

Ebraheem

waclawek.jan
Super User
December 29, 2020

Why do you think the crash is related to use of __HAL_DMA_GET_COUNTER()? Did you trace back the error from the fault handler? Did you single-step the code to see the instruction and registers which caused the fault?

You can also use DMA1_Stream0->NDTR directly, if you are sure the DMA/stream won't change in the future.

JW

ESale.2
ESale.2Author
Associate II
December 29, 2020

when running in debug mode , i crash after executing the line that contains __HAL_DMA_GET_COUNTER()

this is my code:

uint32_t total = MAX_BUF_SIZE - __HAL_DMA_GET_COUNTER(hspi1.hdmarx);

when executing this command the program point to the void HardFault_Handler(void) loop ..

waclawek.jan
Super User
December 29, 2020

> uint32_t total = MAX_BUF_SIZE - __HAL_DMA_GET_COUNTER(hspi1.hdmarx);

As I've said, I don't use Cube, but you are probably not supposed to __HAL_DMA_GET_COUNTER(hspi1.hdmarx); rather, __HAL_DMA_GET_COUNTER(hspi1.hdmarx->Instance)

> i tried also the DMA1_Stream0->NDTR , it always return 0 !

Maybe you call some Cube component which clears it.

Are you sure you are using DMA1_Stream0?

Try to read out NDTR just after you enabled the DMA, before receiving any data.

Cube is simply not intended for anything out of "usual"; and what's "usual" is given by Cube's authors. They deem "usual" to transfer a known number of data only.

JW

ESale.2
ESale.2Author
Associate II
December 30, 2020

i found something in UART : https://www.programmersought.com/article/6663824121/

any ideas how i can convert this to SPI ?