cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to write Data into SPI2->DR register in stm32g030k6t6 MCU

Nchun.1
Senior

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 

Nchun1_1-1696507445243.png

 

 

/** * @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); }
View more

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

 

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

 

View solution in original post

7 REPLIES 7

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

 

Hi @waclawek.jan 

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);

Nchun1_0-1696611181463.png

Thank You 

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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; } }
View more
HAL_GPIO_WritePin(GPIOB, 5, GPIO_PIN_RESET);

 

 

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

 

Probably not an issue with the library code. Check how you're configuring the pin, or if anything external is driving it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi @waclawek.jan ,

yes you are correct. Passed incorrect argument . Now i am able to solve the issue  

Nchun1_0-1696654011976.png

Thank you