Electronic – STM32 3-wire SPI MOSI high impedance

spistm32

I have a sensor with a 3-wire SSC interface, which is SPI compatible, but only has one bidirectional data line. Now I try to read this sensor (https://www.infineon.com/dgdl/Infineon-Angle_Sensor_TLE5012B-UM-v01_02-en-UM-v01_02-EN.pdf?fileId=5546d46146d18cb40146ec2eeae4633b) out and it sends me data back, but since MISO and MOSI are shorted together (as recommended from the chip manufacturer), the data is blocked after the 470Ohm data line resistance, because MOSI needs to go high-impedance after the command was sent.

So, how can I achieve a high impedance MOSI pin on a STM32F410CBU6? I could define it as an input, but then I need to re-init the SPI interface. Is there a simpler solution with less overhead?

Edit: I tried now to configure the SPI in the half-duplex mode. Since I use CubeMX, the configuration for this was easy, but I have no success yet. When the SPI is in the half-duplex mode, the SCK seems to have some small offset (maybe about 0.4V) and the MOSI line has also a strange behaviour. When I switch to the full-duplex mode, this behaviour is gone. What could cause this? I'm reading the sensor our likes this:

HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS, LOW);
spi_pos->Instance->CR1 |= (1<<BIDIOE);
HAL_SPI_Transmit(spi_pos,&command,1,1);
spi_pos->Instance->CR1 &= ~(1<<BIDIOE);
asm("nop"); // Since sensor needs some ns to switch to sender mode
HAL_SPI_Receive(spi_pos,data,size,1);
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS, HIGH);

The SPI is configured as follows:

  /* SPI2 parameter configuration*/
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 15;

MOSI Full Duplex:
D_FULL

SCK Full Duplex:
C_FULL

MOSI Half Duplex:
D_HALF

SCK Half Duplex:
S_HALF

Edit 2: Here are the settings in CubeMX:
enter image description here

enter image description here

Best Answer

The SPI peripheral of the STM32F4 is configureable for a single wire bidirectional half duplex transfer. In this mode the MOSI pin is used as a master or the MISO as a slave, no need to short the pins together on the STM32 side as only one is used.

For that you need to use the BIDIMODE (=1) bit in SPI_CR1. To set the data direction, you have to use the BIDIOE bit (1 = output, 0 = input) also in SPI_CR1.

So to send data you set BIDIOE to 1 and transfer all the data with writing to SPI_DR after that you reset BIDIOE to 0 and receive data with dummy writing something to SPI_DR (in order to generate the clock, which will tell the slave to send the data) and reading the received data from SPI_DR.

I haven't used this feature yet, and I do not use the peripheral libraries provided by ST, so I can't comment on their capability on using this feature.