cancel
Showing results for 
Search instead for 
Did you mean: 

H7 migration, send SPI without using HAL

jean
Senior

Hello dear community!

I've migrated from F7 to H7, everything fine so far.

To save CPU time I don't want to use HAL for sending two SPI bytes.

My F7 transmit SPI code was very simple and perfectly working :

SPI6->DR = byte_0;
SPI6->DR = byte_1;

But on the H7, the same code doesn't work :

SPI6->TXDR = byte_0;
SPI6->TXDR = byte_1;

In both F7 and H7 projects, this is always working (but time-consuming) :

HAL_SPI_Transmit(&hspi6, const_cast<uint8_t*>(buffer), 2, 1000);

Do you know why bypassing HAL is not possible on the H7 ?

Thanks!

Jean

6 REPLIES 6
Pavel A.
Evangelist III

Perhaps because in H7 SPI data register is sensitive to the width of access. To write a byte, use 8-bit access.

Without HAL, use LL.

--pa

The 'H7 SPI is an overly complex beast.

The master at full duplex (or in any transmit-only mode) starts to communicate when the SPI

is enabled, the CSTART bit is set and the TxFIFO is not empty, or with the next write to

TxFIFO.

JW

*((volatile uint8_t *)&SPI6->TXDR) = byte_0; // 8-bit transaction on the data bus

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jean
Senior

Thanks a lot for your helpful answers!

I ended up by using the low level driver and it working!

LL_SPI_TransmitData8(SPI6, byte_0);
LL_SPI_TransmitData8(SPI6, byte_1);
LL_SPI_StartMasterTransfer(SPI6);

Okay so I looked it up... yep, no surprise, it's the CSTART bit:

__STATIC_INLINE void LL_SPI_StartMasterTransfer(SPI_TypeDef *SPIx)
{
  SET_BIT(SPIx->CR1, SPI_CR1_CSTART);
}

If you don't use transactions, i.e. you keep TSIZE=0, it's enough to set it once, at the beginning, and then the SPI should behave in the same way as in older models.

JW

PS. You may want to read AN5543. It's poorly written - CSTART is not mentioned there and TSIZE is mentioned only marginally - but at least there's a table with SPI versions in different STM32 models.

Pavel A.
Evangelist III

I'm struggling with this 'H7 SPI too. Learned to use these "transfers" - but was happy too soon...

After few "transfers", they start failing. The end of transfer flag SPI_SR_EOT fails to go up after a reasonable time, and I don't understand why.

Using the simplest mode: Motorola, mode 0, unit=byte, no CRC or auto NSS manipulations.

Noticed some errata item about the EOT but don't quite understand what it means.

Tried to disable & enable the SPI after every transfer, as they recommend - this only made situation worse.

So I'm going to get rid of "transfers", set SPI_CR2_TSIZE to 0 (another recommended workaround)...

--pa

P.S. The "transfer-less" mode seems to work well in my case.

This mode is demonstrated in "BSP" example for Nucleo H743 in the Cube H7.