AVR32DB32 RTC problem External Crystal

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Hello,

 

Since a week or so I try to get the RTC of the AVR32DB32 running with an external 32k crystal, but without success. Currently I am waiting for the PCB, so it could be possible that my suboptimal breakout board is the reason, but I am absolutely not sure about the software part. I am curious if someone already got it working and if you could help me to figure out what I missed or did wrong.

Before I started with the external crystal I used the internal RTC clock and my application works fine...

 

Software: Arduinio 1.8.16 and DxCore 1.4.7

AVR32DB32 runs at 1MHz internal clock

 

The datasheet of the AVR DB does not explicit provide an information about a suggested crystal, so I choose this one based on a suggestion in AN2648: 

Selecting and Testing 32 KHz Crystal Oscillators for AVR Microcontrollers (microchip.com)

 

 

The crystal has a load capa of 12.5pF so I used 24pF for the 2 load caps's C1 and C2, connected as described in the AVR DB datasheet: 

 

 

 

The crystal is connected to PF0 (Pin 20) and PF1 (PIN 21)

 

I also tried another ext. crystal with 6pf, same issue...

 

RTC init code:

 

void RTC_init(void)
{
    CLKCTRL.XOSC32KCTRLA &= ~CLKCTRL_ENABLE_bm;                 // Disable oscillator                    
    while(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm){;}          // Wait until XOSC32KS becomes 0
    CLKCTRL.XOSC32KCTRLA |= CLKCTRL_ENABLE_bm;                  // The XOSC32K oscillator is enabled by writing a ‘1’ to the ENABLE bit in the 32.768 kHz Crystal Oscillator Control A (CLKCTRL.XOSC32KCTRLA)                        
    while (RTC.STATUS > 0 || RTC.PITSTATUS > 0) {;}             // Initialize RTC, Wait for all register to be synchronized
    CLKCTRL.XOSC32KCTRLA &= ~CLKCTRL_SEL_bm;                    // Configure the input option by writing the Source Select (SEL) bit in the XOSC32K Control A (CLKCTRL.XOSC32KCTRLA) register
    CLKCTRL.XOSC32KCTRLA |= CLKCTRL_RUNSTDBY_bm;                // Not sure if needed                                   (PIT runs in all sleep modes)                  
    RTC.CTRLA = 0x01;                                           // Not sure if needed, didnt find the correct makro _bm (RTC Enable)
    RTC.CLKSEL =  0x02;                                         // CON CLK - Write the Clock Select (CLKSEL) bit field in the Clock Selection (RTC.CLKSEL) register accordingly.
    RTC.DBGCTRL = RTC_DBGRUN_bm;                                // If the Debug Run (DBGRUN) bit in the Debug Control (RTC.DBGCTRL) register is ‘1’, the RTC will continue normal operation.

   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Set the compare value in the Compare (RTC.CMP) register, and/or the overflow value in the Period (RTC.PER) register.
   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Enable the desired interrupts by writing to the respective interrupt enable bits (CMP, OVF) in the Interrupt Controlregister.
   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Configure the RTC internal prescaler by writing the desired value to the Prescaler (PRESCALER) bit field in the Control A
   // NOT NEEDED BECAUSE PER IS USED ???                        // CON RTC - Enable the RTC by writing a ‘1’ to the RTC Peripheral Enable (RTCEN) bit in the RTC.CTRLA register.

    RTC.PITINTCTRL = RTC_PI_bm;                                 // PIT´- Enable the interrupt by writing a ‘1’ to the Periodic Interrupt (PI) bit in the PIT Interrupt Control (RTC.PITINTCTRL) register.
    RTC.PITCTRLA |= RTC_PERIOD_CYC32768_gc;                     // PIT - Select the period for the interrupt by writing the desired value to the Period (PERIOD) bit field in the Periodic Int Timer Control A
    RTC.PITCTRLA |= RTC_PITEN_bm;                               // PIT -  Enable the PIT by writing a ‘1’ to the Periodic Interrupt Timer Enable (PITEN) bit in the RTC.PITCTRLA register
}//void RTC_init(void)

 

In the ISR I just try to toggle a LED and to increment a variable:

 

ISR(RTC_PIT_vect)
{
  LED_TGL;                                           // DEBUG TOGGLE LED
  rtc_secs ++;                                       // Increment RTC seconds
  RTC.PITINTFLAGS = RTC_PI_bm;                       // The interrupt flag has to be cleared manually
}// ISR(RTC_PIT_vect)

 

As I said with the internal CLK 32k everything works fine (except the accuracy of the internal clk, about 4 min per day). Would be great if I could get some feedback from you.

 

Thanks in advance for your support!

Yves 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would be surprised if your watch xtal needs any caps at all!   Note in the app note you linked, it did not show any.

The caps in the DS may just be stray capacitance of the pcb...

Jim

 

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

CLKCTRL is change protected.

The truth is more important than the facts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Finwe09 wrote:
so it could be possible that my suboptimal breakout board is the reason,
True though can solder the crystal directly to the AVR32DB32 pads per AN2648 page 1; can forego balancing capacitors for proof-of-concept.

Finwe09 wrote:
so I choose this one based on a suggestion in AN2648: 
AN2648 updated Sep'21 for AVR Dx.

Another crystal in AVR DB Curiosity Nano.

 


AN2648 Selecting and Testing 32 KHz Crystal Oscillators for AVR Microcontrollers | Application Note | Microchip Technology (AVR4100)

 

Revision History | Selecting and Testing 32.768 kHz Crystal Oscillators for AVR® Microcontrollers

Crystal Recommendations | Selecting and Testing 32.768 kHz Crystal Oscillators for AVR® Microcontrollers

continual trend in reduction of crystal CL

AVR128DB48 CURIOSITY NANO EVALUATION KIT | Microchip Technology

[schematic, page 2, grid D4]

[page 16]

XC200

VMK3-9001-32K7680000TR

Crystal, 32.768kHz, CL=9.0pF, ESR=70kOhm, SMD LxW=3.2 x 1.5mm, 20ppm

https://octopart.com/search?q=VMK3-9001-32K7680000TR&currency=USD&specs=0&in_stock_only=1

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Thanks for your feedback! I already tried to connect the crystal without any Cbut this also didnt work out (CC7V 7pF crystal)

 

@Wannebe: I saw this in the datasheet, so I thought I can use the Status registers... to wait until the XOSC#@KS becomes 0 and Wait that all registers are synchronized...

 

void RTC_init(void)
{
    CLKCTRL.XOSC32KCTRLA &= ~CLKCTRL_ENABLE_bm;                 // Disable oscillator
    while(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm){;}          // Wait until XOSC32KS becomes 0
    CLKCTRL.XOSC32KCTRLA |= CLKCTRL_ENABLE_bm;                  // The XOSC32K oscillator is enabled by writing a ‘1’ to the ENABLE bit in the 32.768 kHz Crystal Oscillator Control A (CLKCTRL.XOSC32KCTRLA)
    while (RTC.STATUS > 0 || RTC.PITSTATUS > 0) {;}             // Initialize RTC, Wait for all register to be synchronized
    CLKCTRL.XOSC32KCTRLA &= ~CLKCTRL_SEL_bm;                    // Configure the input option by writing the Source Select (SEL) bit in the XOSC32K Control A (CLKCTRL.XOSC32KCTRLA) register
    CLKCTRL.XOSC32KCTRLA |= CLKCTRL_RUNSTDBY_bm;                // Not sure if needed                                   (PIT runs in all sleep modes)
    RTC.CTRLA = 0x01;                                           // Not sure if needed, didnt find the correct makro _bm (RTC Enable)
    RTC.CLKSEL =  0x02;                                         // CON CLK - Write the Clock Select (CLKSEL) bit field in the Clock Selection (RTC.CLKSEL) register accordingly.
    RTC.DBGCTRL = RTC_DBGRUN_bm;                                // If the Debug Run (DBGRUN) bit in the Debug Control (RTC.DBGCTRL) register is ‘1’, the RTC will continue normal operation.

   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Set the compare value in the Compare (RTC.CMP) register, and/or the overflow value in the Period (RTC.PER) register.
   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Enable the desired interrupts by writing to the respective interrupt enable bits (CMP, OVF) in the Interrupt Controlregister.
   // NOT NEEDED BECAUSE PIT IS USED ???                        // CON RTC - Configure the RTC internal prescaler by writing the desired value to the Prescaler (PRESCALER) bit field in the Control A
   // NOT NEEDED BECAUSE PER IS USED ???                        // CON RTC - Enable the RTC by writing a ‘1’ to the RTC Peripheral Enable (RTCEN) bit in the RTC.CTRLA register.

    RTC.PITINTCTRL = RTC_PI_bm;                                 // PIT´- Enable the interrupt by writing a ‘1’ to the Periodic Interrupt (PI) bit in the PIT Interrupt Control (RTC.PITINTCTRL) register.
    RTC.PITCTRLA |= RTC_PERIOD_CYC32768_gc;                     // PIT - Select the period for the interrupt by writing the desired value to the Period (PERIOD) bit field in the Periodic Int Timer Control A
    RTC.PITCTRLA |= RTC_PITEN_bm;                               // PIT -  Enable the PIT by writing a ‘1’ to the Periodic Interrupt Timer Enable (PITEN) bit in the RTC.PITCTRLA register
}//void RTC_init(void)

 

I found a AN :  Getting Started with RTC Technical Brief (microchip.com)  Which describes the init of an external crystal but not for the AVR DB they handled it this way:

 

 

Is this what you suggest to do?

 

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Thanks gchapman for your feedback and the links. First thing I will try is to replace the crystal with the correct one based on the AN...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

poftamunk wrote:

CLKCTRL is change protected.

 

yes Poftamunk thanks for your short but effective comment, now it is working! 

 

I checked again what I coded and reloaded an earlier try of the RTC init, I forgot to enable the CLKCTRL via Protected Write... Here is the working code... it works with the CC7V crystal and 2 load capa's of 24pF. I will check the accuracy tomorrow and let you know how bad the breakout board is... 

 

Here is the working code: 

void RTC_init(void)
{
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, ~CLKCTRL_ENABLE_bm);     // Disable oscillator, CLKCTRL via _Protected_WRITE
 while(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm) {;}             // Wait until XOSC32KS becomes 0
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, ~CLKCTRL_SEL_bm);        // SEL = 0 (Use External Crystal), CLKCTRL via _Protected_WRITE
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm);      // Enable oscillator, CLKCTRL via _Protected_WRITE
 while (RTC.STATUS > 0) {;}                                      // Wait for all register to be synchronized
 RTC.CLKSEL = 0x02;                                              // 32.768kHz External Crystal Oscillator (XOSC32K)
 RTC.DBGCTRL = RTC_DBGRUN_bm;                                    // Run in debug: enabled
 RTC.PITINTCTRL = RTC_PI_bm;                                     // Periodic Interrupt: enabled
 RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc                           // RTC Clock Cycles 32768
 | RTC_PITEN_bm;                                                 // Enable: enabled
}//void RTC_init(void)

 

Thanks again for all your help with this... 

 

Best,

Yves

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller