Appendix

ADC Single Conversion Code Example

/* RTC Period */
#define RTC_PERIOD          (511)

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

uint16_t adcVal;

void ADC0_init(void);
uint16_t ADC0_read(void);

void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTD.PIN6CTRL &= ~PORT_ISC_gm;
    PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;

    /* Disable pull-up resistor */
    PORTD.PIN6CTRL &= ~PORT_PULLUPEN_bm;

    ADC0.CTRLC = ADC_PRESC_DIV4_gc          /* CLK_PER divided by 4 */
                | ADC_REFSEL_INTREF_gc;     /* Internal reference */

    ADC0.CTRLA = ADC_ENABLE_bm              /* ADC Enable: enabled */
                | ADC_RESSEL_10BIT_gc;      /* 10-bit mode */

    /* Select ADC channel */
    ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
}

uint16_t ADC0_read(void)
{
    /* Start ADC conversion */
    ADC0.COMMAND = ADC_STCONV_bm;

    /* Wait until ADC conversion done */
    while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
    {
        ;
    }

    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;

    return ADC0.RES;
}

int main(void)
{
    ADC0_init();

    adcVal = ADC0_read();

    while (1) 
    {
        ;
    }
}

ADC Free Running Code Example

#include <avr/io.h>
#include <stdbool.h>

uint16_t adcVal;

void ADC0_init(void);
uint16_t ADC0_read(void);
void ADC0_start(void);
bool ADC0_conersionDone(void);

void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTD.PIN6CTRL &= ~PORT_ISC_gm;
    PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
    /* Disable pull-up resistor */
    PORTD.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    ADC0.CTRLC = ADC_PRESC_DIV4_gc          /* CLK_PER divided by 4 */
                | ADC_REFSEL_INTREF_gc;     /* Internal reference */
    
    ADC0.CTRLA = ADC_ENABLE_bm              /* ADC Enable: enabled */
                | ADC_RESSEL_10BIT_gc;      /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
    
    /* Enable FreeRun mode */
    ADC0.CTRLA |= ADC_FREERUN_bm;
}

uint16_t ADC0_read(void)
{
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    
    return ADC0.RES;
}

void ADC0_start(void)
{
    /* Start conversion */
    ADC0.COMMAND = ADC_STCONV_bm;
}

bool ADC0_conersionDone(void)
{
    return (ADC0.INTFLAGS & ADC_RESRDY_bm);
}

int main(void)
{
    ADC0_init();
    ADC0_start();
    
    while(1)
    {
        if (ADC0_conersionDone())
        {
            adcVal = ADC0_read();
            /* In FreeRun mode, the next conversion starts automatically */
        }
    }
}

ADC Sample Accumulator Code Example

#define ADC_SHIFT_DIV64    (6)

#include <avr/io.h>

uint16_t adcVal;

void ADC0_init(void);
uint16_t ADC0_read(void);

void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTD.PIN6CTRL &= ~PORT_ISC_gm;
    PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
    /* Disable pull-up resistor */
    PORTD.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    ADC0.CTRLC = ADC_PRESC_DIV4_gc          /* CLK_PER divided by 4 */
                | ADC_REFSEL_INTREF_gc;     /* Internal reference */
    
    ADC0.CTRLA = ADC_ENABLE_bm              /* ADC Enable: enabled */
                | ADC_RESSEL_10BIT_gc;      /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS  = ADC_MUXPOS_AIN6_gc;
    
    /* Set the accumulator mode to accumulate 64 samples */
    ADC0.CTRLB = ADC_SAMPNUM_ACC64_gc;
}

uint16_t ADC0_read(void)
{
    /* Start ADC conversion */
    ADC0.COMMAND = ADC_STCONV_bm;
    
    /* Wait until ADC conversion done */
    while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
    {
        ;
    }
    
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    
    return ADC0.RES;
}

int main(void)
{
    ADC0_init();
    
    while (1) 
    {
        adcVal = ADC0_read();
        
        /* divide by 64 */
        adcVal = adcVal >> ADC_SHIFT_DIV64;
    }
}

ADC Window Comparator Code Example

#define WINDOW_CMP_LOW_TH_EXAMPLE    (0x100)

#include <avr/io.h>
#include <stdbool.h>

uint16_t adcVal;

void ADC0_init(void);
uint16_t ADC0_read(void);
void ADC0_start(void);
bool ADC0_conersionDone(void);
bool ADC0_resultBelowTreshold(void);
void ADC0_clearWindowCmpIntFlag(void);
void LED0_init(void);
void LED0_on(void);
void LED0_off(void);

void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTD.PIN6CTRL &= ~PORT_ISC_gm;
    PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
    /* Disable pull-up resistor */
    PORTD.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    ADC0.CTRLC = ADC_PRESC_DIV4_gc          /* CLK_PER divided by 4 */
                | ADC_REFSEL_INTREF_gc;     /* Internal reference */
    
    ADC0.CTRLA = ADC_ENABLE_bm              /* ADC Enable: enabled */
                | ADC_RESSEL_10BIT_gc;      /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
    
    /* Set conversion window comparator low threshold */
    ADC0.WINLT = WINDOW_CMP_LOW_TH_EXAMPLE;
    
    /* Set conversion window mode */
    ADC0.CTRLE = ADC_WINCM_BELOW_gc;
    
    /* Enable FreeRun mode */
    ADC0.CTRLA |= ADC_FREERUN_bm;
}

uint16_t ADC0_read(void)
{
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    
    return ADC0.RES;
}

void ADC0_start(void)
{
    /* Start conversion */
    ADC0.COMMAND = ADC_STCONV_bm;
}

bool ADC0_conersionDone(void)
{
    return (ADC0.INTFLAGS & ADC_RESRDY_bm);
}

bool ADC0_resultBelowTreshold(void)
{
    return (ADC0.INTFLAGS & ADC_WCMP_bm);
}

void ADC0_clearWindowCmpIntFlag(void)
{
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_WCMP_bm;
}

void LED0_init(void)
{
    /* Make High (OFF) */
    PORTB.OUT |= PIN5_bm;
    /* Make output */
    PORTB.DIR |= PIN5_bm;
}

void LED0_on(void)
{
    /* Make Low (ON) */
    PORTB.OUT &= ~PIN5_bm;
}

void LED0_off(void)
{
    /* Make High (OFF) */
    PORTB.OUT |= PIN5_bm;
}

int main(void)
{
    ADC0_init();
    LED0_init();
    
    ADC0_start();
    
    while(1)
    {
        if (ADC0_conersionDone())
        {        
            if(ADC0_resultBelowTreshold())
            {
                LED0_on();
                ADC0_clearWindowCmpIntFlag();
            }
            else
            {
                LED0_off();
            }
            
            adcVal = ADC0_read();
        }
    }
}

ADC Event Triggered Code Example

/* RTC Period */
#define RTC_PERIOD            (511)

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

volatile uint16_t adcVal;

void ADC0_init(void);
void LED0_init(void);
void LED0_toggle(void);
void RTC_init(void);
void EVSYS_init(void);

void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTD.PIN6CTRL &= ~PORT_ISC_gm;
    PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
    /* Disable pull-up resistor */
    PORTD.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    ADC0.CTRLC = ADC_PRESC_DIV4_gc          /* CLK_PER divided by 4 */
                | ADC_REFSEL_INTREF_gc;     /* Internal reference */
    
    ADC0.CTRLA = ADC_ENABLE_bm              /* ADC Enable: enabled */
                | ADC_RESSEL_10BIT_gc;      /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
    
    /* Enable interrupts */
    ADC0.INTCTRL |= ADC_RESRDY_bm;
    
    /* Enable event triggered conversion */
    ADC0.EVCTRL |= ADC_STARTEI_bm;
}

void LED0_init(void)
{
    /* Make High (OFF) */
    PORTB.OUT |= PIN5_bm;
    /* Make output */
    PORTB.DIR |= PIN5_bm;
}

void LED0_toggle(void)
{
    PORTB.IN |= PIN5_bm;
}

ISR(ADC0_RESRDY_vect)
{
    /* Clear flag by writing '1': */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    adcVal = ADC0.RES;    
    LED0_toggle();
}

void RTC_init(void)
{
    uint8_t temp;

    /* Initialize 32.768kHz Oscillator: */
    /* Disable oscillator: */
    temp = CLKCTRL.XOSC32KCTRLA;
    temp &= ~CLKCTRL_ENABLE_bm;
    /* Enable writing to protected register */
    CPU_CCP = CCP_IOREG_gc;
    CLKCTRL.XOSC32KCTRLA = temp;

    while(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm)
    {
        ; /* Wait until XOSC32KS becomes 0 */
    }

    /* SEL = 0 (Use External Crystal): */
    temp = CLKCTRL.XOSC32KCTRLA;
    temp &= ~CLKCTRL_SEL_bm;
    /* Enable writing to protected register */
    CPU_CCP = CCP_IOREG_gc;
    CLKCTRL.XOSC32KCTRLA = temp;

    /* Enable oscillator: */
    temp = CLKCTRL.XOSC32KCTRLA;
    temp |= CLKCTRL_ENABLE_bm;
    /* Enable writing to protected register */
    CPU_CCP = CCP_IOREG_gc;
    CLKCTRL.XOSC32KCTRLA = temp;

    /* Initialize RTC: */
    while (RTC.STATUS > 0)
    {
        ; /* Wait for all register to be synchronized */
    }

    RTC.CTRLA = RTC_PRESCALER_DIV32_gc      /* 32 */
                | RTC_RTCEN_bm              /* Enable: enabled */
                | RTC_RUNSTDBY_bm;          /* Run In Standby: enabled */

    /* Set period */
    RTC.PER = RTC_PERIOD;

    /* 32.768kHz External Crystal Oscillator (XOSC32K) */
    RTC.CLKSEL = RTC_CLKSEL_TOSC32K_gc;

    /* Run in debug: enabled */
    RTC.DBGCTRL |= RTC_DBGRUN_bm;
}

void EVSYS_init(void)
{
    /* Real Time Counter overflow */
    EVSYS.CHANNEL0 = EVSYS_GENERATOR_RTC_OVF_gc;
    /* Connect user to event channel 0 */
    EVSYS.USERADC0 = EVSYS_CHANNEL_CHANNEL0_gc;
}

int main(void)
{
    ADC0_init();
    LED0_init();
    RTC_init();
    EVSYS_init();
    
    /* Enable Global Interrupts */
    sei();
    
    while (1) 
    {
        ;
    }
}