Unable to write Data into SPI2->DR register in stm32g030k6t6 MCU
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-05 5:09 AM - edited ‎2023-10-05 5:14 AM
Hello ,
I Have configured STM32G030K6t6 MCU has SPI master . I have used SPI2 Module. Chip select is controlled manually by GPIO .
I am unable to write exact data 0x79 in SPI2->DR register . Always it writes 0xff to DR and i am unable to read/Write anything from Slave. Kindly provide inputs
/**
* @brief SPI2 Initialization Function
* None
* @retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB6 ------> SPI2_MISO
PB7 ------> SPI2_MOSI
PB8 ------> SPI2_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
/**
* @brief This function handles SPI2 global interrupt.
*/
void SPI2_IRQHandler(void)
{
/* USER CODE BEGIN SPI2_IRQn 0 */
/* USER CODE END SPI2_IRQn 0 */
// HAL_SPI_IRQHandler(&hspi2);
FlagStatus tmp1;
FlagStatus tmp2;
FlagStatus tmp3;
tmp1 = __HAL_SPI_GET_FLAG(&hspi2, SPI_FLAG_RXNE)?SET:RESET;
tmp2 = __HAL_SPI_GET_IT_SOURCE(&hspi2, SPI_IT_RXNE);
tmp3 = __HAL_SPI_GET_FLAG(&hspi2, SPI_FLAG_OVR)?SET:RESET;
/* SPI in mode Receiver and Overrun not occurred ---------------------------*/
if ((tmp1 != RESET) && (tmp2 != RESET) && (tmp3 == RESET))
{
rx_isr();
}
/* USER CODE BEGIN SPI2_IRQn 1 */
/* USER CODE END SPI2_IRQn 1 */
}
* USER CODE BEGIN 1 */
/* USER CODE END 1 */
void rx_isr()
{
uint8_t temp1;
temp1 = *(__IO uint8_t *)&hspi2.Instance->DR;
HAL_GPIO_WritePin(GPIOB, 5, GPIO_PIN_RESET);
}
Solved! Go to Solution.
- Labels:
-
STM32G0 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 11:36 AM - edited ‎2023-10-06 11:37 AM
HAL_GPIO_WritePin(GPIOB, 5, GPIO_PIN_RESET);
You are not supposed to use a number as the second parameter. Read the comment to that function:
This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
i.e. you should write
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_5, GPIO_PIN_RESET);
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-05 5:15 AM - edited ‎2023-10-05 5:36 AM
SPI_DR is not a memory-like register and you won't be able to read back what you've written to it. It in fact is two registers - when you write it, you write into the transmitter's buffer (FIFO), when you read it, you read the receiver's buffer (FIFO).
Observe the SPI signals using oscilloscope/logic analyzer.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 10:10 AM
I found issue is resolved after using below GPIOB->ODR register manipulation directly instead of using BSRR ,BRR for Manual Chip select
When i checked signals with scope using BSRR,BRR registers GPIO CS output is not stable till the transmission is completed. kindly explain difference between ODR and BSRR ,BRR registers
GPIOB->ODR |= 1 << 5 ;
GPIOB->ODR &= ~(1<< 5);
Thank You
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 10:41 AM
Parking a Peripheral view over registers which change others where read, or FIFOs, will result in interference with normal functionality.
Doing an RMW on ODR will take many bus cycles to complete a load store operation. Whereas using a write to BSRR takes effect in a single cycle of the GPIO clock. It's an atomic / efficiency thing.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 11:11 AM
But using "HAL_GPIO_WritePin" API is not functioning properly . I am unable to read/write from slave
/**
* @brief Set or clear the selected data port bit.
*
* @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between
* the read and the modify access.
*
* @PAram GPIOx where x can be (A..F) to select the GPIO peripheral for STM32G0xx family
* @PAram GPIO_Pin specifies the port bit to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
* @PAram PinState specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = (uint32_t)GPIO_Pin;
}
else
{
GPIOx->BRR = (uint32_t)GPIO_Pin;
}
}
HAL_GPIO_WritePin(GPIOB, 5, GPIO_PIN_RESET);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 11:36 AM - edited ‎2023-10-06 11:37 AM
HAL_GPIO_WritePin(GPIOB, 5, GPIO_PIN_RESET);
You are not supposed to use a number as the second parameter. Read the comment to that function:
This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
i.e. you should write
HAL_GPIO_WritePin(GPIOB, GPIO_Pin_5, GPIO_PIN_RESET);
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 11:37 AM
Probably not an issue with the library code. Check how you're configuring the pin, or if anything external is driving it.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-10-06 9:48 PM
Hi @waclawek.jan ,
yes you are correct. Passed incorrect argument . Now i am able to solve the issue
Thank you
