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