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-02-22
Revision:
53:a1563574a980
Parent:
52:64a2c71c7c49
Child:
54:c04d7b6fa075

File content as of revision 53:a1563574a980:

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

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

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

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

//DigitalOut gpio3(GPIO3, 1); // Flash ~hold signal

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();
    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);

    dot = mDot::getInstance();

    logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);

    // start from a well-known state
    logInfo("defaulting Dot configuration");
    dot->resetConfig();

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

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

    // Finish radio init
    protocol->init();

    // 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->setWakePin(GPIO3);


    // display configuration
//    display_config();

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

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

    bbio->sampleUserSwitches();
    bbio->relayNormal(); // Always force relay in known state

    unsigned int intCnt = 0; // Just a quick temp varaible to keep track of ints
    /**
     * Main Loop
     */
    while (true) {
        std::vector<uint8_t> data;
        bbio->ledOff();

        // Sample IO and update any configuration
        bool prevCCNormallyOpen = bbio->isCCNO();
        bbio->sampleUserSwitches();
        if (prevCCNormallyOpen == bbio->isCCNO()) { // Only activate the coil if the DIP SW has changed
            bbio->regCCInInt(ccInIntObj);
            bbio->regTamperInt(tamperIntObj);
            bbio->regPairBtnInt(pairBtnIntObj);
            bbio->relayNormal();
        }
        if (bbio->isTx()) {
            protocol->setTx(true);
        }
        else { // RX
            protocol->setTx(false);
        }
        // End sample and update

		if (protocol->isTx()) {
            logInfo("Got int #%d. CCFlag %d, TamperFlag %d, PairBtnFlag %d",
                    intCnt, ccIntFlag, tamperIntFlag, pairBtnIntFlag);
            // TODO add tamper
            if (pairBtnIntFlag) { // Wait up to 1 second for short button hit
                for (int i=0; i<10;i++) {
                    if (bbio->isPairBtn() == false){ // Button released
                        break;
                    }
                    wait(0.1);
                }
            }
		    if (ccIntFlag || // If contact closure in
		       (pairBtnIntFlag && (bbio->isPairBtn() == false))) { // If short pair btn hit

                ccIntFlag = false;
                tamperIntFlag = false;
                pairBtnIntFlag = false;
                #if LED_FEEDBACK
                bbio->ledOn();
                #endif

                data.push_back((seqNum >> 8) & 0xFF);
                data.push_back(seqNum & 0xFF);
                protocol->send(data);
                seqNum++;
                wait(0.5); // Leave the LED on so a person can see it.
		    }

            bbio->ledOff();
//            sleep_save_io();
//            sleep_configure_io();
            dot->sleep(0, mDot::INTERRUPT, false);  // Go to sleep until wake button
//            sleep_restore_io();
		}

		if (protocol->isRx()) {
		    bool msgPending;
		    protocol->listen(msgPending);
		    logInfo("Listening.");
		    if (msgPending) {
		        protocol->recv(data);
                std::string dataStr(data.begin(), data.end());
                logInfo("Got msg num: %d, payload: %s", seqNum, dataStr.c_str());
                bbio->relayAlert();
                seqNum++;
                #if LED_FEEDBACK
                bbio->ledOn();
                #endif
                wait(0.5); // TODO this should be configurable
		    }
            bbio->ledOff();
            bbio->relayNormal();
            logInfo("Sleeping.  Time %d", us_ticker_read());
//            sleep_save_io();
//            sleep_configure_io();
            // TODO maybe add if statement here to prevent double hits by sleeping for a longer time
            dot->sleep(2, mDot::RTC_ALARM_OR_INTERRUPT, false);  // Go to sleep until wake button
//            sleep_restore_io();
		}

		// TODO maybe a good place to put pairing logic

        logInfo("================================");
        wait(1.0);
        // Need to re-implement some of these sleep functions
//		sleep_save_io();
//		sleep_configure_io();
        intCnt++;
    }

    return 0;
}
#endif