2020-09-07 06:01 AM
Good Morning,
I encountered a problem concerning the SPI peripheral. When it is configured in half-duplex master mode, I'm able to transmit data but not to receive them.
Here's the inizialitazion code for SPI peripheral (auto-generated with MX Cube):
/* SPI1 init function */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_1LINE;
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_16;
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;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/**SPI1 GPIO Configuration
PE13 ------> SPI1_SCK
PE15 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
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_SPI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
Here are the TX/RX functions:
/**
* @brief Transmit data to SPI bus
* @param spi_id: spi bus identifier
* @param txData: pointer to transmission buffer of bytes to write on MOSI line
* @param txDataSize: tx buffer length in bytes
* @retval None
*/
void SPI_Transmit(spi_id_t spi_id, uint8_t *txData, uint16_t txDataSize)
{
SPI_HandleTypeDef *hspi;
GPIO_Port_Pin_t chipSelect;
switch (spi_id)
{
case SPI1_ID:
hspi = &hspi1;
chipSelect = SPI1_CS;
break;
case SPI2_ID:
hspi = &hspi2;
chipSelect = SPI2_CS;
break;
case SPI3_ID:
break;
default:
break;
}
/* Select slave */
GPIO_Reset(chipSelect);
if (HAL_SPI_Transmit(hspi, txData, txDataSize, TIMEOUT_100MS) != HAL_OK)
{
Error_Handler();
}
/* Deselect slave */
GPIO_Set(chipSelect);
}
/**
* @brief Receive data on SPI bus
* @param spi_id: spi bus identifier
* @param txData: pointer to transmission buffer of bytes to write on MOSI line (e.g. register from which data are meant to be read)
* @param txDataSize: tx buffer length in bytes
* @param rxData: pointer to receive buffer where to put read data
* @param rxDataSize: rx buffer length in bytes
* @retval None
*/
void SPI_Receive(spi_id_t spi_id, uint8_t *txData, uint16_t txDataSize, uint8_t *rxData, uint16_t rxDataSize)
{
SPI_HandleTypeDef *hspi;
GPIO_Port_Pin_t chipSelect;
switch (spi_id)
{
case SPI1_ID:
hspi = &hspi1;
chipSelect = SPI1_CS;
break;
case SPI2_ID:
hspi = &hspi2;
chipSelect = SPI2_CS;
break;
case SPI3_ID:
break;
default:
break;
}
/* Select slave */
GPIO_Reset(chipSelect);
if (HAL_SPI_Transmit(hspi, txData, txDataSize, TIMEOUT_100MS) != HAL_OK)
{
Error_Handler();
}
if (HAL_SPI_Receive(hspi, rxData, rxDataSize, TIMEOUT_100MS) != HAL_OK)
{
Error_Handler();
}
/* Deselect slave */
GPIO_Set(chipSelect);
}
I thought of solving the problem by means of using FULL-DUPLEX MASTER mode and connecting MOSI and MISO lines togheter, but I'm afraid of possible short circuits when the SLAVE is writing data (I don't know if the MOSI line is in high impedance state or if it is forcing the line HIGH/LOW).
What might be the cause?
Thank you so much. Kind regards.