Skip to main content
JohnsAby
Associate III
November 26, 2021
Solved

STM32F4 SPI-DMA with daisy chain not working. Problem with NSS signal.

  • November 26, 2021
  • 1 reply
  • 1323 views

I have done an SPI transfer only with DMA and working fine, but when I need to do a daisy chain configuration its not working. I am suspecting the NSS signal.

below is SPI configuration

#define SPIx_Mode SPI_MODE_MASTER
#define SPIx_Direction SPI_DIRECTION_2LINES
#define SPIx_DataSize SPI_DATASIZE_16BIT
#define SPIx_ClkPolarity SPI_POLARITY_LOW
#define SPIx_ClkPhase SPI_PHASE_1EDGE
#define SPIx_Nss SPI_NSS_SOFT
#define SPIx_BaudRatePrescaler SPI_BAUDRATEPRESCALER_4
#define SPIx_FirstBit SPI_FIRSTBIT_MSB
#define SPIx_TiMode SPI_TIMODE_ENABLE
#define SPIx_CrcCalc SPI_CRCCALCULATION_DISABLE
#define SPIx_CrcPolynomial 0

Below is DMA configuration

(DMA_MINC_DISABLE is used in case of single transfer)

 hdma_tx.Instance = SPIx_TX_DMA_STREAM;
 hdma_tx.Init.Channel = SPIx_TX_DMA_CHANNEL;
 hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_tx.Init.MemInc = DMA_MINC_ENABLE;//DMA_MINC_DISABLE;
 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_tx.Init.Mode = DMA_NORMAL;
 hdma_tx.Init.Priority = DMA_PRIORITY_HIGH;
 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;

TI mode is enabled.

 #define SPIx_NSS_Mode GPIO_MODE_AF_PP
 #define SPIx_NSS_Pull GPIO_PULLUP

Without Daisy, waveform(below)

0693W00000GYzeYQAT.png 

With daisy waveform(below)

0693W00000GYzZZQA1.pngin the above picture NSS is coming in between.

 uInt16 aTxBuffer[4] = {0xC333, 0xC666, 0xC999, 0xCCCC}; // sample data
 
 HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
 spi5_dataTransfer(aTxBuffer);
 HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
 
 
 
void spi5_dataTransfer(uint16_t *TxBuffer)
{
// HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
 HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, 4u);
 while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
 // After successful transfer NSS is put high from HAL_SPI_TxCpltCallback. 
}

please help to achieve like below

0693W00000GYzloQAD.png

This topic has been closed for replies.
Best answer by TDK

NSS is not a CS signal. In TI mode, it is high for the first byte in a transfer. Since your data size is 16 bits, it is high for the first bit, then low for the remaining 15 bits. This isn't what you want.

Set up the SYNC signal as a GPIO output and control it manually. Set it low before each transfer and high after.

1 reply

TDK
TDKBest answer
November 26, 2021

NSS is not a CS signal. In TI mode, it is high for the first byte in a transfer. Since your data size is 16 bits, it is high for the first bit, then low for the remaining 15 bits. This isn't what you want.

Set up the SYNC signal as a GPIO output and control it manually. Set it low before each transfer and high after.

"If you feel a post has answered your question, please click ""Accept as Solution""."
JohnsAby
JohnsAbyAuthor
Associate III
November 26, 2021

Hi TDK,

Thanks for the fast response.

Disabled TI mode and GPIO is used to control the NSS signal (manually).

This solved my issue.