cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA variable data length

ESale.2
Associate II

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 ...

11 REPLIES 11
TDK
Guru

> 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".

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
Guru

hspi->hdmarx->Instance->NDTR

If you feel a post has answered your question, please click "Accept as Solution".

it wouldn't compile when i do:

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

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
Associate II

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

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

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 ..

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