2022-04-28 01:55 PM
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:
or the HAL_SPI_Transfer function followed by HAL_SPI_Receive:
However, 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?
Solved! Go to Solution.
2022-04-28 05:07 PM
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));
2022-04-28 05:07 PM
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));
2022-04-29 11:29 AM
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.