Showing results for 
Search instead for 
Did you mean: 

F401CC RTC: Unable to perform reference clock detection (60 Hz)



I am writing here because I am out of solution for making the F401CC RTC use the reference clock detection feature to correct its timing. Everything in the RTC is working fine in my application, except for that feature. I use a STM32F401CCU6 (UQFN48 package) on a Black Pill board.

To verify whether the RTC is syncing off the external reference, I compare the RTC 1 Hz calibration output (pin PC13) to the 60 Hz (pin PB15) on an oscilloscope triggered by the 1 Hz. I cannot see any alignment effort whatsoever between the two signals. All I see is the frequency offset between the 32KHz resonator (LSE clock) and the 60 Hz reference, a slow drift of the 60 Hz signal on the screen. BTW, I use a lab-grade function generator to provide the 60 Hz (HP 33120A).

I use the STM32RTC library to get going, but then apply changes directly into the RTC registers to setup for, and enable the RTC reference clock detection, a feature not covered in the library. Here is the part of my Arduino code that deals with that feature (sorry for the French comments).

  rtc.setClockSource(STM32RTC::LSE_CLOCK);  // Selection du résonateur 32KHz comme source de l'horloge RTC
  rtc.begin();                              // initialisation de l'horloge RTC

  // Input pin configuration for 50/60 Hz external reference
  GPIOB->MODER &= 0x7FFFFFFF;               // Configuration de la broche PB15 en entrée
  GPIOB->PUPDR &= 0x3FFFFFFF;               // Configuration de la broche PB15 sans pullup/pulldown
  GPIOB->AFR[1] &= 0x0FFFFFFF;              // Configuration de la broche PB15 sans fonction alternative

  // RTC register unlock and transition into RTC Init mode
  RTC->WPR = 0xCA;                          // Deverrouillage des registres du RTC
  RTC->WPR = 0x53;                          //     "
  RTC->ISR |= RTC_ISR_INIT;                 // Entrer en mode Init
  while (!((RTC->ISR) & RTC_ISR_INITF));    // Attendre que le mode Init soit confirmé

  // Disabling of shift feature and coarse calibration
  RTC->SHIFTR &= 0x7FFF8000;
  RTC->CALIBR &= 0xFFFFF60;                 // Pas d'ajustement grossier du RTC

  // Prescalers setting
  RTC->PRER &= 0xFF808000;                  // Effacer les prescalers.
  RTC->PRER |= 0x000000FF;                  // D'abord, PREDIV_S doit être 0x00FF pour un hotloge externe de 32.768 KHz.
  RTC->PRER |= 0x007F0000;                  // Ensuite, PREDIV_A doit être 0x007F.
  // Setup of 1 Hz calibration output and reference clock detection activation
  RTC->CR &= 0xFF000000;                    // Envoyer la reference interne en sortie PC13.
  RTC->CR |= RTC_CR_BYPSHAD;                // Lire directement des registres du calendrier, pas des registres fantômes
  RTC->CR |= RTC_CR_COE;                    //      "
  RTC->CR |= RTC_CR_COSEL;                  // Configurer fréquence de la reference en sortie à 1 Hz 
  RTC->CR |= RTC_CR_REFCKON;                // Activer la detection de reference externe 50/60Hz

  // Exit of Init mode
  RTC->ISR &= !RTC_ISR_INIT;                // Sortir du mode Init
  while ((RTC->ISR) & RTC_ISR_INITF);       // Attendre la sortie du mode Init

  // RTC register lock
  RTC->WPR = 0xFF;                          // Verrouillage des registres du RTC

Here is what I have tried to debug:

  • I can read back all the RTC registers and they read back the same as I set them.
  • I run some clock firmware (other part of the code) and the RTC is working properly.
  • I have verified that the 60 Hz signal makes it inside the MCU through PB15. I can correctly read back the logic level of the applied signal in the GPIOB_IDR register.
  • I have tried both 50 and 60 Hz. Made no difference.
  • I have tried to configure port pin PB15 using the "pinMode(PB15, INPUT)" command instead, but it made no difference.
  • I have checked the component errata sheet, but could not find anything linked to that issue.

    Am I missing something here? I have read a lot of ST documentation on the topic, and believe that I am doing what it takes to enable the feature.

    Any Idea of where to explore?

    I thank you for taking the time to read this, and for any insight you may have.


Accepted Solutions

You may want to have a look at

The point is, that you have to set PB15 as AF, i.e. 0b10. You use only &, which clears the uppermost bit in GPIOB_MODER which is already zero by default; while you are supposed to set it.


View solution in original post


I am afraid there's not much expertize here for the 50/60Hz calibration; myself included.

You can try to search this forum, I remember this being discussed in the past but I am afraid with no conclusion whatsoever.

Please note that this is a primarily user-driven forum with casual ST presence. You may want to contact ST directly, through FAE or the web support form.


You may want to have a look at

The point is, that you have to set PB15 as AF, i.e. 0b10. You use only &, which clears the uppermost bit in GPIOB_MODER which is already zero by default; while you are supposed to set it.


You got it, JW! "Properly" configuring the PB15 input as AF0 did it:


  GPIOB->MODER &= 0x0FFFFFFF;               // Configuration de la broche PB15 en AF0
  GPIOB->MODER |= 0x80000000;               //      "


That RTC_REFIN signal is defined as an "Additional Function" in the pin list, not an "Alternate Function". This is where my confusion came from. Admittedly, elsewhere in the datasheet, it is written:

To use an I/O in a given configuration, proceed as follows:
• System function
Connect the I/O to AF0 and configure it depending on the function used:
RTC_REFIN: this pin should be configured in Input floating mode

So Additional Function implies Alternate Function 0.

I thank you much! Have a good weekend.