cancel
Showing results for 
Search instead for 
Did you mean: 

We need the register-based low level SPI R/W drive for STM32C031C6

RongShengWang
Associate II

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

35 REPLIES 35

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.

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.


@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...

I am testing the register based SPI R/W code

I am testing my register based SPI R/W code. Forget HAL and LL.

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.

There's an echo in here!

I agreed and agree with you. I am testing my code now. I will let you know soon. Thanks!

Hi, Andrew Neil,

     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 (uint8_t *data_tx, uint8_t *data_rx, uint8_t size)

{

 

SPI1->CR1 |= (1u << 6); //ENABLE SPI

while (size)

{

   while( !(SPI1->SR & SPI_SR_TXE) ){}; // poll for TX empty

   while (((SPI1->SR)&(1<<7))) {}; // wait for BSY bit to Reset 

   SPI1->DR = *data_tx++; // load the data into the Data Register

   while( !(SPI1->SR & SPI_SR_RXNE) ){}; // poll for RX non-empty

   *data_rx++ = SPI1->DR;

   size--; //

}

while (((SPI1->SR)&(1<<7))) {}; // wait for BSY bit to Reset

size = SPI1->DR;

size = SPI1->SR;

SPI1->CR1 &= ~(1u << 6); //DISABLE SPI

 

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

}