/*
 * 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 eCxx::Logic;


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

    //
    // ===== Simple gate test using CCL =====
    //
    auto& logic = App::logic();

    // ----- Create a 2-inverted-input AND gate using LUT0  -----
    // Inp Out
    // 210
    // 000 1
    // 001 0
    // 010 0
    // 011 0
    // 100 0 (disabled)
    // 101 0 (disabled)
    // 110 0 (disabled)
    // 111 0 (disabled)
    logic.lut[0].enabled    = true;
    logic.lut[0].input[0]   = Logic::Input::PinPullUp;
    logic.lut[0].input[1]   = Logic::Input::PinPullUp;
    logic.lut[0].input[2]   = Logic::Input::Disabled;
    logic.lut[0].output     = Logic::Output::Default;
    logic.lut[0].truthTable = 0b00000001;

    // ----- Create a 2-inverted-input OR gate using LUT1  -----
    // Inp Out
    // 210
    // 000 1
    // 001 1
    // 010 1
    // 011 0
    // 100 0 (disabled)
    // 101 0 (disabled)
    // 110 0 (disabled)
    // 111 0 (disabled)
    logic.lut[1].enabled    = true;
    logic.lut[1].input[0]   = Logic::Input::PinPullUp;
    logic.lut[1].input[1]   = Logic::Input::PinPullUp;
    logic.lut[1].input[2]   = Logic::Input::Disabled;
    logic.lut[1].output     = Logic::Output::Default;
    logic.lut[1].truthTable = 0b00000111;

    // ----- Create a 2-inverted-input XOR gate using LUT2  -----
    // Inp Out
    // 210
    // 000 0
    // 001 1
    // 010 1
    // 011 0
    // 100 0 (disabled)
    // 101 0 (disabled)
    // 110 0 (disabled)
    // 111 0 (disabled)
    logic.lut[2].enabled    = true;
    logic.lut[2].input[0]   = Logic::Input::PinPullUp;
    logic.lut[2].input[1]   = Logic::Input::PinPullUp;
    logic.lut[2].input[2]   = Logic::Input::Disabled;
    logic.lut[2].output     = Logic::Output::Default;
    logic.lut[2].truthTable = 0b00000110;

    // ----- Create a 3-inverted-input custom gate using LUT3  -----
    // Inp Out
    // 210
    // 000 1 (act as a 2-inverted-input OR  gate)
    // 001 1 (act as a 2-inverted-input OR  gate)
    // 010 1 (act as a 2-inverted-input OR  gate)
    // 011 0 (act as a 2-inverted-input OR  gate)
    // 100 1 (act as a 2-inverted-input AND gate)
    // 101 0 (act as a 2-inverted-input AND gate)
    // 110 0 (act as a 2-inverted-input AND gate)
    // 111 0 (act as a 2-inverted-input AND gate)
    logic.lut[3].enabled    = true;
    logic.lut[3].input[0]   = Logic::Input::PinPullUp;
    logic.lut[3].input[1]   = Logic::Input::PinPullUp;
    logic.lut[3].input[2]   = Logic::Input::PinPullUp;
    logic.lut[3].output     = Logic::Output::Default;
    logic.lut[3].truthTable = 0b00010111;

    // ----- Start the CCL -----
    logic.begin();
}


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