cancel
Showing results for 
Search instead for 
Did you mean: 

Configure STM32CubeMX for SPI half-duplex communication

ndsmith34
Associate II

I have two peripherals on my board that I need to communicate with using 3-wire, half-duplex SPI. I have tried every combination of settings I can think of, but I am unable to communicate with either chip.

Here is my SPI1 init function:

static void MX_SPI1_Init(void)
{
 
  /* USER CODE BEGIN SPI1_Init 0 */
 
  /* USER CODE END SPI1_Init 0 */
 
  /* USER CODE BEGIN SPI1_Init 1 */
 
  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 0x0;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi1.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi1.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
 
  /* USER CODE END SPI1_Init 2 */
 
}

I am manually controlling the CS line with a GPIO. The transfer requires 24 clock cycles (1 R/W bit, 2 data length bits, 13 address bits, and 8 data bits). I can get the clock and transmit data to appear by either using the HAL_SPI_TransferReceive function:

0693W00000LzONKQA3.jpgor the HAL_SPI_Transfer function followed by HAL_SPI_Receive:

0693W00000LzONoQAN.jpgHowever, I cannot get either of the chips to transmit any of their data. I have tried all four different SPI modes. The clock speed is within the requirements of each chip. Is there something special I need to do for half-duplex mode other than configuring the MCU (STM32H755) as a half-duplex master?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

On the second photo, it's clear the STM32 is releasing control of the MOSI line. If the slave isn't driving it, then it's your slave that needs to be debugged. Look into the datasheet of the slave to determine why it's not working as expected. Signals look fine apart from the slave not taking control, but that's not an STM32 code issue. Perhaps the hardware wiring isn't as it should be.

> HAL_SPI_TransferReceive 

Presumably you mean HAL_SPI_TransmitReceive. This function is not compatible with 3-wire mode, as only the master or the slave can control the data line, not both at once. Trying to use in 3-wire mode will fail at the following assert if assertions are enabled.

  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));

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

View solution in original post

2 REPLIES 2
TDK
Guru

On the second photo, it's clear the STM32 is releasing control of the MOSI line. If the slave isn't driving it, then it's your slave that needs to be debugged. Look into the datasheet of the slave to determine why it's not working as expected. Signals look fine apart from the slave not taking control, but that's not an STM32 code issue. Perhaps the hardware wiring isn't as it should be.

> HAL_SPI_TransferReceive 

Presumably you mean HAL_SPI_TransmitReceive. This function is not compatible with 3-wire mode, as only the master or the slave can control the data line, not both at once. Trying to use in 3-wire mode will fail at the following assert if assertions are enabled.

  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));

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

Thank you for the direction to use the separate TX and RX functions.

The issue was I was not correctly controlling the RESET and CS lines for the chip. I can read the registers now. Thank you.