2022-06-02 12:44 PM
STM32H7 SPI DMA not working
Hi. I have stm32H745 nucleo board, in my project i want send data from MOSI via DMA (i did the same on old F4 discovery correctly).
PE_14, SPI4 , DMA2_stream3, DMUX11=84 (for tx spi4)
In project i need to send data (fb[][]) then generated interrupt. For exam for correct work the IRQ_handler inside interrupt function i switched PG_9.
It did not work, dma don't send data, there no switching PG_9 inside handler function.
Could anybody help me ?
Me code bellow
Function for SPI_DMA initialisation:
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
SPI_HandleTypeDef SpiHandle;
//static
DMA_HandleTypeDef hdma_tx;
#define SPIx SPI4
#define SPIx_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define SPIx_CLK_ENABLE() __HAL_RCC_SPI4_CLK_ENABLE()
#define DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
SPIx_MOSI_GPIO_CLK_ENABLE();
/* Enable SPI1 clock */
SPIx_CLK_ENABLE();
/* Enable DMA clock */
DMAx_CLK_ENABLE();
// Common configuration for all channels
GPIO_InitStructure.Pin = GPIO_PIN_14 ;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF5_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
/*##-3- Configure the DMA ##################################################*/
/* Configure the DMA handler for Transmission process */
hdma_tx.Instance = DMA2_Stream3; // SPI4 maybe?
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4;
hdma_tx.Init.Request = DMA_REQUEST_SPI4_TX;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_tx);
/* Associate the initialized DMA handle to the the SPI handle */
//__HAL_LINKDMA(SPI4, hdmatx, hdma_tx); // navisho ???
/*##-1- Configure the SPI peripheral #######################################*/
/* Set the SPI parameters */
SpiHandle.Instance = SPI4;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; // use 4 for 400 pixels, 2 for 800 pixels
SpiHandle.Init.Direction = SPI_DIRECTION_1LINE;
SpiHandle.Init.CLKPhase = SPI_PHASE_2EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
SpiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommanded setting to avoid glitches */
HAL_SPI_Init(&SpiHandle);
/*##-4- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt (SPI4_TX) */
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
SPI4->CR1 &= ~SPI_CR1_SPE;
// SPI4->CR2 = 7;
DMA_STREAM->CR&= ~DMA_SxCR_EN; // clear the EN bit to disable the stream
DMA_STREAM->PAR = (uint32_t) &(SPI4->TXDR);
DMA_STREAM->NDTR = VTOTAL; // set number of bytes to transfer
DMA_STREAM->M0AR = (u32) &fb[0][0]; // set start of frame buffer
DMA_STREAM->CR|=DMA_SxCR_CIRC | DMA_SxCR_TCIE;
DMAMUX1_Channel11->CCR = 84; //SPI4_TX vs DMA2_Stream3;
DMAMUX1_Channel11->CCR |=DMAMUX_CxCR_EGE ; //| DMAMUX_SPI1_RX_ID;
//SPI4->IER |= SPI_IER_TXPIE;
SPI4->CFG1 |= SPI_CFG1_TXDMAEN;
//SPI4->CR1 |= SPI_CR1_CSTART;
SPI4->CR1 |= SPI_CR1_SPE;
DMA_STREAM->CR|= DMA_SxCR_EN; // set the EN bit to disable the stream
// DMAMUX1 channels 8 to 15 are connected to DMA2 channels 0 to 7
// 84 spi4_tx_dma
// DMA1_Stream_x -> DMAMUX1_Channel_x
//DMA2_Stream_x -> DMAMUX1_Channel_(x+8)
}
Function for Interrupt
void DMA2_Stream3_IRQHandler(void)
{
VIDEO_DMA->LIFCR = DMA_LIFCR_CTCIF3; // clear the transfer complete interrupt flag
DMA_STREAM->CR &= ~DMA_SxCR_EN; // clear the EN bit to disable the stream
DMA_STREAM->NDTR = VTOTAL; // reload the number of bytes to send
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_9);
}
2022-06-03 02:34 AM
Hello @AAnt.1 and welcome to the Community :)
Perhaps this FAQ will help: DMA is not working on STM32H7 devices
Check the DMA status for errors.
You can check SPI examples in the STM32CubeH7 MCU package.
Imen
2022-06-03 02:26 PM
Hi @Imen DAHMEN
phanks for interst to my problem, but your topic i have been read in past.
It don't help me.
I use two core M7 and M4. M4 core (D2 domain) i use for transmit data trouth MOSI PE_14 DMA_2
M7 core i don't use with DMA.
When transaction will finish i need to generate interrupt - i didn't saw switching PG_9 inside interrupt function. DMA transaction don't start.
M4 core i use with SRAM1, SRAM2, SRAM3. In Keil i wrote IRAM1 addres 0x10 000 000 size 0x48000 - it don't help me. And i probed addres 0x30 000 000 same size - zero rezult.
I wrote my code upper, may be i got mistake with registers for SPI or DMA start ?
2022-06-19 04:35 AM
Hi to all! My old code:
https://community.st.com/s/question/0D53W00001atD9zSAE/stm32h7-spi-dma-not-working
I write modernized code - i could get only done function of IRQ_Handler, insite function LED switched, PD9 switched . That means - i can enter inside IRQ_handler and handler work, not stoped inside, but don't have any signal on MOSI SPI PIN .....
Me modernized code
function main.c
DMA_HandleTypeDef hdma_tx;
SPI_HandleTypeDef SpiHandle;
#define TBS0 11
uint8_t TBuf0[TBS0]={0,1,2,3,4,5,6,7,8,9,11};
SPI_Configuration( );
.....
while (1)
{
HAL_DMA_Start_IT(&hdma_tx, *TBuf0,(uint32_t) &(SPI4->TXDR),TBS0);
}
function for SPI_DMA init
#define VIDEO_DMA DMA2
#define DMA_STREAM DMA2_Stream3
#define DMA_CHANNEL DMA_Channel_3
void SPI_Configuration( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
// RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN); // Enable the SRAM
// __HAL_RCC_D2SRAM1_CLK_ENABLE();
// __HAL_RCC_D2SRAM2_CLK_ENABLE();
// __HAL_RCC_D2SRAM3_CLK_ENABLE();
#define SPI4_FORCE_RESET() __HAL_RCC_SPI4_FORCE_RESET()
#define SPI4_RELEASE_RESET() __HAL_RCC_SPI4_RELEASE_RESET()
#define SPIx SPI4
#define SPIx_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define SPIx_CLK_ENABLE() __HAL_RCC_SPI4_CLK_ENABLE()
#define DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
SPI4_FORCE_RESET();
SPI4_RELEASE_RESET();
HAL_DMA_DeInit(&hdma_tx);
// ##-1- Enable peripherals and GPIO Clocks #################################
// Enable GPIO TX/RX clock
SPIx_MOSI_GPIO_CLK_ENABLE();
// Enable SPI1 clock
SPIx_CLK_ENABLE();
// Enable DMA clock
DMAx_CLK_ENABLE();
// Common configuration for all channels
GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_12; // PE12 SPI SCK
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF5_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
// ##-3- Configure the DMA
// Configure the DMA handler for Transmission process
hdma_tx.Instance = DMA_STREAM; // SPI4 maybe?
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_tx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
hdma_tx.Init.Request = DMA_REQUEST_SPI4_TX;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_CIRCULAR; //DMA_NORMAL; // ?????
hdma_tx.Init.Priority = DMA_PRIORITY_HIGH; // ????
HAL_DMA_Init(&hdma_tx);
// ##-1- Configure the SPI peripheral
// Set the SPI parameters
SpiHandle.Instance = SPI4;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
SpiHandle.Init.CLKPhase = SPI_PHASE_2EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
SpiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
HAL_SPI_Init(&SpiHandle);
// ##-4- Configure the NVIC for DMA
// NVIC configuration for DMA transfer complete interrupt (SPI4_TX)
HAL_NVIC_SetPriority(DMA_INTERRUPT, 1, 1); //DMA2_Stream3_IRQn
HAL_NVIC_EnableIRQ(DMA_INTERRUPT); // DMA2_Stream3_IRQn
}
Function for INTERRUPT and switching PIN inside
void DMA2_Stream3_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_tx);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // LD1 blinky
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9); // PD9 blinky
}
If i understand, DMA start to work, because interrupt handler worked, but DMA don'nt send any signal to MOSI PE14 pin.....
Best regards.