AnsweredAssumed Answered

STM32 RTC Digital Smooth Calibration

Question asked by horcicka.jan on Jun 20, 2017

Hi everybody,

I've got a custom made board with STM32L486VG on it. I'm trying to do a RTC calibration with external 1Hz clock based on X-CUBE-RTC. Everything is set up and working OK. Though, I'm getting slightly different measurements when I have MCO enabled or disabled.

With help of timer 3 & 2, the code counts a number of LSE cycles (32.768Hz) in 32 seconds and compares the value to the expected value.

 

void SystemClock_Config(void) {
     RCC_OscInitTypeDef RCC_OscInitStruct;
     RCC_ClkInitTypeDef RCC_ClkInitStruct;
     RCC_PeriphCLKInitTypeDef PeriphClkInit;

     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
     RCC_OscInitStruct.LSEState = RCC_LSE_ON;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = 16;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
     RCC_OscInitStruct.PLL.PLLM = 1;
     RCC_OscInitStruct.PLL.PLLN = 10;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
     RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
     RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
          Error_Handler();

     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_DIV1;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
          Error_Handler();

     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
     PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
          Error_Handler();

     HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);

//     HAL_RCCEx_EnableLSCO(RCC_LSCOSOURCE_LSE);
     HAL_RCCEx_DisableLSCO();

     __HAL_RCC_PWR_CLK_ENABLE();

     if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
          Error_Handler();

     HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
     HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
     HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
static void calibrate(void) {
     /* expected number of RTCCLK cycles during 32-seconds */
     const uint32_t cycles_expected = 0x100000;

     uint32_t smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
     uint32_t smooth_calib_minus_pulses_value = 0x0;

     if (Calibration1stITDone == RESET) {
          Calibration1stITDone = SET;
          printf("Calibrating...\n");
     }
     else {
          printf("Cycles expected: %lu\n", cycles_expected);
          printf("Cycles measured: %lu\n", TIM2->CCR1);

          if (TIM2->CCR1 >= cycles_expected) {
               smooth_calib_minus_pulses_value = TIM2->CCR1 - cycles_expected;
               smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
               printf("CALP - Add 512 pulses: NO\n");
          }
          else {
               smooth_calib_minus_pulses_value = (RTC_SMOOTH_CALIB_MINUS_MASK + 1) - (cycles_expected - TIM2->CCR1);
               smooth_calib_plus_pulses = RTC_SMOOTHCALIB_PLUSPULSES_SET;
               printf("CALP - Add 512 pulses: YES\n");
          }

          if (smooth_calib_minus_pulses_value > RTC_SMOOTH_CALIB_MINUS_MASK) {
               printf("Out of calibration range - please change crystal!\n\n");
          }
          else {
               printf("CALM - Minus pulses: %lu\n", smooth_calib_minus_pulses_value);
               printf("Done\n\n");

//               HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, smooth_calib_plus_pulses, smooth_calib_minus_pulses_value);
          }
     }
}

 

Case 1:   With MCO enabled the result is:

HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);

System Core Clock: 80000000
Calibrating...
Cycles expected: 1048576
Cycles measured: 1048587
CALP - Add 512 pulses: NO
CALM - Minus pulses: 11
Done

 

Case 2:   With MCO disabled the result is:

HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_NOCLOCK, RCC_MCODIV_1);

System Core Clock: 80000000
Calibrating...
Cycles expected: 1048576
Cycles measured: 1048590
CALP - Add 512 pulses: NO
CALM - Minus pulses: 14
Done

 

Any ideas why the difference?? 

 

Kind regards,

Jan

Outcomes