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


//
// For convenience
//
#ifdef ECXX_HAVE_PROGRAM_STRING_LITERALS
using namespace eCxx::program_string_literals;
#endif


//
// Helper functions
//
template <typename UART_T>
static void printSeparator(UART_T& u)
{
    u.writeString( PGM_STR("--------------------------------------------------------------------------------\n\n") );
    App::yield();
}


#ifdef ECXX_HAVE_PROGRAM_STRING_LITERALS

template <typename UART_T>
static void testProgramStringLiterals(UART_T& u)
{
    // Print separator
    printSeparator(u);

    // Test string literals in program memory by using literal operators for string literals
    u.writeStringln("Test printing string literal from RAM       "     );
    u.writeStringln("Test printing string literal from PGM (near)"_pgm );
    u.writeStringln("Test printing string literal from PGM (far )"_pgmf);
    u.write        ( '\n'                                              );
    App::yield();
}

#endif


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

    // Print some hardware information
    eCxx::uint8_t chipId[10];
    eCxx::HWInfo::chipId(chipId);

    u.write      ( '\n'                                          );
    u.write      ( '\n'                                          );
    u.writeString( PGM_STR("eCxx     version                : ") ); u.writeStringln      ( eCxx::HWInfo::eCxxVersion     ()               );
    u.writeString( PGM_STR("Compiler version                : ") ); u.writeStringln      ( eCxx::HWInfo::compilerVersion ()               );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Device name                     : ") ); u.writeStringln      ( eCxx::HWInfo::deviceName      ()               );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Chip signature                  : ") ); u.writeHexSeqStringln( eCxx::HWInfo::chipSignature   (), true, true   );
    u.writeString( PGM_STR("Chip identification             : ") ); u.writeHexSeqStringln( chipId, sizeof(chipId),           true, true   );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("CPU frequency           ( Hz  ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::cpuFrequency    (), 9            );
    u.writeString( PGM_STR("CPU frequency           (kHz  ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::cpuFrequency_kHz(), 9            );
    u.writeString( PGM_STR("CPU frequency           (MHz  ) : ") ); u.writeDecStringln   ( eCxx::HWInfo::cpuFrequency_MHz(), 9            );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Total RAM      size     (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::totalRAMSize    (), 9            );
    u.writeString( PGM_STR("Total flash    size     (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::totalFlashSize  (), 9            );
    u.writeString( PGM_STR("Total EEPROM   size     (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::totalEEPROMSize (), 9            );
    u.write      ( '\n'                                          );
    App::yield();
    u.writeString( PGM_STR("Raw NV-storage size     (bytes) : ") ); u.writeDecStringln   ( eCxx::HWInfo::rawNVStorageSize(), 9            );
    u.writeString( PGM_STR("EEPROM is emulated              : ") ); u.writeStringln      ( eCxx::Bool( eCxx::HWInfo::eepromIsEmulated() ) );
    u.write      ( '\n'                                          );
    App::yield();

    // Print separator
    printSeparator(u);

    // Return the UART object
    return u;
}
