/*
 * This is a simple example file to show how to use the WiMOD Arduino
 * library to communicate with a WiMOD Module by IMST GmbH
 *
 * http://www.wireless-solutions.de
 *
 */

/*
 * Example:
 *
 * This example demonstrates how to use the RadioLink feature of the LoRaWAN
 * ProLink firmware of the WiMOD.
 *
 * Setup requirements:
 * -------------------
 * - 1 WiMOD module running LoRaWAN ProLinkEndNode Modem firmware
 *
 * Usage:
 * -------
 * Start the program and watch the serial monitor @ 115200 baud
 *
 */

// make sure to use only the WiMODProLink.h
#include <WiMODProLink.h>

//-----------------------------------------------------------------------------
// platform defines
//-----------------------------------------------------------------------------
/*
 * Note: This sketch is for Arduino devices with two separate serial interfaces
 * (e.g. DUE). One interface is connected to a PC and one is used for WiMOD.
 *
 * For single serial interface boards (e.g. UNO) it is recommended to disbale
 * the PC / Debug messages
 */

#define WIMOD_IF    Serial1        // for WiMODino use: SerialWiMOD
#define PC_IF    SerialUSB          // for WiMODino use: SerialUSB

/*
 * Create in instance of the interface to the WiMOD LoRaWAN ProLink firmware
 */
WiMODProLink wimod(WIMOD_IF);  // use the Arduino Serial3 as serial interface

//-----------------------------------------------------------------------------
// section code
//-----------------------------------------------------------------------------

/*****************************************************************************
 * Function for printing out some debug infos via serial interface
 ****************************************************************************/
void debugMsg(String msg) {
    PC_IF.print(msg);  // use default Arduino serial interface
}

/*****************************************************************************
 * print out a welcome message
 ****************************************************************************/
void printStartMsg() {
    debugMsg(F("==================================================\n"));
    debugMsg(F("This is FileName: "));
    debugMsg(F(__FILE__));
    debugMsg(F("\r\n"));
    debugMsg(F("Starting...\n"));
    debugMsg(F("This simple demo will show \n"));
    debugMsg(
            F(
                    "how to use the RadioLink feature of the a WiMOD radio module\n"));
    debugMsg(F("running the LoRaWAN ProLink Firmware.\n"));
    debugMsg(F("==================================================\n"));
}

/*****************************************************************************
 * Arduino setup function
 ****************************************************************************/
void setup() {
    // wait for the PC interface to be ready (max 10 sec); usefull for USB
    while (!PC_IF && millis() < 10000) {
    }

    // init / setup the serial interface connected to WiMOD
    WIMOD_IF.begin(WIMOD_PROLINK_SERIAL_BAUDRATE);
    // init the communication stack
    wimod.begin();

    // debug interface
    PC_IF.begin(115200);

    printStartMsg();

    delay(100);
}

static TWiMODLR_ProLinkRadioLink_RadioConfig radioCfg;
static TWiMODLR_RadioLink_Msg radioLinkMsg;

static uint32_t loopCnt = 0;

void loop() {
    loopCnt++;

    /*
     * every 10 sec the radio stack is being switch from LoRaWAN to proprietary
     * Mode (LR-BASE) and a demo message is transmitted.
     */
    if (!((loopCnt % 20) == 0) ) {
        // check for any pending data of the WiMOD
        wimod.Process();
    } else {

        // switch to the proprietary RadioLink mode / stack
        if (wimod.SetRadioStack(RadioStack_PROPRIETARY_LR_BASE)) {
            // ok, the proprietary stack mode is now active

            /*
             *  configure the stack.
             *  For Demo pursoses a full configuration is shown here
             */
            radioCfg.RadioMode      = ProLinkRadioMode_Standard;
            radioCfg.GroupAddress   = 0x10;
            radioCfg.DeviceAddress  = 0x1234;
            radioCfg.Modulation     = ProLinkModulation_LoRa;
            wimod.calcFreqToRegister(869525000, &radioCfg.RfFreq_MSB,
                                                &radioCfg.RfFreq_MID,
                                                &radioCfg.RfFreq_LSB);
            radioCfg.LoRaBandWidth       = ProLinkLoRaBandwith_125kHz;
            radioCfg.LoRaSpreadingFactor = ProLinkLoRa11_SF11;
            radioCfg.ErrorCoding         = ProLinkErrorCoding0_4_5;
            radioCfg.PowerLevel          = ProLinkTxPowerLevel0_5_dBm;
            radioCfg.RxControl           = ProLinkRxCtrl_Receiver_AlwaysOn;
            radioCfg.RxWindowTime        = 2000;
            radioCfg.MiscOptions = PROLINK_RADIOLINK_RADIO_CFG_MISC_EXTENDED_HCI_OUTPUT_FORMAT
                                   | PROLINK_RADIOLINK_RADIO_CFG_MISC_HCI_TX_IND_ENABLED;
            radioCfg.FskDatarate        = ProLinkFskDatarate_50kbps;

            if (!wimod.SetRadioLinkRadioConfig(&radioCfg)) {
                debugMsg(F("Error Error setting Radio Config\r\n"));
            } else {

                // prepare the proprietary message
                radioLinkMsg.DestinationGroupAddress  = 0x10;
                radioLinkMsg.DestinationDeviceAddress = 0x1234;
                radioLinkMsg.Length = strlen_P(PSTR("Hello World!"));
                strcpy_P((char*) radioLinkMsg.Payload, PSTR("Hello World!"));

                // send the message
                if (!wimod.SendRadioLinkUData(&radioLinkMsg)) {
                    debugMsg(F("Error sending data\r\n"));
                } else {
                    debugMsg(F("-> TX Done\r\n"));
                }
            }

            // switch back to LoRaWAN mode
            wimod.SetRadioStack(RadioStack_LoRaWAN);

        } else {
            debugMsg(F("Error switsching to RadioLink Stack - check for pending LoRaWAN stack operations\r\n"));
        }

        // check for any pending data of the WiMOD
        wimod.Process();
    }
    delay(500);
}
