cancel
Showing results for 
Search instead for 
Did you mean: 

USART4 Tx idle stays low STM32G070

PSicl.2
Associate II

Hello everyone,

I successfully used USART1 and USART3 in my application. However, when trying to use USART4, Rx is working but not Tx. The idle signal stays at 0V all the time.

 

Here is what I already check:

  • UART init
static void MX_USART4_UART_Init(void)
{
  huart4.Instance = USART4;
  huart4.Init.BaudRate = 115200;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    Error_Handler();
  }
}
  • Clock and GPIO init
    __HAL_RCC_USART4_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART4 GPIO Configuration
    PA0     ------> USART4_TX
    PA1     ------> USART4_RX
    */
    GPIO_InitStruct.Pin = TX4_Aux_Pin|RX4_Aux_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART4;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN USART4_MspInit 1 */
    /* USART3 interrupt Init */
    HAL_NVIC_SetPriority(USART3_4_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART3_4_IRQn);
  •  USART4 CR1 register

CR1 = 0x0d = 1101

UE = 1, UESM = 0, RE = 1, TE = 1

  • USART4 ISR register

ISR = 0x6200e2

Framing error = 1, TEACK = 1, REACK = 1

  • FW version 1.6.2

I updated the firmware version but with no result. I noticed the addition of HAL_RCCEx_PeriphCLKConfig in hal_msp.c driver but it can't be applied to USART4.

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }
  •  Hardware connection

No short-circuit on Rx or Tx. I am measuring signal at MCU output and there is nothing after.

 

I tested everything I could think of. You will maybe have other ideas. Tell me if you need more details (registers values, function output, signal measurement). Thank you in advance.

MCU : STM32G070CBT6
Clock source : internal clock
Driver : HAL

1 ACCEPTED SOLUTION

Accepted Solutions

Thank you so much waclawek.jan for helping me.

So to recap, PA0 was not usable because TAMP_IN2 was enable and was overriding GPIO settings.

The solution is either:

  • Disable TAMPER
  • Move TAMPER from IN2 to IN1 on PC13

In addition, to disable TAMPER on IN2 (PA0), you can use HAL_RTCEx_DeactivateTamper function. Or if you don't use HAL, you can change TAMP->CR1 register.

View solution in original post

11 REPLIES 11

Check hardware by setting given pin to GPIO output and toggling it. You can do that in debugger, no need to write program.

Read out and check/post UART and GPIO registers content.

JW

 

I tried to control PA0 as a GPIO output but it did not worked. I tried the same code on PA1 which is USART4_Rx and this time it worked.

 

I am using a custom board with an STM32G070 mounted on it. I tried with 2 new boards but same result.

 

Any idea why I can't use PA0 ? What register do you need to see to better understand what is happening with this GPIO ?

Thank you.

> I tried to control PA0 as a GPIO output but it did not worked.

So, design error? PA0 not connected to the point you are measuring at, or connected to some other signal (perhaps ground?) which pulls it permanently low?

I presume you are trying this with an absolutely minimal program, which does nothing else just sets the given GPIO.

JW

 

To try with a minimal hardware configuration, I used the following socket : PE047X06.

IMG_20240617_155439.jpg

IMG_20240617_155448.jpg

For the program, I used a minimal one straight out from CubeMX with only :

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_GPIO_WritePin(GPIOA, GPIO_TX_Pin|GPIO_RX_Pin, GPIO_PIN_RESET);
    HAL_Delay(256);
    HAL_GPIO_WritePin(GPIOA, GPIO_TX_Pin|GPIO_RX_Pin, GPIO_PIN_SET);
    HAL_Delay(256);
  }

Still the same result. Nothing on PA0 (USART4_TX).

PSicl2_0-1718634252642.png

 

Could it be an issue from ST hardware or firmware ? What could I do to give you more information ?

Thank you.

 

In debugger, stop the program and check/post content of GPIOA registers.

You can also try toggling directly in debugger.

JW

 

PS. Connect VBAT to VDD and make sure it powers completely down to 0V before starting again, because of the "backup domain brownout" erratum. You can try to perform the backup domain reset in software, too.

Here is a video of the GPIOA registers during SET or RESET :

Animation.gif

As you can see, ODR is set to 3 in SET state and to 0 in RESET state which seems normal.

 

I tried with a NUCLEO-G070RB devkit and I can reproduce the bug. I can't output signal from PA0.
I also tried with all pin from Port A and they all worked except PA13 (SWDIO), PA14 (SWCLK) and of course PA0.

 

There might be a conflict with something else.

Can you please check RTC/TAMP registers, and /or reset the backup domain upon startup.

Thanks,

JW

Here are RTC, RCC and TAMP registers.

RTC

PSicl2_0-1718716055785.png

RCC

PSicl2_1-1718716073374.png

TAMP

PSicl2_3-1718716095227.png

 

I tried to reset backup domain on my Nucleo-G070RB with minimalist code by setting RCC->BDCR->BDRST to 1. It worked, I was able to control PA0. However, when doing the same thing at the beggining of my application, it doesn't work.

 

By looking at the registers, do you know why I can't control PA0. Does it have something to do with RTC_TAMP_IN2 ?

 

In TAMP register, CR1 is showing TAMP2E enable.

In fact, in RTC_INIT(), I have the following code:

void RTC_INIT(RTC_HandleTypeDef *hrtc){
  RtcHandle = hrtc;

  sTamper.Tamper = RTC_TAMPER_2;
  sTamper.Trigger = RTC_TAMPERTRIGGER_RISINGEDGE;
  sTamper.NoErase = RTC_TAMPER_ERASE_BACKUP_DISABLE; //RTC_TAMPER_ERASE_BACKUP_ENABLE;
  sTamper.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE;
  sTamper.Filter = RTC_TAMPERFILTER_DISABLE;
  sTamper.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768;
  sTamper.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK;
  sTamper.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE;
  sTamper.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_ENABLE;

  if (HAL_RTCEx_SetTamper(RtcHandle, &sTamper) != HAL_OK)
  {
	Error_Handler();
  }

}

I tried to replace RTC_TAMPER_2 by RTC_TAMPER_1 which is mapped on PC13 (not used in my application) but TAMP_CR1 is now : 4294901763, so RTC_TAMPER_1 and RTC_TAMPER_2 are enable. How can I disable both ?

 

Do you think it could be the answer ?