cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746 DMA SPI's Clock is incoherent

Jinhui Lin
Associate II
Posted on August 07, 2017 at 16:34

As the title says, the clock's wave is as below for DMA SPI2's Clock:

0690X00000607ueQAA.png

My DMA SPI Setting is as below with red color:

 if(hspi->Instance==SPI2)

{

/* USER CODE BEGIN SPI2_MspInit 0 */

/* USER CODE END SPI2_MspInit 0 */

/* Peripheral clock enable */

__HAL_RCC_SPI2_CLK_ENABLE();

/**SPI2 GPIO Configuration

PA9 ------> SPI2_SCK

PC3 ------> SPI2_MOSI

PB14 ------> SPI2_MISO

*/

GPIO_InitStruct.Pin = GPIO_PIN_9;

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_SPI2;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_3;

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_SPI2;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_14;

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_SPI2;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral DMA init*/

hdma_spi2_rx.Instance = DMA1_Stream3;

hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi2_rx.Init.Mode = DMA_NORMAL;

hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW;

hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;

hdma_spi2_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

hdma_spi2_rx.Init.MemBurst = DMA_MBURST_SINGLE;

hdma_spi2_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;

if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)

{

Error_Handler();

}

__HAL_LINKDMA(hspi,hdmarx,hdma_spi2_rx);

hdma_spi2_tx.Instance = DMA1_Stream4;

hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi2_tx.Init.Mode = DMA_NORMAL;

hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;

hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)

{

Error_Handler();

}

__HAL_LINKDMA(hspi,hdmatx,hdma_spi2_tx);

/* USER CODE BEGIN SPI2_MspInit 1 */

/* USER CODE END SPI2_MspInit 1 */

}

If there is anything wrong with my setting?

So is there any method to remove the  incoherent SPI DMA clock.

#dma #spi #stm32f7 #clock-incoherent #incoherent
4 REPLIES 4
Posted on August 07, 2017 at 18:41

>> incoherent 

Discontinuous?

Make sure the data widths match.

TX side drives clock in Master mode, review Tx DMA, use FIFO and high priority settings?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
Posted on August 07, 2017 at 19:50

I would advise to check SPI 4 wires example code in Cube from the nucleo or discovery of an STM32F7.

When using SPI, the DMA TX and corresponding block size will drive the clock. Maybe the DMA is transferring blocks of 1 byte, or, because the time scale is unclear, other higher priority tasks/DMA are running in the background (unlikely). Make DMA priorities to be sure. You send a byte, you later get a byte.

Jinhui Lin
Associate II
Posted on August 08, 2017 at 05:01

I fix the issue by modifying SPI2's TIMode setting from:(disable -> enable)

/* SPI2 init function */

static void MX_SPI2_Init(void)

{

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_2;

hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi2.Init.CRCPolynomial = 7;

hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

if (HAL_SPI_Init(&hspi2) != HAL_OK)

{

Error_Handler();

}

}

0690X00000607Y3QAI.png

to 

hspi2.Init.TIMode = SPI_TIMODE_ENABLE;0690X00000607guQAA.png

The Clock is continuous, but the clock number is not correct and data is also changed.

So Why the gap between byte of clock disappeared after I changed to TI Mode???

Jinhui Lin
Associate II
Posted on August 08, 2017 at 09:01

The right way to fix this issue is to disable NSSPMode as below:

/* SPI2 init function */

static void MX_SPI2_Init(void)

{

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_2;

hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi2.Init.CRCPolynomial = 7;

hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

if (HAL_SPI_Init(&hspi2) != HAL_OK)

{

Error_Handler();

}

}