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

Thanks Andrew, I made the correction - Sorry I did not know before.  Rong

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

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;

Hello @RongShengWang,

 

Could you check this code with setting data size to SPI_DATASIZE_8BIT please:

 

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(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
    }
    else
    {
      /* Set fiforxthreshold according the reception data length: 8bit */
      SET_BIT(hspi->Instance->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(hspi->Instance->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,

   The syntax errors occur (For either hspi or hspi1).

   " CLEAR_BIT(hspi1->Instance->CR2, SPI_RXFIFO_THRESHOLD);" 

    "SET_BIT(hspi1->Instance->CR2, SPI_RXFIFO_THRESHOLD);"

 

     Please advise.

     Thanks you very much!

Rong

  

Hello @RongShengWang 

 

I updated my code. Could you check with this please.

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);
    }
    else
    {
      /* Set fiforxthreshold according the reception data length: 8bit */
      SET_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,

     Looks like it works! Thanks you very much!

     I will test one more time to conclude this case.

     Thanks again!

Rong