2022-01-24 11:39 PM
Hello,
My design does not produce interrupts and I'm not sure why.
Goal:
SPI6 gets a 2MHz clock (external). For each clock the BDMA should take one 1 byte from a buffer (SRAM4, D3) and put it to the MISO. The BDMA runs double buffered => it should cycle M0/M1.
void MX_SPI6_Init(void)
{
/* USER CODE BEGIN SPI6_Init 0 */
/* USER CODE END SPI6_Init 0 */
/* USER CODE BEGIN SPI6_Init 1 */
/* USER CODE END SPI6_Init 1 */
hspi6.Instance = SPI6;
hspi6.Init.Mode = SPI_MODE_SLAVE;
hspi6.Init.Direction = SPI_DIRECTION_2LINES;
hspi6.Init.DataSize = SPI_DATASIZE_8BIT;
hspi6.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi6.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi6.Init.NSS = SPI_NSS_SOFT;
hspi6.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi6.Init.TIMode = SPI_TIMODE_DISABLE;
hspi6.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi6.Init.CRCPolynomial = 0x0;
hspi6.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hspi6.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi6.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi6.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi6.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi6.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi6.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi6.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi6.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi6.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi6) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI6_Init 2 */
/* USER CODE END SPI6_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(spiHandle->Instance==SPI6)
{
/* USER CODE BEGIN SPI6_MspInit 0 */
/* USER CODE END SPI6_MspInit 0 */
/* SPI6 clock enable */
__HAL_RCC_SPI6_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/**SPI6 GPIO Configuration
PG14 ------> SPI6_MOSI
PG13 ------> SPI6_SCK
PG12 ------> SPI6_MISO
*/
GPIO_InitStruct.Pin = SPI6_MOSI_Pin|SPI6_SCLK_Pin|SPI6_MISO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI6;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* SPI6 DMA Init */
/* SPI6_TX Init */
hdma_spi6_tx.Instance = BDMA_Channel0;
hdma_spi6_tx.Init.Request = BDMA_REQUEST_SPI6_TX;
hdma_spi6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi6_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi6_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi6_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_spi6_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi6_tx);
/* SPI6 interrupt Init */
HAL_NVIC_SetPriority(SPI6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI6_IRQn);
/* USER CODE BEGIN SPI6_MspInit 1 */
hdma_spi6_tx.XferCpltCallback = Dma_Trx_Spi_Transfer_Complete_M0;
hdma_spi6_tx.XferM1CpltCallback = Dma_Trx_Spi_Transfer_Complete_M1;
hdma_spi6_tx.XferErrorCallback = Dma_Trx_Spi_Transfer_ERROR;
/* USER CODE END SPI6_MspInit 1 */
}
void MX_BDMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_BDMA_CLK_ENABLE();
/* DMA interrupt init */
/* BDMA_Channel0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
}
Main.c
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
MX_GPIO_Init();
MX_BDMA_Init();
MX_SPI6_Init();
/* USER CODE BEGIN 2 */
start_SPI_BDMA_MULTIBUFFERED();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
volatile TrxTxFrameBuffer _gTxTrxCircBuffer[TRX_FRAME_COUNT] __attribute__((section(".sram4_d3"))); // circular TX buffer
void start_SPI_BDMA_MULTIBUFFERED(void)
{
/* start the dma */
if(HAL_DMAEx_MultiBufferStart_IT(&hdma_spi_tx, \
(uint32_t)&_gTxTrxCircBuffer[1].buf[0], \
(uint32_t)&hspi6->TXDR, \
(uint32_t)&_gTxTrxCircBuffer[1].buf[1], \
(uint32_t)TRX_FRAME_SIZE) != HAL_OK)
{
Error_Handler();
}
/* enable spi instance */
__HAL_SPI_ENABLE(&hspi6);
}
void BDMA_Channel0_IRQHandler(void)
{
/* USER CODE BEGIN BDMA_Channel0_IRQn 0 */
/* USER CODE END BDMA_Channel0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi6_tx);
/* USER CODE BEGIN BDMA_Channel0_IRQn 1 */
/* USER CODE END BDMA_Channel0_IRQn 1 */
}
There are no interrupts generated. If I change the code and manually start HAL_TransmitReceive_SPI it works.
Maybe I need to create a DMAMUX event interrupt? But as far as I understand this should be routed directly to the BDMA. And since I used and configured everything in CubeMX it should run without a problem, right?
2022-01-27 02:04 AM
Hi again,
I played around with different HAL_API to figure out its not generating anything.
SPI6 as slave.
HAL_SPI_Transmit_IT() is working
HAL_SPI_Transmit_DMA() is partially working.
HAL_DMAEx_MultiBufferStart_IT() not working at all.
2022-01-27 05:58 AM
Hi,
so. I fixed it.
The SPI (slave) was permanently feed with a running SCLK. The internal driver simply flagged UDR. This was the problem which caused it to directly stall.
The HAL_SPI_Transmit_IT was not affected. I assume it evaluates a little later and the buffer is send.
The HAL_SPI_Transmit_DMA just wont start, since the UDR is directly active.
Workaround is to clear the UDR bit before the HAL_DMA_IRQHandler() evaluates the interrupt.
void SPI6_IRQHandler(void)
{
/* USER CODE BEGIN SPI6_IRQn 0 */
__HAL_SPI_CLEAR_UDRFLAG(&hspi6);
/* USER CODE END SPI6_IRQn 0 */
HAL_SPI_IRQHandler(&hspi6);
}
2022-06-21 11:56 PM
Hello Deadbeef,
I'm working to an SPI communication between two STM32H743 boards, in particular, for the first ST I use SPI3 (slave) with DMA and for the second ST I use SPI6 (slave) with BDMA. Both the boards are clocked with an external fixed clock.
Now, for SPI3 I haven't any problems in fact, with oscilloscope, I see go out from the MISO data that I set, while with SPI6 I have only poblems in fact i don't see anything on MISO pin.
Could u share your .ioc and completed project in order to get ideas?
Thanks and regards.