2019-02-04 06:44 AM
Hallo,
i dont unterstand how i can receive data in Spi Half-Duplex-Mode.
My used Controller is STM32F446RET.
STM32CubeMX is configured as follow
Thats my Code:
HAL_GPIO_WritePin(CS_GPIOxLib, CS_GPIO_PinLib, GPIO_PIN_RESET);
status = HAL_SPI_Transmit(hspiLib, (uint8_t*)®ister_Address_calculation, 1, 10000);
status = HAL_SPI_Receive(hspiLib, (uint8_t*)Value, 1, 10000);
if(status != HAL_OK)
{
Error_Handler();
}
HAL_GPIO_WritePin(CS_GPIOxLib, CS_GPIO_PinLib, GPIO_PIN_SET);
A Logic Analyser shows that there are same Errors on the SPI when i try to receive.
But when i changed
hspi3.Init.Direction = SPI_DIRECTION_1LINE;
to
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
the SPI looks better:
Is this wrong implemented by STM32Cube?
When i changed my Code back to
hspi3.Init.Direction = SPI_DIRECTION_1LINE;
&
HAL_GPIO_WritePin(CS_GPIOxLib, CS_GPIO_PinLib, GPIO_PIN_RESET);
status = HAL_SPI_TransmitReceive(hspiLib, (uint8_t*)®ister_Address_calculation, (uint8_t*)Value, 1, 10000);
if(status != HAL_OK)
{
Error_Handler();
}
HAL_GPIO_WritePin(CS_GPIOxLib, CS_GPIO_PinLib, GPIO_PIN_SET);
the Function HAL_SPI_TransmitReceive goes in TIMEOUT.
When i changed SPI Direction to
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
i can see, that STM32 dont spend clocks for receive
Is there anything wrong in my code?
Is there an example code?
2019-02-04 08:25 AM
>>Is there an example code?
grep through the HAL example trees for the F4, and perhaps others.
2019-02-04 11:53 AM
I would advise to use SPI 4 wires mode with MISO and MOSI shorted outside (of as some SPI IP versions have MISO swap MOSI) to make half duplex mode SPI in 3 wire mode.
Still you'll use DMA for TX (how many clocks to send) and RX (receiving data and triggering transfer complete interrupt). The monodirectional may make SCK clock generation more time/latency stressing.
2019-02-04 04:59 PM
If set to master and half-duplex (SPI_CR1.BIDIMODE=1), as soon as turned to Rx (SPI_CR1.BIDIOE=0), SPI starts to automatically output clocks (and shift in data) and does not stop until turned to Tx again. It means, you have to very carefully time the direction turns. Cube/HAL has probably no provision for this - it's one of the many specialty uses of STM32 hardware, and Cube/HAL covers inevitably only the most common modes of use.
As Clive said, look at the examples in Cube. For example, at the STM32L476G-DISCO, there's a magnetometer, LSM303C, which requires bidirectional SPI communication, and CubeL4 handles it in [CubeL4]\Drivers\BSP\STM32L476G-Discovery\stm32l476g_discovery.c , for example:
uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr)
{
MAGNETO_CS_LOW();
__SPI_DIRECTION_1LINE_TX(&SpiHandle);
SPIx_Write(RegisterAddr | 0x80);
__SPI_DIRECTION_1LINE_RX(&SpiHandle);
uint8_t val = SPIx_Read();
MAGNETO_CS_HIGH();
return val;
}
static uint8_t SPIx_Read(void)
{
uint8_t receivedbyte;
__HAL_SPI_ENABLE(&SpiHandle);
__DSB();
__DSB();
__DSB();
__DSB();
__DSB();
__DSB();
__DSB();
__DSB();
__HAL_SPI_DISABLE(&SpiHandle);
while((SpiHandle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
/* read the received data */
receivedbyte = *(__IO uint8_t *)&SpiHandle.Instance->DR;
/* Wait for the BSY flag reset */
while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);
return receivedbyte;
}
Needless to say that interrupts have to be disabled around such code.
I don't say I like this code. And I don't Cube.
If you don't necessarily need things to go very fast, and/or you don't intend to dig deep, you may be better off bit-banging the SPI.
JW
2020-08-26 11:14 PM
Why 4 wires? That's wastes 1 pin and adds 1 extra resistor.
2022-03-08 03:48 AM
same problem i am facing i read data but with garbage value also comming.