Receiving a burts of data from SPI using DMA
Hi,
I am using an STM32f407VGT MCU and I am trying to receive a burst of data of 112 bytes from SPI1 and storing it in an array buffer, initially set with all its elements to 0.
According to the RM0090 TRF this should be easily done with the DMA, but unfortunately I cannot see the data as correctly stored into the memory.
The code I am using to configure the DMA and the SPI is the following:
#include "stm32f4xx.h"
#include "stm32f4xx_ll_cortex.h"
#include "stm32f4xx_ll_bus.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_rcc.h"
#include "stm32f4xx_ll_usart.h"
#include "stm32f4xx_ll_gpio.h"
#include "stm32f4xx_ll_system.h"
#include "stm32f4xx_ll_pwr.h"
#include "stm32f4xx_ll_spi.h"
#include "stm32f4xx_ll_tim.h"
#include "stm32f4xx_ll_utils.h"
#define SPI1_MOSI LL_GPIO_PIN_7
#define SPI1_MISO LL_GPIO_PIN_6
#define SPI1_SCLK LL_GPIO_PIN_5
#define SPI1_NSS LL_GPIO_PIN_4
uint8_t data_buffer[28][5] = {{0}};
void init_DMA(\
DMA_TypeDef *DMAx, \
uint32_t channel,
uint32_t dma_stream,
uint32_t src_address, \
uint32_t dst_address, \
uint32_t direction, \
uint32_t mode, \
uint32_t periph_inc_mode, \
uint32_t mem_inc_mode, \
uint32_t src_data_size, \
uint32_t dst_data_size, \
uint32_t nb_data, \
uint32_t priority, \
uint32_t fifo_mode, \
uint32_t fifo_threshold, \
uint32_t mem_burst, \
uint32_t periph_burst)
{
LL_DMA_InitTypeDef dma_init = {0};
LL_DMA_StructInit(&dma_init);
dma_init.Channel = channel;
dma_init.PeriphOrM2MSrcAddress = src_address;
dma_init.MemoryOrM2MDstAddress = dst_address;
dma_init.Direction = direction;
dma_init.Mode = mode;
dma_init.PeriphOrM2MSrcIncMode = periph_inc_mode;
dma_init.MemoryOrM2MDstIncMode = mem_inc_mode;
dma_init.PeriphOrM2MSrcDataSize = src_data_size;
dma_init.MemoryOrM2MDstDataSize = dst_data_size;
dma_init.NbData = nb_data;
dma_init.Priority = priority;
dma_init.FIFOMode = fifo_mode;
dma_init.FIFOThreshold = fifo_threshold;
dma_init.MemBurst = mem_burst;
dma_init.PeriphBurst = periph_burst;
LL_DMA_EnableIT_TE(DMAx, dma_stream);
LL_DMA_EnableIT_TC(DMAx, dma_stream);
LL_DMA_Init(DMAx, dma_stream, &dma_init);
LL_DMA_EnableStream(DMA2, dma_stream);
}
void DMA2_Stream0_IRQHandler(void)
{
if(LL_DMA_IsActiveFlag_TC0(DMA2))
LL_DMA_ClearFlag_TC0(DMA2);
}
void init_SPI(
SPI_TypeDef *SPIx, \
uint32_t transfer_dir, \
uint32_t mode, \
uint32_t data_width, \
uint32_t clock_pol, \
uint32_t clock_phase, \
uint32_t nss, \
uint32_t baudrate, \
uint32_t bit_order, \
uint32_t crc_calc, \
uint32_t crc_poly)
{
LL_SPI_InitTypeDef spi_init = {0};
if(SPIx == SPI1)
{
init_GPIO(
GPIOA, \
SPI1_MOSI | SPI1_MISO | SPI1_SCLK | SPI1_NSS, \
LL_GPIO_MODE_ALTERNATE, \
LL_GPIO_SPEED_FREQ_VERY_HIGH, \
LL_GPIO_OUTPUT_PUSHPULL, \
LL_GPIO_PULL_UP, \
LL_GPIO_AF_5);
}
LL_SPI_Disable(SPIx);
LL_I2S_Disable(SPIx);
spi_init.TransferDirection = transfer_dir;
spi_init.Mode = mode;
spi_init.DataWidth = data_width;
spi_init.ClockPolarity = clock_pol;
spi_init.ClockPhase = clock_phase;
spi_init.NSS = nss;
spi_init.BaudRate = baudrate;
spi_init.BitOrder = bit_order;
spi_init.CRCCalculation = crc_calc;
spi_init.CRCPoly = crc_poly;
if(SPIx == SPI1)
{
LL_SPI_EnableDMAReq_RX(SPI1);
}
LL_SPI_Init(SPIx, &spi_init);
LL_SPI_Enable(SPIx);
}
int main(void)
{
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA | LL_AHB1_GRP1_PERIPH_GPIOB | LL_AHB1_GRP1_PERIPH_GPIOC | LL_AHB1_GRP1_PERIPH_GPIOD | LL_AHB1_GRP1_PERIPH_DMA1 | LL_AHB1_GRP1_PERIPH_DMA2);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1 | LL_APB2_GRP1_PERIPH_SPI1);
// DMA2 Channel 3 Stream 0 is attached to SPI1_RX
init_DMA(DMA2, \
LL_DMA_CHANNEL_3, LL_DMA_STREAM_0, LL_SPI_DMA_GetRegAddr(SPI1), \
(uint32_t) &data_buffer[0][0], LL_DMA_DIRECTION_PERIPH_TO_MEMORY, LL_DMA_MODE_CIRCULAR, \
LL_DMA_PERIPH_NOINCREMENT, LL_DMA_MEMORY_NOINCREMENT, LL_DMA_PDATAALIGN_BYTE, \
LL_DMA_MDATAALIGN_BYTE, 140, LL_DMA_PRIORITY_VERYHIGH, \
LL_DMA_FIFOMODE_ENABLE, LL_DMA_FIFOTHRESHOLD_1_4, LL_DMA_MBURST_SINGLE, \
LL_DMA_PBURST_SINGLE);
init_SPI(SPI1, LL_SPI_SIMPLEX_RX, LL_SPI_MODE_SLAVE, LL_SPI_DATAWIDTH_8BIT, \
LL_SPI_POLARITY_LOW, LL_SPI_PHASE_1EDGE, LL_SPI_NSS_HARD_INPUT, LL_SPI_BAUDRATEPRESCALER_DIV2, \
LL_SPI_MSB_FIRST, LL_SPI_CRCCALCULATION_DISABLE, 10);
NVIC_EnableIRQ(DMA2_Stream0_IRQn);
while(1)
{
;
}
}but every time I check the content of data_buffer it is always all to 0, like nothing has been stored into it.
So what am I doing wrong here ?
Any hint ?
Thanks in advance.
s.
