int main( void )
{   
    KEY_PORT.DIR = 0x00; // Set direction as input.
    LED_PORT.DIR = 0xFF;

    PORTCFG.MPCMASK = 0xFF;
    LED_PORT.PIN0CTRL |= (LED_PORT.PIN0CTRL ) | PORT_INVEN_bm;
               
    // Configure all keys to be active when pressed (inverted).
    PORTCFG.MPCMASK = 0xFF;
    KEY_PORT.PIN0CTRL |= (KEY_PORT.PIN0CTRL ) | PORT_INVEN_bm;

    // Enable overflow interrupt
    TCC0.INTCTRLA = ( TCC0.INTCTRLA & TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc; 

    DMA_Setup(DMA_CHANNEL_0, SineWaveHighRes, (void *) &DACB.CH0DATA, SINE_WAVE_HIGH_RES * 2, DMA_REPEAT_FOREVER);

    DMA_Setup(DMA_CHANNEL_1, SineWaveLowRes,  (void *) &DACB.CH1DATA, SINE_WAVE_LOW_RES  * 2, DMA_REPEAT_FOREVER);
 
    DAC_DualChannel_Enable(  &DACB,
	                         DAC_REFSEL_AVCC_gc,
	                         false, // Right adjusted
 	                         DAC_CONINTVAL_4CLK_gc,
	                         DAC_REFRESH_32CLK_gc 
                          );

    DMA_EnableChannel( DMA_CHANNEL_0 );
    DMA_EnableChannel( DMA_CHANNEL_1 );
    
    // Enable medium interrupt level in PMIC and enable global interrupts.
	PMIC.CTRL |= PMIC_MEDLVLEN_bm;
    sei();

	while (1) 
    {
        if(KEY_PORT.IN == 0x00)
        {
            // No Timer to trigger DMA: No Signal
             TCC0.CTRLA = ( TCC0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
        }
        else
        {
            // Enable Timer C0, prescaler div1 means Main Clock (2MHz).
            TCC0.CTRLA = ( TCC0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV1_gc;

    	    if(KEY_PORT.IN & 0x01)
            {
                TCC0.PER = TIMER_C0_PERIOD;

                while(KEY_PORT.IN & 0x01)
                {                    
                    LED_PORT.OUTSET = 0x01;                  
                }
            }            
            LED_PORT.OUT = 0x00;
        }
    }
}
/*
 * Function Name: main();
 * Description: All the function calls are done in main(). The CPU goes to sleep while in main(); until Interupt is generated.
 */
int main(void)
{

    CHIP_Init();

    CMU_HFRCOBandSet(cmuHFRCOBand_14MHz);
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
    CMU_OscillatorEnable(cmuOsc_HFXO, false, false);

    blockSleepMode(EM2); //Prevents the CPU to go below EM3 mode.

#if DEBUG_ON
    BSP_TraceSwoSetup(); //For simplicity studio Energy profiler code correlation.
#endif
    LETIMER_setup(); //Initialize LETIMER.

    ADC_Setup(); //Initialize the ADC

    DMA_Init();	//Initialize DMA.

    DMA_Setup(); //Setup DMA.

    LEUART_Setup(); //Initialize LEUART.

    GPIO_Init(); //Initialize GPOIs.

    LETIMER_IntEnable(LETIMER0, LETIMER_IF_UF); //Enable underflow UF interrupt.

    LEUART_IntEnable(LEUART0, LEUART_IF_SIGF);	// Enable SF RXDATAV

    NVIC_EnableIRQ(LETIMER0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

    NVIC_EnableIRQ(LEUART0_IRQn); //Enable LETIMER0 interrupt vector in NVIC (Nested Vector Interrupt Controller)

	LEUART0->SIGFRAME = '!';							// Set LEUART signal frame to '!'

	LEUART0->CTRL |= LEUART_CTRL_RXDMAWU;				// Enable DMA wake up for LEUART RX in EM2
    DMA_ActivateBasic(DMA_CHANNEL_RX, true, false, (void *)RX_Buffer, (void *)&(LEUART0->RXDATA), LEUART0_BUFFER-1);

    // Enable Sleep-on-Exit
#if SLEEPONEXIT
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;	// Setting the corresponding bit for SleepOnExit
#endif

    while(1)
    {
        sleep(); //CPU goes to EM3 Mode to save energy, waits there until Interrupt is generated.
    }

}