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 III

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

44 REPLIES 44

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

Hi, Omar,

     Your code seems working with my setting hspi1.Init.DataSize = SPI_DATASIZE_8BIT

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

     Thank you very much!

Rong

Hello @RongShengWang,

 

Yes, you should change hspi1.Init.DataSize to SPI_DATASIZE_16BIT to run the code correctly.

I wasn't getting notified about your answer. To notify people in the forum, you need to use @username.

Thank you very much!

 

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

Thanks
Omar

Hi, Omar,

      It is strange - When I changed to SPI_DATASIZE_16BIT, your code does not work. Also "HAL_SPI_TransmitReceive" stops working - nothing works.   

    Two C files (spi.c and main.c are attached.

     When I changed it back to SPI_DATASIZE_8BIT, "HAL_SPI_TransmitReceive" works again. Your code works - but not very consistently...

     Two C files (spi.c and main.c are attached. My SPI initialization code is below. Could you explain why?  The slave SPI IC is SPTM34.

   Thank you very for your help!

Rong

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 7;

hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

Remember to use this button for posting source code:

 

AndrewNeil_0-1721307055936.png

 

Hi, Omar,

      It is strange - When I changed to SPI_DATASIZE_16BIT, your code does not work. Also "HAL_SPI_TransmitReceivestops working - nothing works.   

    Two C files (spi.c and main.c are attached.

     When I changed it back to SPI_DATASIZE_8BIT, "HAL_SPI_TransmitReceiveworks again. Your code works - but not very consistently...

     Two C files (spi.c and main.c are attached. My SPI initialization code is below. Could you explain why?  The slave SPI IC is SPTM34.

   Thank you very for your help!

Rong

 

 

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 7;

hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;