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


//
// Helper functions
//
static void eCxx_user_init_IOExpander()
{
    // Set pin modes
    App::setPinMode(PLL, App::PinMode::Output);
    App::setPinMode(SDO, App::PinMode::Output);
    App::setPinMode(SDI, App::PinMode::Input );
    App::setPinMode(SCK, App::PinMode::Output);

    // Ensure that all the output pins are in inactive states
    App::digitalWrite(PLL, true ); // The latch/load pin is active low
    App::digitalWrite(SDO, false);
    App::digitalWrite(SCK, false);

    // Initialize UART
    App::uart().begin(9600);
}


static void eCxx_user_task_IOExpander()
{
    // Process event and delay
    static eCxx::uint32_t prvMillis = 0;
           eCxx::uint32_t curMillis = App::processEvent();
    if(curMillis - prvMillis < 500) return;
    else                            prvMillis = curMillis;

    // Read from the input port and write back its inverted value to the output port
    static eCxx::uint16_t valueW = 0;
           eCxx::uint16_t valueR = 0;

    App::shiftOutIn(
        valueW,
        valueR,
        SDO,
        SDI,
        SCK,
        PLL,
        eCxx::ActiveState::Low,
        eCxx::ActiveClockEdge::Rising,
        eCxx::ActiveClockEdge::Falling,
        eCxx::BitOrder::MSBFirst
    );

    valueW = ~valueR; // The switches are active low

    // Write the R/W values to UART
    App::uart().writeString( PGM_STR("R=") );
    App::uart().writeBinString(
        valueR,
        eCxx::Convert::NumSign::None_Minus,
        16,
        eCxx::Convert::NumPad::Zero,
        eCxx::Convert::NumFormat::Lowercase
    );

    App::uart().writeString( PGM_STR("     W=") );
    App::uart().writeBinString(
        valueW,
        eCxx::Convert::NumSign::None_Minus,
        16,
        eCxx::Convert::NumPad::Zero,
        eCxx::Convert::NumFormat::Lowercase
    );

    App::uart().write('\n');
}
