stm32duino / STM32RTC

Arduino RTC library for STM32.
131 stars 48 forks source link

RTC with LSE not keeping time #100

Closed gerrygralton closed 1 year ago

gerrygralton commented 1 year ago

Hi, I'm having a bit of trouble with my STM32F411RE not keeping time. I have an 32.768kHz output from a DS3231M chip being using as the LSE source. I am finding that the internal stm32 RTC and the DS3231M times are drifting substantially (approx 1 minute per day). This was not something I expected as they should be sharing the same clock signal.

My current setup for the STM32 RTC is very simple:

    STM32RTC & rtc = STM32RTC::getInstance();
    rtc.setClockSource(STM32RTC::LSE_CLOCK);
    rtc.begin();

I'm wondering if I need to set up the STM32 RTC in bypass mode. Is this possible with this library? Am I even on the right track? Thanks!

fpistm commented 1 year ago

Hi @gerrygralton I have a STM32F407VE with LSE crystal and do not have this issue. Looking at the ref man:

image

image

So I guess you should configure it as bypass. To do this simply redefine the SystemClock_Config

gerrygralton commented 1 year ago

Thank you! It's good to know that we're at least on the right track. Could you please give me an example of the configuration code? Or where to find the current configuration from this library?

fpistm commented 1 year ago

You can use STM32CubeMx to generate the configuration and follow the Wiki link I gave in my previous comment.

Anyway, here the modified one of the Generic_STM32F411RE to add in your sketch which will be used instead of the default one:

extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.LSEState = RCC_LSE_BYPASS;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 192;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) {
    Error_Handler();
  }
}
gerrygralton commented 1 year ago

Thank you!

fpistm commented 1 year ago

Let me know if it works.

gerrygralton commented 1 year ago

No, this hasn't worked unfortunately. Over three hours, the external DS3231M chip gained 12 seconds on the stm32 RTC.

fpistm commented 1 year ago

Unfortunately, I have no more input. I will test longer with my F407 board but I'm confident it will be OK. Maybe due to your wiring? or something bad with the hardware.

gerrygralton commented 1 year ago

Thanks for your help anyway Frederic. I'll update this if we establish the root cause.

gerrygralton commented 1 year ago

I think we have established the cause. The DS3231M chip has a 32.768 kHz accuracy of +- 2.5 % which easily explains our 1 minutes per day drift.

image

fpistm commented 1 year ago

Thanks for the feedback