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-16 01:55 AM
There's that echo again!
Please see the instructions to properly post source code:
2024-07-16 03:50 AM - edited 2024-07-16 03:57 AM
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;
}
2024-07-16 05:00 AM
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
2024-07-16 05:18 AM
Hi, Omar,
I found my setting is - hspi1.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
2024-07-16 07:42 AM
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
2024-07-16 10:24 AM
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
2024-07-18 01:10 AM
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!
2024-07-18 05:07 AM
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;
2024-07-18 05:51 AM
Remember to use this button for posting source code:
2024-07-18 06:52 AM
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;