cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 SPI DMA is not working, HAL_SPI_STATE_BUSY_TX_RX state. Cache and MPU are disabled.

JJilg.1
Associate II

I am trying to use SPI and DMA in a STM32H7, but it is not worling. The spi handler goes to "HAL_SPI_STATE_BUSY_TX_RX" state as soon as i call the function "HAL_SPI_TransmitReceive_DMA" and it does not do anything, it does not even generate the clock signal. The CPU IChache and DCache are disabled and MPU is not used. Besides, i have placed all the memory sections in "RAM_D1" as you can see in the linker attached.

I have tried placing the DMA buffers in another memory section and place this in "RAM_D2". Besides, i have also tried aligning these buffers with "ALIGN_32BYTES", and using different DMA streams but the result is always the same.

0693W00000Ho84EQAR.png0693W00000Ho84YQAR.pngI would really appreciate any help, i am really stuck into this.

4 REPLIES 4
TDK
Guru

Probably a bug in your code, so show it. Verify DMA is initialized prior to SPI.

Alternatively, there are SPI examples in the repository you can go off of.

No need to store _user_heap_stack or bss in FLASH, although I don't think that's the issue.

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

SPI initialization:

 hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 0x0;
  hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
  hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }

DMA initialization:

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
  /* DMA1_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
  /* DMA1_Stream4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
  /* DMA1_Stream5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
  /* DMA2_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);

Call to transmit/receive through DMA:

uint8_t tx_block[20480+1] = {0};
void SPI_StartGetBlock(SPI_HandleTypeDef *spiHandler, char *block, uint32_t size)
{
	HAL_StatusTypeDef status;
	uint8_t retry;
	const uint16_t attempts = 10;
	if (size > 20480) return;
	do
	{
		status = HAL_SPI_TransmitReceive_DMA(spiHandler, tx_block, block, size);
		retry++;
		if (retry>attempts) {
			return;
		}
	} while (status!=HAL_OK);
	return;
}

Buffer where RX info would be stored, defined as global:

uint8_t CAMERA_photoBlock[CAMERA_MODEL_PHOTO_BLOCK_SIZE];

DMA interrupts in stm32h7xx_it file, that are never executed:

/**
  * @brief This function handles DMA1 stream3 global interrupt.
  */
void DMA1_Stream3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
#ifdef CAMERA_ARDUCAM
	CAMERA_RxFromCameraComplete();
#endif
  /* USER CODE END DMA1_Stream3_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_spi2_rx);
  /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
 
  /* USER CODE END DMA1_Stream3_IRQn 1 */
}

TDK
Guru

I still don't think the error is within the code you've presented.

Is DMA initialized before SPI?

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

Sorry for the late. In the end i had to change it in order not to use DMA and i could not test it more time. I did not find the issue. Thanks for the help