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

}

 

 

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