cancel
Showing results for 
Search instead for 
Did you mean: 

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

JohnsAby
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

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".

View solution in original post

2 REPLIES 2
TDK
Guru

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".

Hi TDK,

Thanks for the fast response.

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

This solved my issue.