/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#include <eCxx/eCxx.h>

#include "../AVR_Common.h"


//
// Check the MCU
//
#ifndef __AVR_ARCH_X__
#error "this test application is meant for AVRX platform only"
#endif


//
// For convenience
//
using RTCtr = eCxx::RealTimeCounter;


//
// The init function
//
void eCxx_user_init()
{
    // Initialize application
    initBasicAVRApp();

    // Initialize UART
    auto& u = App::uart();
    u.begin(9600);

    // Initialize real-time counter
    u.writeStringln( PGM_STR("\nInitializing RTC - setting clock configurations ...") );
    RTCtr::setClock(RTCtr::ClockSource::Internal1K, RTCtr::ClockPrescaler::_1);
    App::yield();

    u.writeStringln( PGM_STR("Initializing RTC - setting overflow period and attaching overflow interrupt handler ...") );
    RTCtr::setOverflowPeriod(8192);
    RTCtr::attachOverflowInterrupt( +[]() {
        // Overflow interrupt resets the RTC running counter
        App::uart().writeStringln( PGM_STR("RTC overflow interrupt!") );
    } );
    App::yield();

    u.writeStringln( PGM_STR("Initializing RTC - setting compare-match value and attaching compare-match interrupt handler ...") );
    RTCtr::setCompareMatchValue(2048);
    RTCtr::attachCompareMatchInterrupt( +[]() {
        // Compare-match interrupt does not reset the RTC running counter
        App::uart().writeStringln( PGM_STR("RTC compare-match interrupt!") );
    } );
    App::yield();

    u.writeStringln( PGM_STR("Initializing RTC - setting periodic interrupt cycle and attaching periodic interrupt handler ...") );
    RTCtr::setPeriodicInterruptCycle(RTCtr::PICycle::_1024);
    RTCtr::attachPeriodicInterrupt( +[]() {
        // Periodic interrupt has nothing to do with the RTC running counter
        App::uart().writeStringln( PGM_STR("RTC periodic interrupt!") );
    } );
    App::yield();

    u.writeStringln( PGM_STR("Initializing RTC - starting RTC ...\n") );
    RTCtr::start();
    App::yield();
}


//
// The task function
//
void eCxx_user_task()
{
    // Process event
    App::processEvent();
}
