Fork to see if I can get working

Dependencies:   BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated

Fork of xDotBridge_update_test20180823 by Matt Briggs

xDotBridge/src/main.cpp

Committer:
Matt Briggs
Date:
2017-03-14
Revision:
64:46c8819c07cc
Parent:
63:e1efbe3402d9
Child:
65:d546060aa03d

File content as of revision 64:46c8819c07cc:

#include <math.h>
#include "config.h"
#include "xdot_flash.h"
#include "dot_util.h"
#include "RadioEvent.h"
#include "WinbondSPIFlash.h"
#include "UserInterface.h"
//#include <xdot_low_power.h>
#include "mDot.h"
#include "MyLog.h"

#include "BaseboardIO.h"
#include "CommProtocolPeerBrute.h"

#ifndef __TEST__ // Exclude code for tests
Serial pc(USBTX, USBRX);

mDot* dot = NULL; // Used by dot-utils

volatile bool ccIntFlag;
volatile bool tamperIntFlag;
volatile bool pairBtnIntFlag;
void ccInIntCallback () {
    ccIntFlag = true;
}
void tamperIntCallback () {
    tamperIntFlag = true;
}
void pairBtnIntCallback () {
    pairBtnIntFlag = true;
}

int main() {
    CommProtocolPeerBrute *protocol = new CommProtocolPeerBrute();
    BaseboardIO *bbio = new BaseboardIO();
    WinbondSPIFlash *flash = new WinbondSPIFlash(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_NSS);

    CmdResult result;
    ccIntFlag = false;
    tamperIntFlag = false;
    pairBtnIntFlag = false;
    pc.baud(115200);

    RadioEvent events;  // Custom event handler for automatically displaying RX data

    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
    MyLog::setLogLevel(MyLog::INFO_LEVEL);

    dot = mDot::getInstance();

    // make sure library logging is turned on
//    dot->setLogLevel(mts::MTSLog::WARNING_LEVEL);
    dot->setLogLevel(mts::MTSLog::WARNING_LEVEL);

    myLogInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
    myLogInfo("libxDot-mbed5 library ID: %s", dot->getId().c_str());

    // attach the custom events handler
    dot->setEvents(&events);  // Little bonus event debug information

    // Finish radio init
    myLogInfo("= Protocol Init Starting                     =\r\n");
    protocol->init();
    if (result == cmdSuccess) {
        myLogInfo("= Protocol Init Finished Successfully    =\r\n");
    }
    else {
        myLogInfo("= Protocol Init Finished with Error      =\r\n");
    }
    protocol->printDotConfig();

    // save changes to configuration
//    logInfo("saving configuration");
//    core_util_critical_section_enter();
//    bool dotConfigSaved = dot->saveConfig();
//    core_util_critical_section_exit();
//    if (!dotConfigSaved) {
//        logError("failed to save configuration");
//    }

    // Setup programmable voltage detector
    // PVD_LEVEL0 Falling 1.85
    // PVD_LEVEL1 Falling 2.04
    // PVD_LEVEL2 Falling 2.24
    // PVD_LEVEL3 Falling 2.44
    // PVD_LEVEL4 Falling 2.64
    // PVD_LEVEL5 Falling 2.84
    // PVD_LEVEL6 Falling 3.05
//    PWR_PVDTypeDef pvdConfig;
//    pvdConfig.Mode = PWR_PVD_MODE_NORMAL;
//    pvdConfig.PVDLevel = PWR_PVDLEVEL_5;
//
//    HAL_PWR_ConfigPVD(&pvdConfig);
//    HAL_PWR_EnablePVD();
//    logInfo("Programmable Voltage Detector set for level: %d", pvdConfig.PVDLevel);
//    // HAL_PWR_PVDCallback need to define this I think this will override the current implementation

    dot->setWakeMode(mDot::RTC_ALARM_OR_INTERRUPT);
    dot->setWakePin(UART1_RX);

    display_config();  // Print configuration for now

    // display configuration
//    display_config();

    myLogInfo("= Baseboard Init Starting                     =\r\n");
    result = bbio->init();
    if (result == cmdSuccess) {
        myLogInfo("= Baseboard Init Finished Successfully    =\r\n");
    }
    else {
        myLogInfo("= Baseboard Init Finished with Error      =\r\n");
    }
    LedPatterns ledPatterns(bbio);

    uint16_t txSeqNum=0;
    uint16_t rxSeqNum=0;
    Callback<void()> ccInIntObj (&ccInIntCallback);
    Callback<void()> tamperIntObj (&tamperIntCallback);
    Callback<void()> pairBtnIntObj (&pairBtnIntCallback);

    bbio->sampleUserSwitches();
    bbio->relayNormal(); // Always force relay in known state
    bbio->regCCInInt(ccInIntObj);
    bbio->regTamperInt(tamperIntObj);
    bbio->regPairBtnInt(pairBtnIntObj);

    // Start flash powered down
    flash->powerDown();

    unsigned int loopCnt = 0; // Just a quick temp varaible to keep track of loopNums
    bool prevCCNormallyOpen;
    PairBtnState pairBtnState;
    /**
     * Main Loop
     */
    while (true) {
        std::vector<uint8_t> data;
        ledPatterns.turnOff();

        // Sample IO and update any configuration
        prevCCNormallyOpen = bbio->isCCNO();
        bbio->sampleUserSwitches();
        if (prevCCNormallyOpen == bbio->isCCNO()) { // Only activate the coil if the DIP SW has changed
            bbio->regCCInInt(ccInIntObj);
            bbio->relayNormal();
        }
        if (bbio->isTx()) {
            protocol->setTx(true);
        }
        else { // RX
            protocol->setTx(false);
        }
        // End sample and update
        // Pair logic
        if (pairBtnIntFlag) {
            pairBtnState = PairBtnInterp::read(bbio);
            if (protocol->isTx()) {
                if (pairBtnState == pairBtnMediumPress) {
//                    protocol->sampleDLC();
                    protocol->configForPairingNetwork();
                    protocol->sendPairReq();
                    myLogInfo("Sent pair request.  Waiting %f secs for accept.", TX_ACCEPT_WAIT_TIME);
                    result = protocol->waitForAccept(TX_ACCEPT_WAIT_TIME);
                    if (result == cmdSuccess) {
                        myLogInfo("Got accept");
                        ledPatterns.turnOff();
                        wait(0.5);
                        ledPatterns.tripleBlink();
                    }
                    else {
                        myLogInfo("Did not receive accept");
                    }
                    protocol->configForSavedNetwork();
                    protocol->printDotConfig();
                    protocol->resetCounters();
                }
            }
            if (protocol->isRx()) {
                if (pairBtnState == pairBtnMediumPress) {
//                    protocol->sampleDLC();
                    protocol->configForPairingNetwork();
                    ledPatterns.turnOn();
                    myLogInfo("Waiting for pair request for %f seconds", RX_PAIR_WAIT_TIME);
                    result = protocol->waitForPairing(RX_PAIR_WAIT_TIME);
                    ledPatterns.turnOff();
                    if (result == cmdSuccess) {
                        myLogInfo("Got pair request and responded");
                        ledPatterns.tripleBlink();
                    }
                    else if (result == cmdTimeout) {
                        myLogInfo("Did not receive request");
                    }
                    else {
                        myLogInfo("Unknown pair error");
                    }
                    protocol->configForSavedNetwork();
                    protocol->printDotConfig();
                    protocol->resetCounters();
                }
                else if (pairBtnState == pairBtnLongPress) {
                    myLogInfo("Clearing pair values and generating new ones.");
                    protocol->clearPair();
                    protocol->printDotConfig();
                    ledPatterns.tenBlinks();
                    protocol->resetCounters();
                }
            }
        }

        // Alert code
		if (protocol->isTx()) {
            myLogInfo("Loop #%d. CCFlag %d, CCAlertState %d, TamperFlag %d, PairBtnFlag %d",
                    loopCnt, ccIntFlag, bbio->isCCInAlert(), tamperIntFlag, pairBtnIntFlag);
            // TODO add tamper
		    if (ccIntFlag || // If contact closure in
		       bbio->isCCInAlert() || // If closure remains in effect
		       (pairBtnIntFlag && (pairBtnState == pairBtnShortPress))) {
                ccIntFlag = false;
                ledPatterns.turnOn();

                data.clear();
                data.push_back((txSeqNum >> 8) & 0xFF);
                data.push_back(txSeqNum & 0xFF);
                std::string dataStr(data.begin(), data.end());
                myLogInfo("Sent msg num: %d, payload: %s", txSeqNum, dataStr.c_str());
                protocol->send(data);
                txSeqNum++;
                ledPatterns.turnOff();
		    }

            ledPatterns.turnOff();
            pairBtnIntFlag = false;
            tamperIntFlag = false;
            bbio->prepareSleep();
		    if (bbio->isCCInAlert()) { // Still in alert mode
                dot->sleep(2, mDot::RTC_ALARM_OR_INTERRUPT, false);  // Go to sleep and check in 2 secs if CCInAlert is asserted
		    }
		    else {
                dot->sleep(0, mDot::INTERRUPT, false);  // Go to sleep until wake button
		    }
		    bbio->exitSleep();
		}

		if (protocol->isRx()) {
		    bool msgPending;
		    protocol->listen(msgPending);
		    myLogInfo("Loop Cnt %d.  Listening.", loopCnt);
		    if (msgPending) {
		        data.clear();
		        protocol->recv(data);
                std::string dataStr(data.begin(), data.end());
                myLogInfo("Got msg num: %d, payload: %s", rxSeqNum, dataStr.c_str());
                bbio->relayAlert();
                rxSeqNum++;
                ledPatterns.turnOn();
                // Hold time for alert
                // TODO maybe use sleep instead of wait
                myLogInfo("Holding alert for %f secs", HoldTimeSetting::rotVal2Sec(bbio->rotarySwitch1()));
                wait(HoldTimeSetting::rotVal2Sec(bbio->rotarySwitch1()));
                ledPatterns.turnOff();
                bbio->relayNormal();
		    }
            myLogInfo("Sleeping.  Time %d", us_ticker_read());
//            protocol->sampleDLC();
            bbio->prepareSleep();
            dot->sleep(2, mDot::RTC_ALARM_OR_INTERRUPT, false);  // Go to sleep until wake button
            bbio->exitSleep();
		}

		protocol->resetCounters();
        myLogInfo("\r\n================================");
        loopCnt++;
    }

    delete protocol;
    delete bbio;
    return 0;
}
#endif