nano curiosity 4809: can't enable ext 32.768 kHz oscillator

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

Hi All,

 

I have a Nano Curiosity 4809.  I was trying to get the RTC working with the external crystal but I'm failing.

I trimmed down code to enable the oscillator and then waiting for the "stable" bit to be non-zero.  It's not working.

In the code below, if I comment-out the while-loop that waits for bit-6 of the MSTATUS register to be non-zero, the LED blinks.  If the loop is enabled, the LED never blinks.

Any ideas what could be going wrong?

 

#include <avr/io.h>
#include <util/delay.h>

int main(void) {
  PORTF.DIRSET = PIN5_bm;		/* set LED/PF5 as output */
  PORTF.OUTSET = PIN5_bm;		/* LED off */

 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);
 while ((CLKCTRL.MCLKSTATUS & 0x10) == 0);
 
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x01);
 while ((CLKCTRL.MCLKSTATUS & 0x40) == 0);

 while (1) {
   _delay_ms(500);
   PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
 }
}

 compile lines:

$ /opt/local/bin/avr-gcc -DF_CPU=5000000 -mmcu=atmega4809 -Os -B/opt/local/avr/packs/mega-2.0.12 -o main.elf main.c
$ /opt/local/bin/avr-objcopy -O ihex main.elf main.hex

 

asm:

000000b8 <main>:
  b8:	80 e2       	ldi	r24, 0x20	; 32
  ba:	80 93 a1 04 	sts	0x04A1, r24	; 0x8004a1 <__TEXT_REGION_LENGTH__+0x7f44a1>
  be:	80 93 a5 04 	sts	0x04A5, r24	; 0x8004a5 <__TEXT_REGION_LENGTH__+0x7f44a5>
  c2:	88 ed       	ldi	r24, 0xD8	; 216
  c4:	90 e0       	ldi	r25, 0x00	; 0
  c6:	84 bf       	out	0x34, r24	; 52
  c8:	90 93 60 00 	sts	0x0060, r25	; 0x800060 <__TEXT_REGION_LENGTH__+0x7f4060>
  cc:	23 e0       	ldi	r18, 0x03	; 3
  ce:	30 e0       	ldi	r19, 0x00	; 0
  d0:	84 bf       	out	0x34, r24	; 52
  d2:	20 93 61 00 	sts	0x0061, r18	; 0x800061 <__TEXT_REGION_LENGTH__+0x7f4061>
  d6:	80 91 63 00 	lds	r24, 0x0063	; 0x800063 <__TEXT_REGION_LENGTH__+0x7f4063>
  da:	84 ff       	sbrs	r24, 4
  dc:	fc cf       	rjmp	.-8      	; 0xd6 <main+0x1e>
  de:	88 ed       	ldi	r24, 0xD8	; 216
  e0:	91 e0       	ldi	r25, 0x01	; 1
  e2:	84 bf       	out	0x34, r24	; 52
  e4:	90 93 7c 00 	sts	0x007C, r25	; 0x80007c <__TEXT_REGION_LENGTH__+0x7f407c>
  e8:	80 91 63 00 	lds	r24, 0x0063	; 0x800063 <__TEXT_REGION_LENGTH__+0x7f4063>
  ec:	86 ff       	sbrs	r24, 6
  ee:	fc cf       	rjmp	.-8      	; 0xe8 <main+0x30>
  f0:	80 e2       	ldi	r24, 0x20	; 32
  f2:	2f e1       	ldi	r18, 0x1F	; 31
  f4:	31 ea       	ldi	r19, 0xA1	; 161
  f6:	97 e0       	ldi	r25, 0x07	; 7
  f8:	21 50       	subi	r18, 0x01	; 1
  fa:	30 40       	sbci	r19, 0x00	; 0
  fc:	90 40       	sbci	r25, 0x00	; 0
  fe:	e1 f7       	brne	.-8      	; 0xf8 <main+0x40>
 100:	00 c0       	rjmp	.+0      	; 0x102 <__EEPROM_REGION_LENGTH__+0x2>
 102:	00 00       	nop
 104:	80 93 a7 04 	sts	0x04A7, r24	; 0x8004a7 <__TEXT_REGION_LENGTH__+0x7f44a7>
 108:	f4 cf       	rjmp	.-24     	; 0xf2 <main+0x3a>

 

This topic has a solution.
Last Edited: Wed. Aug 12, 2020 - 01:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which loop is it waiting at?

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Isn't it because you haven't used it anywhere?

 

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

You can check the status after you enable the rtc, which has selected xos32 as its source. Now that xcos32 is requested by rtc, it will startup (or if xosc32 runstdby is enabled it may already be started or starting). Once the xosc sut period expired and xosc32 is 'stable' (edges detected, I assume), and is requested, then the status bit will be 1.

 

The datasheet could do a little better describing these status bits. 'XOSC32K is stable' should be 'XOSC32K is in use'. The clock could already be running and 'stable' with runstdby enabled, so the current description would say that the status bit should be 1 (but it will be 0 if not in use). If 'in use' was used, it would show both that the clock is requested and is working.

 

In the case of rtc, you can check the status bit to make sure your xosc32 is running and switch to internal osc32 as a backup (or you may want to code for with/without xosc32 xtal on board, and this is how you could check if you have a 32k xtal). You will have to determine how much time to give for the xtal to start before concluding the xtal is not working (sut or actual startup time).

 

The main clock is the only other place xosc32 can be used, but the status bit is not useful in that case- you already have sosc to tell you if the switch worked (and if no xtal, no switch, and sosc remains set until next reset), and after switch success you are not going to be able to check anything if the clock fails (now need watchdog to recover).

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

Try to also set the RUNSTBY bit, this should convince the clock to start.

 

  _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_RUNSTDBY_bm | CLKCTRL_ENABLE_bm); 

 

edit: nevermind, read post #3

But in my experiments with the oscillator, I've found that it's usually better to have RUNSTBY set.

Last Edited: Tue. Aug 11, 2020 - 09:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Setting the STANDBY bit made it work.  Off to check the PIT now.

Last Edited: Wed. Aug 12, 2020 - 12:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll have to take back my post. I know I have been through this before, but apparently am mixed up.

 

Tested again- either if the clock is requested (by peripheral or main clock), OR the RUNSTDBY is enabled, then the XOSC32KS bit is set if it is working (stable). So the little paragraph describing this status bit now makes no sense, but the description does. Erase the paragraph, keep the description.

 

I'll try to add something useful-

 

Since xosc32 probably only gets used for rtc (unless you want to run the main clock with it), and the rtc most likely will want to be left running in standby, the RUNSTDBY bit should be enabled. If it is not enabled, xosc32 still works fine but will be off in sleep/standby mode.

 

In any case, you will not want to block on that xosc32ks status bit, unless you want the app to stop if there is no working xosc32. The only time looking at that status bit makes sense, is if you want to make sure the rtc has a good clock source and switch to internal if it fails, or as I said previously if you don't know if your board will be populated with a xtal and you want a way to find out.

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

Now I'm trying to get the PIT interrupt to work.  The code below is similar to to the above, but now with STANDBY bit fixed interrupt set up.  The LED should start flashing when the PIT interrupt sets debug_flag to 1.  It does not flash.

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t debug_flag = 0;

ISR(RTC_PIT_vect) {
  debug_flag = 1;
}

int main(void) {
  PORTF.DIRSET = PIN5_bm;		/* set LED/PF5 as output */
  PORTF.OUTSET = PIN5_bm;		/* LED off */

 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);
 while ((CLKCTRL.MCLKSTATUS & 0x10) == 0); /* wait for stable OSC20M */

 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x01);
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x37);
 while ((CLKCTRL.MCLKSTATUS & 0x40) == 0); /* wait for stable XOSC32K */

 RTC.PITCTRLA = 0x09;			/* enable PIT at 32762/4 */
 RTC.PITINTCTRL = 0x01;			/* enable PIT intr */

 while (1) {
   while (debug_flag == 0);
   _delay_ms(500);
   PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
 }
}

 

Last Edited: Wed. Aug 12, 2020 - 01:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

slam palm on forehead: forgot to add

    sei();

LED is flashing now. 

 

EDIT: But flashing is very slow.  Need to understand that.

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

MattRW wrote:

EDIT: But flashing is very slow.  Need to understand that.

 

Odd, but when I add

    RTC.PITINTFLAGS = 0x01;

To the interrupt service routine, the LED flash rate goes back to normal (1 Hz).  It was about 0.25 Hz before.

 

Here is the current code:

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t debug_flag = 0;

ISR(RTC_PIT_vect) {
  debug_flag = 1;
  RTC.PITINTFLAGS = 0x01;		/* clear interrupt flag */
}

int main(void) {
  PORTF.DIRSET = PIN5_bm;		/* set LED/PF5 as output */
  PORTF.OUTSET = PIN5_bm;		/* LED off */

 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);
 while ((CLKCTRL.MCLKSTATUS & 0x10) == 0); /* wait for stable OSC20M */
 
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x37);
 while ((CLKCTRL.MCLKSTATUS & 0x40) == 0); /* wait for stable XOSC32K */

 while ((RTC.STATUS & 0x1) != 0);	/* wait for steady CTRLA */
 RTC.CTRLA = 0x01;			/* enable RTC */

 while ((RTC.PITSTATUS & 0x1) != 0);	/* wait for steady PITCTRLA */
 RTC.PITCTRLA = 0x09;			/* enable PIT at 32762/4 */
 RTC.PITINTCTRL = 0x01;			/* enable PIT intr */

 sei();
 while (1) {
   while (debug_flag == 0);
   _delay_ms(500);
   PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
 }
}

 

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

Declare F_CPU before including delay.h.

 

#define F_CPU 5000000UL

 

If F_CPU is not declared, delay.h uses 1MHz as the default F_CPU.

But with this alone, the LED should blink at 5Hz.
I don't know why it's late.

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

kabasan wrote:

Declare F_CPU before including delay.h.

 

In post #1 you'll see that F_CPU is defined on the compile command line.

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

Oh, I'm sorry. I was overlooked.

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

 RTC.PITCTRLA = 0x09;            /* enable PIT at 32762/4 */

 

That is CYC4 you are doing, so that is ~122us. Also, if you forget to clear an interrupt flag after the reti you get one instruction executed before you end up back in the isr. So progress is still made in the main code, although slowly.

 

 

A 1 Hz blink on a mega4809-

 

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

 

ISR(RTC_PIT_vect) {
  RTC.PITINTFLAGS = 0x01;
  PORTF.OUTTGL = PIN5_bm;
}

 

int main(void) {
    PORTF.DIRSET = PIN5_bm;
    PORTF.OUTSET = PIN5_bm;

    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 1);
   
RTC.CLKSEL = 2; //xos32k

    while( RTC.PITSTATUS );
    RTC.PITCTRLA = 0xD<<3|1; //16384, 1/2sec, 1Hz using toggle
    RTC.PITINTCTRL = 0x01;

    sei();
    while (1) {}
}

 

and since PIT can wake up from power down, can add sleep to the while loop, and the led can toggle either in the isr or after the sleep-

 

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

 

ISR(RTC_PIT_vect) {
  RTC.PITINTFLAGS = 0x01;
}

 

int main(void) {
    PORTF.DIRSET = PIN5_bm;
    PORTF.OUTSET = PIN5_bm;

    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 1);
   
RTC.CLKSEL = 2; //xos32k

    while( RTC.PITSTATUS );
    RTC.PITCTRLA = 0xD<<3|1; //16384, 1/2sec, 1Hz using toggle
    RTC.PITINTCTRL = 0x01;

 

    sei();

 

    SLPCTRL.CTRLA = 5; //powerdown, enable
    while (1) {
        asm("sleep");
        PORTF.OUTTGL = PIN5_bm;
    }
}

Last Edited: Thu. Aug 13, 2020 - 12:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Curt, and I think RTC.CTRLA=0x01; is not required.

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

I'm now trying to use EVSYS to route the PIT to TCB in  FRQ mode so that I can get a count of CLK_PER (system clock) counts to crytal clocks.

This would allow me to calibrate the internal 20 MHz (/ 4 in my case) clock to the crystal.

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

>and I think RTC.CTRLA=0x01; is not required.

 

You are correct. I should have also checked the busy status as they say they use the rtc internally during startup.

 

And I now also see no one is using CLKSEL in RTC, so are getting the internal 32k. I changed my code above to use xosc32k for rtc.

Last Edited: Thu. Aug 13, 2020 - 12:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:

And I now also see no one is using CLKSEL in RTC, so are getting the internal 32k. I changed my code above to use xosc32k for rtc.

 

I have to palmslap again.   Thanks for that.

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

Mine is a mess right now, but just to show what I'm trying ...

 

I'm trying to route PIT to TCB0 to generate periodic interrupt that captures the TCB0 count on positive edge of PIT 32K/N.

 

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t debug_flag = 0;

void init_sys_clk() {
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);
 while ((CLKCTRL.MCLKSTATUS & 0x10) == 0); /* wait for stable OSC20M */
}


void init_rtc_pit() {
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x33);
 while ((CLKCTRL.MCLKSTATUS & 0x40) == 0); /* wait for stable XOSC32K */

 RTC.CLKSEL = RTC_CLKSEL_TOSC32K_gc;	/* external crystal */

 // following not working
 //while ((RTC.PITSTATUS & 0x1) != 0);	/* wait for steady PITCTRLA */
 RTC.PITINTCTRL = 0x01;
 RTC.PITCTRLA = 0x71;			/* 32768 cycles */
 // not needed: RTC.CTRLA = 0x01;
}

ISR(RTC_PIT_vect) {
  //debug_flag = 1;
  //PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
  EVSYS.STROBE = 0x80;
  RTC.PITINTFLAGS = 0x01;
}


void config_evsys() {
  EVSYS.CHANNEL7 = 0x0B;	    /* RTC_PIT DIV64 -> channel7 */
  EVSYS_USERTCB0 = 0x80;	    /* channel7 -> TCB0 */
  //EVSYS.USERCCLLUT0A = 0x80;	    /* channel7 -> LUT0A */
}


void config_tcb0() {
  //TCB0.CTRLB = TCB_CNTMODE_CAPT_gc;	/* event capture */
  //TCB0.CTRLB = 0x04 | TCB_CNTMODE_FRQ_gc;	/* async + frequency count */
  TCB0.CTRLB = TCB_CNTMODE_FRQ_gc;	/* CCMPEN FRQ */
  TCB0.EVCTRL = 0x01;			/* enable event input */
  TCB0.INTCTRL = 0x01;			/* capture interrupt */
}

void  enable_tcb0() {
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | 0x01; /* CLK_PER/1, enable */
  while (TCB0.STATUS == 0); //debug_flag = 1;
}

ISR(TCB0_INT_vect) {
  TCB0.INTFLAGS = 1;			/* reset INTR flag */
  debug_flag = 1;
}


void init_ccl() {
  CCL.LUT0CTRLB = 0x03;			/* 1: masked, 0: event A */
  CCL.LUT0CTRLC = 0x00;			/* 2: masked */
  CCL.TRUTH0 = 0xAA;			/* on 0 */
  CCL.INTCTRL0 = 0x01;
  _PROTECTED_WRITE(CCL.CTRLA, 0x01);
}

ISR(CCL_CCL_vect) {
  CCL.INTFLAGS = 1;
  debug_flag = 1;
}


int main(void) {
  PORTF.DIRSET = PIN5_bm;		/* set LED/PF5 as output */
  PORTF.OUTSET = PIN5_bm;		/* LED off */

  init_sys_clk();
  init_rtc_pit();
  config_tcb0();

  config_evsys();
  //init_ccl();

  enable_tcb0();

  //works: while ((TCB0.CNT & 0x01) == 0); debug_flag = 1;
  
  sei();
  while (debug_flag == 0);
  //while (TCB0.CNT == 0);
  //while (TCB0.CCMP == 0);
  while (1) {
    _delay_ms(500);
    PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
  }
}

 

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

I don't think the 'calibration' will end up being of much use. The clock calibration mechanism is already a coarse adjustment, so you have to apply the sigrow oscerr correction. If you start adjusting the calibration register, you then also would have to come up with a new oscerr correction to take care of the amount the coarse correction cannot do.

 

Trying to create your own sigrow type correction value does not seem to work, but maybe I'm doing something wrong. It almost seems like the clock synchronization between the main clock and the rtc clock is not a precise thing (reading rtc cnt in this case). Maybe using the event system would work better, but still may have a clock synchronization uncertainty there also.

 

If I create a tca0 freq output, the freq will be close to correct, if I apply the sigrow correction (to the period) then I get pretty much dead on (a multimeter doing the measurements), if I try to create my own correction using below code, then it just makes it worse and will vary on each call to calibrate.

 

In the end, I think if you want an accurate main clock, you just have to spend the 80cents on an external clock.

 

#define F_CPU 10000000ul
int8_t clockError; //signed 7bit value /1024, same as sigrow oscerr 

 

//rtc already running on xosc32

void clockCalibrate(){
    TCB0.CTRLA = 0; TCB0.CNT = 0; //reset tcb0
    while( RTC.CNT == RTC.CNT ); //find a transition
    TCB0.CTRLA = 1; //start
    uint8_t cnt = RTC.CNT + 32; // 1/1024 sec
    while( RTC.CNT != cnt );
    TCB0.CTRLA = 0; //stop
    asm("nop"); //breakpoint
    clockError = TCB0.CNT - F_CPU/1024ul; //error in signed n/1024

    //tcb0 cnt values seen (why they all end in 9, not sure)
    //9799,10109,9779,10069,9759,10089,9769,10099,10119,9789

    //10MHz/1024=9765
}

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

Calibration not to change the value in the CLKCTRL register but to have a running average of the number of OSC20M ticks to one XOSC32K ticks.   If that is what you are calling sigrow, then yes.

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


And finding that the PIT event output is async whereas TCB0 in FRQ mode accepts sync events.  So this won't work.

 

 

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


Sorry to spam.   I did find this, which seems to indicate that the sync and async lines are joined somehow.  I'm not sure yet.

 

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


MattRW wrote:
And finding that the PIT event output is async whereas TCB0 in FRQ mode accepts sync events.  So this won't work.

 

It doesn't mean it won't work, you can connect asych generators to synch users. The asynch signal just gets synchronized to the main clock, typically this costs a few cycles delay on the AVR-0/1.

This is from another related thread, not exactly the same situation, but this is what happens when signals get synchronized, the edge is delayed by 3-4 main clock cycles:

 

 

In fact as far as I remember, this was first discussed about a year ago:  https://www.avrfreaks.net/forum/it-datasheet-error-avr-01-series-tcb

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

I have something working now.   Off to work timing issues.

 

#ifdef F_CPU
#undef F_CPU
#endif
#define F_CPU 5000000L
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t debug_flag = 0;

void init_sys_clk() {
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
 _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm);
 while ((CLKCTRL.MCLKSTATUS & 0x11) != 0x10); /* wait for stable OSC20M */
}


void init_rtc_pit() {
 _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, 0x33);
 while ((CLKCTRL.MCLKSTATUS & 0x41) != 0x40); /* wait for stable XOSC32K */

 while (RTC.STATUS != 0);
 RTC.CLKSEL = RTC_CLKSEL_TOSC32K_gc;	/* external crystal for RTC/PIT */
 RTC.CTRLA = RTC_PRESCALER_DIV1_gc;	/* RTC/PIT DIV1 scaling */

 while ((RTC.PITSTATUS & 0x1) != 0);	/* wait for steady PITCTRLA */
 RTC.PITCTRLA = RTC_PERIOD_OFF_gc | RTC_PITEN_bm; 
}


void config_evsys() {
  EVSYS.CHANNEL7 = 0x0B;	       /* RTC_PIT DIV64 -> channel7 */
  EVSYS_USERTCB0 = EVSYS_CHANNEL_CHANNEL7_gc; /* channel7 -> TCB0 */
}


void init_tcb0() {
  TCB0.CCMP = 0x7fff;
  TCB0.EVCTRL = TCB_EDGE_bm | TCB_CAPTEI_bm; /* enable event input */
  TCB0.CTRLB = TCB_CNTMODE_FRQ_gc;	/* capture count on event */
  TCB0.INTCTRL = TCB_CAPT_bm;		/* and interrupt */
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;
}

ISR(TCB0_INT_vect) {
  TCB0.INTFLAGS = RTC_PI_bm;		/* reset INTR flag */
  debug_flag = 1;
}


int main(void) {
  PORTF.DIRSET = PIN5_bm;		/* set LED/PF5 as output */
  PORTF.OUTSET = PIN5_bm;		/* LED off */

  init_sys_clk();
  init_rtc_pit();
  init_tcb0();
  config_evsys();

  sei();
  while (debug_flag == 0);
  while (1) {
    _delay_ms(500);
    PORTF.OUTTGL = PIN5_bm;		/* toggle LED */
  }
}