/***
 *** The example has no copyright and can be used by anyone.
 *** The following example is based on Device File Package
 *** required to compile the macro definitions used.
 *** The Device File Package is available by downloading Atmel Studio 7.
 ***/

/*** 
 *** In this example,  The ADC is triggered by the RTC every 1s to start a conversion.
 *** An interrupt is then generated once the ADC result is ready.
 *** ADC is configured as Event USER using the Event system,
 *** RTC is configured to be the Event GENERATOR in the Event System
 ***/

/***
 *** Function to configure the RTC in calendar mode
 *** The RTC is also confgured to provide an Event every second.
 *** This Even twill be then used to trigger the ADC Start conversion
 ***/ 
void RTC_Configure(void) 
{
 /*** 
  *** Enable XOSC32K (for RTC) 
  ***/
 OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE|
                           OSC32KCTRL_XOSC32K_XTALEN|
                           OSC32KCTRL_XOSC32K_EN1K|
                           OSC32KCTRL_XOSC32K_RUNSTDBY|
                           OSC32KCTRL_XOSC32K_STARTUP(5);
 while(OSC32KCTRL->STATUS.bit.XOSC32KRDY==0);

 /*** Enable RTC Clock 
  *** at the peripheral clock mask
  *** (This clock is enabled by default
  ***/  
 MCLK->APBAMASK.reg |= MCLK_APBAMASK_RTC;

 /*** 
  *** Select source clock for RTC : Xosc32k
  ***/
 OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL(OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val);

 /*** Disable RTC ((Enable Protected) ***/
 RTC->MODE2.CTRLA.reg &= ~(RTC_MODE2_CTRLA_ENABLE);
 /*** ( write synchronized) ***/
 while(RTC->MODE2.SYNCBUSY.reg & RTC_MODE2_SYNCBUSY_ENABLE);

 /*** Reset RTC ***/
 RTC->MODE2.CTRLA.reg = (RTC_MODE2_CTRLA_SWRST);
 /*** ( write synchronized) ***/
 while(RTC->MODE2.SYNCBUSY.reg & RTC_MODE2_SYNCBUSY_SWRST);

 /*** Configure RTC in mode 2 (calendar) ***/
 RTC->MODE2.CTRLA.reg = RTC_MODE2_CTRLA_PRESCALER(RTC_MODE2_CTRLA_PRESCALER_DIV1024_Val)|
                                                  RTC_MODE2_CTRLA_MODE(RTC_MODE2_CTRLA_MODE_CLOCK_Val);

 /*** 
  *** Clock sync enabled:
  *** means that a synchronization will be required 
  *** to read the CLOCK value register. 
  *** This will prevent reading bad values.
  ***/
 RTC->MODE2.CTRLA.bit.CLOCKSYNC = 1;
 while(RTC->MODE2.SYNCBUSY.bit.CLOCKSYNC);

 /***
  *** Configure RTC Periodic Event Generation
  *** one event every 1024/1024 seconds to trigger the ADC.
  ***/
  RTC->MODE2.EVCTRL.reg = RTC_MODE2_EVCTRL_PEREO7; 

       /*** !!! ADD these lines if RTC interrupt is required !!! ***/
       /*** Clear All interrupt flags
       RTC->MODE2.INTFLAG.reg = 0xFFFF;

       /*** set interrupt every seconds ***/
       RTC->MODE2.INTENSET.reg |= RTC_MODE2_INTENSET_PER7;

       /*** Enable RTC interrupt at core Level (NVIC) set the highest priority ***/
       NVIC_EnableIRQ(RTC_IRQn);
       NVIC_SetPriority(RTC_IRQn,0);

 /*** Enable RTC ***/
 RTC->MODE2.CTRLA.bit.ENABLE = 1;
 while(RTC->MODE2.SYNCBUSY.bit.ENABLE);
}

/*** 
 *** Function to configure the ADC as Event user
 *** allowing the RTC trigger to be propagated to the ADC.
 *** At the end of each adc acquisition an interrupt occurs.
 ***/
void Adc_Init_1Hz(void) 
{
 /*** 
  *** Configure ADC Start of conversion 
  *** as user and RTC as a trigger generator 
  *** ADC Start user is linked to the Channel 0.
  *** NO detection because of the asynchronous path
  *** EVSYS Channel 0 can run in STBY
  *** Channel 0 Asynchronous path
  *** Channel 0 RTC PEREO7 (fperiodic(n)=(fCLK_RT_OSC / 2^(7+3)) =1Hz)
  ***/
 EVSYS->USER[EVSYS_ID_USER_ADC_START].reg=        EVSYS_USER_CHANNEL(EVSYS_USER_CHANNEL_0);
 EVSYS->Channel[0].CHANNEL.reg = ( EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT|    
                                   EVSYS_CHANNEL_RUNSTDBY|    
                                   EVSYS_CHANNEL_ONDEMAND|         
                                   EVSYS_CHANNEL_PATH_ASYNCHRONOUS|    
                                   EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_RTC_PEREO7));        

 /*** Enable ADC result ready interrupt ***/
 ADC->INTENSET.bit.RESRDY = 0x01;

 /*** Enable resready ADC interrupt (ID 22) ***/
 NVIC_EnableIRQ(ADC_RESRDY_IRQn);
 NVIC_SetPriority(ADC_RESRDY_IRQn,1);

 /*** Enable the ADC ***/
 ADC->CTRLA.bit.ENABLE    =    0x1;
 /*** ( write synchronized) ***/
 while(ADC->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE);
}

/*** ADC Interrupt Handler ***/
void ADC_RESRDY_Handler(void)
{
 uint16_t adc_result;

 /*** Read and clear Interrupt status register ***/
 ADC->INTFLAG.reg;
 adc_result = ADC->RESULT.reg;   
}