2024-07-08 07:14 AM
1. CubeMX only allows HAL or LL for SPI and other peripherals. STM32C031C6 itself provides the good SPI clock rate.
SPI LL API function only allows two-byte R/W.. The slave STPM34 Meter IC requires 4-Byte SPI R/W. So we have to choose HAL SPI API calls, such as HAL_SPI_TransmitReceive().
However HAL introduces a big delay (15 us or more) between two consecutive HAL SPI-API calls. We need 6 SPI-API calls within 128us for our application, This big delay inserted by HAL makes it impossible. .
2. The only solution is to write the register low level SPI R/W functions. Is it possible to write it under the current CubeMx IDE compiler for STM32C031C6? Could you provide us the solutions?
Thanks,
Rong
Solved! Go to Solution.
2024-07-08 03:48 PM
Thanks. You are correct -
The register based low level SPI drive has been using for many years, it is still the best. HAL and LL are only good for the initialization. Both, especially HAL, adds the overhead (delay) between two consecutive API calls. It is a show-stop for our timing critical application. It was m first time of using HAL and LL - not a good experience. Thanks again.
2024-07-09 12:44 AM
Hi @RongShengWang ,
I see that you'll be trying the direct access to registers. Let us know the results.
In LL side, you can try 4 calls of LL_SPI_TransmitData8() or 2 calls of LL_SPI_TransmitData16().
Based on what you said previously, you made tests with HAL_SPI_TransmitReceive() which is introducing delays. I suggest you make the trial with LL.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-07-09 01:43 AM
@RongShengWang wrote:The register based low level SPI drive has been using for many years, it is still the best (sic). .
So what's stopping you from doing it now?
The registers & the peripheral operation are all described in the RM - so just code it direct from there...
2024-07-09 04:32 AM
I am testing the register based SPI R/W code
2024-07-09 04:33 AM
I am testing my register based SPI R/W code. Forget HAL and LL.
2024-07-09 04:34 AM
The register based low level SPI drive has been using for many years, it is still the best. HAL and LL are only good for the initialization. Both, especially HAL, adds the overhead (delay) between two consecutive API calls. It is a show-stop for our timing critical application. It was m first time of using HAL and LL - not a good experience. Thanks again.
2024-07-09 04:51 AM
There's an echo in here!
2024-07-10 03:39 AM
I agreed and agree with you. I am testing my code now. I will let you know soon. Thanks!
2024-07-16 12:19 AM
Hi, Andrew
I need your help with correcting my the register based SPI code.
The SPI Master is STM32C031C6 Nucleo Eva board.
The SPI Slave is STPM34 (Meter IC) Eva Board.
Test Result:
1. The HAL Function HAL_SPI_TransmitReceive(...) works, but introduces a long delay.
2. I tried to write the register based SPI code to do the same as the above HAL function, but it does not work. I also wrote SPI 16-bit data W/R, it did not work either.
Could you make some correction on the code below? Thank you very much!
void SPI_Transmit_Receive (const uint8_t *data_tx, uint8_t *data_rx, uint8_t size)
{
uint8_t size1 = size;
SPI1->CR1 |= (1u << 6); //ENABLE SPI
while (size)
{
if (size == size1)
{
if (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_TXE))
{
SPI1->DR = *((uint16_t *)data_tx);
data_tx += sizeof(uint16_t);
size -= 2U;
}
}
if (size1 > size)
{
if (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE))
{
*(uint16_t *)data_rx = (uint16_t)SPI1->DR;
data_rx += sizeof(uint16_t);
size1 -= 2U;
}
}
}
SPI1->CR1 &= ~(1u << 6); //DISABLE SPI
}
2024-07-16 12:26 AM
I need your help with correcting my the register based SPI code.
The SPI Master is STM32C031C6 Nucleo Eva board.
The SPI Slave is STPM34 (Meter IC) Eva Board.
Test Result:
1. The HAL Function HAL_SPI_TransmitReceive(...) works, but introduces a long delay.
2. I tried to write the register based SPI code to do the same as the above HAL function, but it does not work.
Could you make some correction on the code below? Or provide me with some working code? Thank you very much!
void SPI_Transmit_Receive (const uint8_t *data_tx, uint8_t *data_rx, uint8_t size)
{
uint8_t size1 = size;
SPI1->CR1 |= (1u << 6); //ENABLE SPI
while (size)
{
if (size == size1)
{
if (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_TXE))
{
SPI1->DR = *((uint16_t *)data_tx);
data_tx += sizeof(uint16_t);
size -= 2U;
}
}
if (size1 > size)
{
if (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE))
{
* (uint16_t *)data_rx = (uint16_t)SPI1->DR;
data_rx += sizeof(uint16_t);
size1 -= 2U;
}
}
}
SPI1->CR1 &= ~(1u << 6); //DISABLE SPI
}