2023-06-01 03: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
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
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.
2023-06-10 01:31 AM
Sorry, but isn't the total number of bytes that needs to be specified? The number of bytes to transmit+receive.
2023-06-10 01: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.
2023-06-10 06: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!
2023-06-10 06: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
2023-06-10 06: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.
2023-06-10 06: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
2023-06-12 04:57 AM
Wrong. No need for volatile specifier at all. If the data address is referenced, the compiler must implement the data in memory.