I am trying to initialize RTC on the STM32F469I-DISCO board. Since I'm still involved, I tried to play with the HAL API, which allowed me to reach some projects until the day when I get enough understanding of this microcontroller to play with registers directly.
In any case, my code uses the STM32F469I-DISCO pattern from CubeF4, which allows you to directly load the HAL level and system clock (180 MHz through the 8 MHz HSE oscillator).
To initialize RTC, I followed the instructions in UM1725: Description of the HAL and LL STM32F4 drivers . Page 715, section 55.2.4, you have instructions for using the HAL_RTC API.
And the first paragraph says that you must enable the "Domain of the RTC domain." This point is explained in the section above (55.2.3, on the same page).
And I did what he was asked to do. Here is my code (simplified, I only allow part of the RTC Init and System Clock):
#include "main.h"
RTC_HandleTypeDef rtcHandle;
RTC_InitTypeDef rtcInit;
RTC_TimeTypeDef rtcTime;
RTC_DateTypeDef rtcDate;
static void SystemClock_Config(void);
static void Error_Handler(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
__HAL_RCC_RTC_ENABLE();
rtcInit.HourFormat = RTC_HOURFORMAT_24;
rtcInit.AsynchPrediv = 0x7F;
rtcInit.SynchPrediv = 0xFF;
rtcInit.OutPut = RTC_OUTPUT_DISABLE;
rtcInit.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
rtcInit.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
rtcHandle.Instance = RTC;
rtcHandle.Init = rtcInit;
HAL_RTC_Init(&rtcHandle);
rtcTime.Hours = 12;
rtcTime.Minutes = 30;
rtcTime.Seconds = 40;
rtcDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;
rtcDate.Month = RTC_MONTH_APRIL;
rtcDate.Date = 4;
rtcDate.Year= 17;
HAL_RTC_SetTime(&rtcHandle, &rtcTime, RTC_FORMAT_BCD);
while (1)
{
}
}
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
#if defined(USE_STM32469I_DISCO_REVA)
RCC_OscInitStruct.PLL.PLLM = 25;
#else
RCC_OscInitStruct.PLL.PLLM = 8;
#endif
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
RCC_OscInitStruct.PLL.PLLR = 6;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
if(HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
static void Error_Handler(void)
{
while(1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
And it does not work. After some digging in the bottom layer, I managed to find where it doesn't work. I just don’t know why.
A call to HAL_RTC_Init () returns the status of HAL_ERROR. This HAL_ERROR appears because HAL_RTC_Init () calls RTC_EnterInitMode () and returns the status HAL_TIMEOUT because the condition is not reached within the expected time. Here are the functions:
HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
{
if(hrtc == NULL)
{
return HAL_ERROR;
}
assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
assert_param (IS_RTC_OUTPUT(hrtc->Init.OutPut));
assert_param (IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));
if(hrtc->State == HAL_RTC_STATE_RESET)
{
hrtc->Lock = HAL_UNLOCKED;
HAL_RTC_MspInit(hrtc);
}
hrtc->State = HAL_RTC_STATE_BUSY;
__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
if(RTC_EnterInitMode(hrtc) != HAL_OK)
{
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
hrtc->State = HAL_RTC_STATE_ERROR;
return HAL_ERROR;
}
else
{
hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);
hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16U);
hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;
hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
hrtc->State = HAL_RTC_STATE_READY;
return HAL_OK;
}
}
and:
HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
{
uint32_t tickstart = 0U;
if((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
{
hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
tickstart = HAL_GetTick();
while((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
{
if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
, , , : hrtc- > Instance- > ISR RTC_ISR_INITF == (uint32_t) RESET
( TIMEOUT ). ting, , (EnterInitMode), RTC_ISR_INITF ISR-, -, , , 0 (RESET).
"ISR" RTC_INIT_MASK (#define 0xFFFFFFFF stm32f4xx_hal_rtc.h)
"RTC_ISR_INITF" - : (0x1U < RTC_ISR_INITF_Pos), RTC_ISR_INITF_Pos 6U (#define), stm32f469xx.h
, , "&" 0?
, TIMEOUT?
!