![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
xDotBridge/src/main.cpp
- Committer:
- mbriggs_vortex
- Date:
- 2017-11-18
- Revision:
- 89:edfe5d376e55
- Parent:
- 81:1eb0f16b2ab9
- Child:
- 90:32f9d043561a
File content as of revision 89:edfe5d376e55:
#include "mbed.h" #include <math.h> #include "config.h" #include "xdot_flash.h" #include "dot_util.h" #include "RadioEvent.h" #include "BufferedSerial.h" #include "WinbondSPIFlash.h" #include "UserInterface.h" //#include <xdot_low_power.h> #include "ChannelPlans.h" #include "mDot.h" #include "MyLog.h" #include "SimpleRxSeqLog.h" #include "BaseboardIO.h" #include "CommProtocolPeerBrute.h" #include "SerialTermMgr.h" #define RX_SEQ_LOG 1 const float BridgeVersion = 1.01; // 232 Pins const PinName SER_TERM_TX = UART_TX; const PinName SER_TERM_RX = UART_RX; #ifndef __TEST__ // Exclude code for tests Serial pc(USBTX, USBRX); BufferedSerial *outPc; InterruptIn uart1RxIntIn (SER_TERM_RX); mDot* dot = NULL; // Used by dot-utils volatile bool uartRxFlag; volatile bool ccIntFlag; volatile bool tamperIntFlag; volatile bool pairBtnIntFlag; void uart1RxCallback () { uartRxFlag = true; } void ccInIntCallback () { ccIntFlag = true; } void tamperIntCallback () { tamperIntFlag = true; } void pairBtnIntCallback () { pairBtnIntFlag = true; } void testFunc() { const uint32_t test=0xDEADBEEF; printf("%d", test); } int main() { CommProtocolPeerBrute *protocol = new CommProtocolPeerBrute(); BaseboardIO *bbio = new BaseboardIO(); WinbondSPIFlash *flash = new WinbondSPIFlash(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_NSS); SerialTermMgr serialTermMgr(bbio, flash, BridgeVersion); pc.baud(115200); CmdResult result; uartRxFlag = false; ccIntFlag = false; tamperIntFlag = false; pairBtnIntFlag = false; RadioEvent events; // Custom event handler for automatically displaying RX data #if RX_SEQ_LOG SimpleRxSeqLog rxSeqLog(0x0000); rxSeqLog.read(); #endif mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL); MyLog::setLogLevel(MyLog::DEBUG_LEVEL); // use US915 plan lora::ChannelPlan* plan = new lora::ChannelPlan_US915(); // use EU868 plan // lora::ChannelPlan* plan = new lora::ChannelPlan_EU868(); assert(plan); dot = mDot::getInstance(plan); // make sure library logging is turned on 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()); myLogInfo("Vortex Wireless Bridge SW Version %0.2f", BridgeVersion); // 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(); dot->setWakeMode(mDot::RTC_ALARM_OR_INTERRUPT); dot->setWakePin(GPIO0); // dot->setWakePin(UART_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); uart1RxIntIn.rise(&uart1RxCallback); // Rising does appear to work better than falling edge uart1RxIntIn.enable_irq(); 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); if (bbio->isTx()) { protocol->setTx(true); } else { // RX protocol->setTx(false); } // Start flash powered down flash->powerDown(); unsigned int loopCnt = 0; // Just a quick temp variable to keep track of loopNums bool prevCCNormallyOpen; PairBtnState pairBtnState; uint32_t rxMsgCnt = 0; uint32_t maxSeenMsgSeqNum = 0; /** * Main Loop */ while (true) { // myLogInfo("Start of loop time %d", us_ticker_read()); ledPatterns.turnOff(); bbio->serialRx(true); // FIXME find a better home bbio->serialTx(false); // FIXME only turn on during TX // Pair logic and switch sampling if (pairBtnIntFlag) { pairBtnState = PairBtnInterp::read(bbio); // 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); } if (protocol->isTx()) { if (pairBtnState == pairBtnMediumPress) { 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(); // Clear test log rxSeqLog.clear(); rxSeqLog.save(); myLogInfo("NVM Cleared Seq Log"); } } if (protocol->isRx()) { if (pairBtnState == pairBtnMediumPress) { 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(); // Clear test log rxSeqLog.clear(); rxSeqLog.save(); myLogInfo("NVM Cleared Seq Log"); } else if (pairBtnState == pairBtnLongPress) { myLogInfo("Clearing pair values and generating new ones."); protocol->clearPair(); protocol->printDotConfig(); ledPatterns.tenBlinks(); protocol->resetCounters(); } } } else { pairBtnState = pairBtnNoPress; } pairBtnIntFlag = false; // Serial Terminal if (uartRxFlag) { pc.printf("Got RX Int\r\n"); uart1RxIntIn.disable_irq(); // pc.printf("Got uart flag!!!\r\n"); uartRxFlag = false; outPc = new BufferedSerial(SER_TERM_TX, SER_TERM_RX); outPc->baud(TERM_BAUD); serialTermMgr.regSerial(outPc); char c; if (outPc->readable()) { c = outPc->getc(); // Throw away the first char pc.printf("Got %d, %c\r\n", c, c); } outPc->printf("Starting Terminal...\r\n"); serialTermMgr.printScreen(); time_t termLastAction = time(NULL); bool quit = false; while(!quit && (time(NULL) < (termLastAction + TERM_TIMEOUT))) { if (outPc->readable()) { // pc.printf("Got %d\r\n", outPc->getc()); quit = serialTermMgr.input(); termLastAction = time(NULL); } } if (quit) { outPc->printf("Terminal quit resuming operation <press any key to reactivate>...\r\n"); } else { outPc->printf("Terminal timeout resuming operation <press any key to reactivate>...\r\n"); } wait(0.01); // Wait for end message to be shifted out serialTermMgr.regSerial(NULL); delete outPc; uart1RxIntIn.enable_irq(); } wait(0.1); myLogInfo("Loop #%d. isTX %d, CCFlag %d, CCAlertState %d, TamperFlag %d, PairBtnState %d", loopCnt, protocol->isTx(), ccIntFlag, bbio->isCCInAlert(), tamperIntFlag, pairBtnState); // Alert code if (protocol->isTx()) { // TODO add tamper if (ccIntFlag || // If contact closure in bbio->isCCInAlert() || // If closure remains in effect pairBtnState == pairBtnShortPress) { ccIntFlag = false; ledPatterns.turnOn(); myLogInfo("Sending msg num: %d.", protocol->getSeqNum()); protocol->sendAlert(0xBEEF); // TODO use this field to encode the alert type e.g. CCIN vs tamper ledPatterns.turnOff(); } ledPatterns.turnOff(); // tamperIntFlag = false; if (pairBtnIntFlag) {// An Interrupt happened during transmission continue; // Go straight to pair handling } bbio->prepareSleep(); if (bbio->isCCInAlert()) { // Still in alert mode // Sleep for 5 seconds to ensure that receiver does not miss a message sequence dot->sleep(5, mDot::RTC_ALARM_OR_INTERRUPT, false); // Go to sleep and check in 5 secs if CCInAlert is asserted } else { dot->sleep(0, mDot::INTERRUPT, false); // Go to sleep until interrupt event // wait(0.5); } bbio->exitSleep(); } if (protocol->isRx()) { ccIntFlag = false; // tamperIntFlag = false; // myLogInfo("Before listen time %d", us_ticker_read()); bool msgPending; protocol->listen(msgPending); if (msgPending) { std::vector<uint8_t> txEui; txEui.reserve(8); uint16_t data; uint32_t msgSeqNum; protocol->recvAlert(txEui, data, msgSeqNum); if (msgSeqNum > maxSeenMsgSeqNum) maxSeenMsgSeqNum = msgSeqNum; rxMsgCnt++; // for message myLogInfo("Got rxMsgCnt #%d, with Seqnum: %d", rxMsgCnt, msgSeqNum); bbio->relayAlert(); ledPatterns.turnOn(); myLogInfo("Holding alert for %f secs", HoldTimeSetting::rotVal2Sec(bbio->rotarySwitch1())); // Hold time for alert // TODO maybe use sleep instead of wait wait(HoldTimeSetting::rotVal2Sec(bbio->rotarySwitch1())); ledPatterns.turnOff(); bbio->relayNormal(); } if (pairBtnIntFlag) {// An Interrupt happened during reception continue; // Go straight to pair handling } //// TEMP LOGGING #if RX_SEQ_LOG if ((loopCnt % 1000 == 0) && rxMsgCnt > rxSeqLog.rxMsgCount()) { rxSeqLog.setLoopCount(loopCnt); rxSeqLog.setRxMsgCount(rxMsgCnt); rxSeqLog.setMaxSeenMsgSeqNum(maxSeenMsgSeqNum); rxSeqLog.save(); myLogInfo("EEPROM Saved."); } myLogInfo("NVM Log: Loop Cnt: %d, RxMsgCnt %d, MaxSeenSeqNum %d", rxSeqLog.loopCount(), rxSeqLog.rxMsgCount(), rxSeqLog.maxSeenMsgSeqNum()); #endif myLogInfo("Sleeping. Time %d", us_ticker_read()); 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