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
RongShengWang
Associate II

     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

}

There's that echo again!

Please see the instructions to properly post source code:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

 

Hello @RongShengWang ,

 

Is the data size set to greater than SPI_DATASIZE_8BIT? If yes, could you please try with this code?

 

void SPI_Transmit_Receive(const uint8_t *data_tx, uint8_t *data_rx, uint8_t size)
{
	uint8_t rx_size= size;
	uint8_t tx_size = size;
	
	/* Set the Rx Fifo threshold */
    if (size > 1U)
    {
      /* Set fiforxthreshold according the reception data length: 16bit */
      CLEAR_BIT(SPI1->CR2, SPI_RXFIFO_THRESHOLD);
	}
	
    /* Enable SPI */
    SPI1->CR1 |= SPI_CR1_SPE;


    while (size > 0)
    {
        /* Wait until TXE (Transmit buffer empty) flag is set */
        while (!__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_TXE));

        /* Transmit data */
      if (tx_size > 1U)
      {
        SPI1->DR = *((uint16_t *)data_tx);
        data_tx += sizeof(uint16_t);
        tx_size -= 2U;
      }
      else
      {
        *(__IO uint8_t *)&SPI1->DR = (*data_tx);
        data_tx ++;
        tx_size --;
      }

        /* Wait until RXNE (Receive buffer not empty) flag is set */
        while (!__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE));
		
		
		if (rx_size > 1U)
        {
          *((uint16_t *)data_rx) = (uint16_t)SPI1->DR;
          data_rx += sizeof(uint16_t);
          rx_size -= 2U;
          if (rx_size <= 1U)
          {
            /* Set RX Fifo threshold before to switch on 8 bit data size */
            SET_BIT(SPI1->CR2, SPI_RXFIFO_THRESHOLD);
          }
        }
        else
        {
          (*(uint8_t *)data_rx) = *(__IO uint8_t *)&SPI1->DR;
          data_rx++;
          rx_size --;
        }
    }

    /* Wait until the SPI is not busy */
    while (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_BSY));

    /* Disable SPI */
    SPI1->CR1 &= ~SPI_CR1_SPE;
}

 

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Hi, Omar,

     Thank you very much for your timely help. I found my setting is -

     hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - Was it a big problem with my code?

     Should I change it to hspi1.Init.DataSize = SPI_DATASIZE_16BIT to run your code?

     Thank you very much!

Rong

 

 

Hi, Omar,

     I found my setting ishspi1.Init.DataSize = SPI_DATASIZE_8BIT

   I also tried to send one byte - 8 bits, rather than 16 bits, at a time. It did not work either.

     Should I change it to hspi1.Init.DataSize = SPI_DATASIZE_16BIT to run your code?

     Thank you very much!

Rong

I need your help with my register based SPI C code which does not work.

Could you provide me with the working register based SPI C code? Thanks