2023-04-24 01:15 AM
Hi,
I'm having some trouble with trying to correct the RTC drift on a STM32F439NIHx. I've enabled the REF_IN and provided a 50Hz signal on the pin, but the RTC still drifts by around 1s per day.
I've also tested that the 50Hz signal is correctly received by changing the pin to an external interrupt and correctly generated 50 interrupts per seconds.
Am I missing something or doing something wrong in the setup:
Enabling the RTC and the ref in :
RTC_HandleTypeDef hrtc = RTC_HandleTypeDef();
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
hrtc.Init.SynchPrediv = RTC_SYNCH_PREDIV;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(hrtc) != HAL_OK)
{
Error_Handler();
}
if (HAL_RTCEx_EnableBypassShadow(hrtc) != HAL_OK)
{
Error_Handler();
}
if (HAL_RTCEx_SetRefClock(hrtc) != HAL_OK)
{
Error_Handler();
}
and the HAL_RTC_MspInit function:
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
/**RTC GPIO Configuration
PB15 ------> RTC_REFIN
*/
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_LockPin(GPIOB, RTC_REF_IN_PIN); // Lock Pin configuration
// Configure LSE as RTC clock source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
// Initialization Error
return;
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
// Initialization Error
return;
}
// Enable RTC peripheral Clocks
__HAL_RCC_RTC_ENABLE();
// Configure the NVIC for RTC Alarm
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
Solved! Go to Solution.
2023-04-24 11:10 PM
I think we'd already tested with GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; before and the drift was the same.
for GPIO_InitStruct.Alternate = GPIO_AF0_RTC_50Hz; it doesn't change anything since its default value is already 0.
I'll restart a test with GPIO_MODE_AF_PP to be sure, but I don't think that's the issue.
2023-04-25 02:18 AM - edited 2023-11-20 07:20 AM
i set refclk in Cube->
then cube gen ->
/** Enable the reference Clock input
*/
if (HAL_RTCEx_SetRefClock(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
-> and no GPIO_PIN_15 init in main ... !
2023-04-25 02:54 AM
I don't use Cube, so I'm not sure how the code generation works, but the GPIO init is probably somewhere. Still, as waclawek.jan said, the GPIO mode I had was INPUT while your screenshot shows it in Alternate, so I'm redoing the test with it in GPIO_MODE_AF_PP. (I think we'd tried this config before, but better to be sure)
2023-04-25 03:49 AM
so is HAL doing the rtc init:
/**
* @brief RTC Initialization Function
* @param None
* @retval None
*/
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Check_RTC_BKUP */
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x11;
sTime.Minutes = 0x22;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_ADD1H;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_TUESDAY;
sDate.Month = RTC_MONTH_MAY;
sDate.Date = 0x18;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/** Enable the reference Clock input
*/
if (HAL_RTCEx_SetRefClock(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
+ look /step in debug , is it relly going to HAL_RTCEx_SetRefClock()
and doing there ->
/**
* @brief Enter the RTC Initialization mode.
* @note The RTC Initialization mode is write protected, use the
* __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
* @param hrtc RTC handle
* @retval HAL status
*/
HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
{
uint32_t tickstart;
HAL_StatusTypeDef status = HAL_OK;
/* Check if the Initialization mode is set */
#if defined(RTC_ICSR_INITF)
if((hrtc->Instance->ICSR & RTC_ICSR_INITF) == 0U)
{
/* Set the Initialization mode */
SET_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
tickstart = HAL_GetTick();
/* Wait till RTC is in INIT state and if Time out is reached exit */
while (((hrtc->Instance->ICSR & RTC_ICSR_INITF) == 0U) && (status != HAL_TIMEOUT))
{
if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
{
status = HAL_TIMEOUT;
hrtc->State = HAL_RTC_STATE_TIMEOUT;
}
}
}
+
>the GPIO init is probably somewhere
right - found it in HAL_RTC_MspInit( ) :
__HAL_RCC_GPIOB_CLK_ENABLE();
/**RTC GPIO Configuration
PB15 ------> RTC_REFIN
*/
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF0_RTC_50Hz;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN RTC_MspInit 1 */
-- this you didnt - right ? >GPIO_InitStruct.Alternate = GPIO_AF0_RTC_50Hz;
2023-04-25 04:08 AM
I checked and the code I have is doing mostly the same things, with the difference of GPIO_InitStruct.Mode = GPIO_MODE_INPUT; instead of GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; The test for this correction is running, but it takes 1-2 days to be sure whether it changes anything.
For GPIO_InitStruct.Alternate = GPIO_AF0_RTC_50Hz; I don't have it, but this just sets the value to 0, which is its default value when the structure is initialized, so missing it shouldn't have an effect.
2023-04-26 06:02 PM
Any conclusions yet?
JW
2023-04-26 10:55 PM
It was indeed the GPIO_InitStruct.Mode = GPIO_MODE_INPUT; that was wrong.
The setup is running now for two days with GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; and the time hasn't drifted.
Thanks a lot for the help.
DP
2023-04-27 12:50 AM
Thanks.
JW