[STM32F469] Using HAL_SPI_TransmitReceive not writing on the receive buffer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-01 3:05 AM
Hello,
I implemented a simple spi transmission on a STM32F469 based board.
The problem i'm facing is that the spi function I'm not getting any value in the receive buffer.
Trough the oscilloscope i can see the byte being send and the one transmitted back from slave device, i'm using a gpio as chip select because notoriusly the hardware NSS by hal does not work properly.
What could be the problem?
Here's my code., the function names might differ because of internal implementation, but are HAL based.
Init Function:
void SIN_SPI6_Init(SPI_HandleTypeDef* spiP)
{
spiP ->Instance = SPI6;
spiP ->Init.Mode = SPI_MODE_MASTER;
spiP ->Init.Direction = SPI_DIRECTION_2LINES;
spiP ->Init.DataSize = SPI_DATASIZE_8BIT;
spiP ->Init.CLKPolarity = SPI_POLARITY_LOW;
spiP ->Init.CLKPhase = SPI_PHASE_1EDGE;
spiP ->Init.NSS = SPI_NSS_SOFT;
spiP ->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
spiP ->Init.FirstBit = SPI_FIRSTBIT_MSB;
spiP ->Init.TIMode = SPI_TIMODE_DISABLE;
spiP ->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spiP ->Init.CRCPolynomial = 10;
if (HAL_SPI_Init(spiP) != HAL_OK)
{
Error_Handler(2);
}
}
MSP function:
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI2)
{
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PC3 ------> SPI2_MOSI
PC2 ------> SPI2_MISO
*/
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
else if(hspi->Instance==SPI6)
{
/* USER CODE BEGIN SPI6_MspInit 0 */
/* USER CODE END SPI6_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI6_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/**SPI6 GPIO Configuration
PG14 ------> SPI6_MOSI
PG13 ------> SPI6_SCK
PG12 ------> SPI6_MISO
*/
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_13|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI6;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
}
The code to the transmission:
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); //SPI6_NSS low
uint8_t readStatusRegister = 0b00000101;
uint8_t readback = 0;
if (HAL_SPI_TransmitReceive (&hspi6, &readStatusRegister,&readback,2, 10) != HAL_OK)
{
Error_Handler(6);
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET); //SPI6_NSS high
- Labels:
-
SPI
-
STM32F4 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-02 12:11 AM
> I'm not getting any value in the receive buffer.
If you initialize the receive buffer to some particular (non-zero, non-FF) value, does it change?
> Trough the oscilloscope i can see the byte being send and the one transmitted back from slave device,
Did you check directly on the mcu pin? Think bad solder joints or shorts.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-02 12:46 AM
You are writing 2 bytes from a 1-byte buffer, then reading 2 bytes into another 1-byte buffer. There might be more errors like these in the rest of your code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 1:31 AM
Sorry, but isn't the total number of bytes that needs to be specified? The number of bytes to transmit+receive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 1:32 AM
I cant check on the mcu pins because its a bga package.
But i checked on the nearest contact i can put a probe.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 6:00 AM
No, and that would be ridiculous even for ST's broken bloatware. It took me few seconds to find it out by looking at the code... Less than writing this short post!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 6:09 AM
On user manual referring to the function TransmitReceive is written "total amount of data to be sent and received".
I thought after sending known amount of data from bufferr SPI "listens" the respond from slave the total-sent amount of bytes.
So you meaning that The function transmits and receive the same amount of data everytime from transmit and also for receive?@gbm​
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 6:53 AM
You can probably probe the 4 SPI signals with a multimeter/oscilloscope, go in debug mode, stop the code, view and modify the GPIO registers to confirm the copper lanes are the right ones.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-10 6:57 AM
Local variables are sometime optimized to be only core registers which don't have memory address location. They are also not volatile, DMA for example can't access them. At least make them volatile to be sure.
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); //SPI6_NSS low
uint8_t readStatusRegister = 0b00000101; ==> Make them global to exist as memory address and not a register. Make them volatile type
uint8_t readback = 0; ==> Same thing.
if (HAL_SPI_TransmitReceive (&hspi6, &readStatusRegister,&readback,2, 10) != HAL_OK)
{
Error_Handler(6);
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET); //SPI6_NSS high
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-06-12 4:57 AM
Wrong. No need for volatile specifier at all. If the data address is referenced, the compiler must implement the data in memory.
