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/SerialTermMgr.cpp

Committer:
Matt Briggs
Date:
2017-05-16
Revision:
76:d1b20a259d8f
Parent:
75:600cb3a9f126
Child:
77:176e3eb8f712

File content as of revision 76:d1b20a259d8f:

/*
 * SerialTermMgr.cpp
 *
 *  Created on: May 8, 2017
 *      Author: mbriggs
 */

#include "SerialTermMgr.h"
#include "UserInterface.h"

extern Serial pc;
const char ACK = 0x06;
const char NAK = 0x15;

SerialTermMgr::SerialTermMgr(BaseboardIO *bbio, float fwVersion)
{
    mPc = NULL;
    mFwVersion = fwVersion;
    mCurrScreen = mainScreenId;
    mBbio = bbio;
}
void SerialTermMgr::printScreen()
{
    switch (mCurrScreen) {
    case mainScreenId:
        printMainScreen();
        break;
    case genInfoScreenId:
        printGenInfo();
        break;
    case settingsScreenId:
    case statsScreenId:
    case errorLogScreenId:
    case liveLogScreenId:
    case enterSerialBridgeScreenId:
        printMainScreen();
        break;
    case enterProgModeScreenId:
        printEnterProgMode();
    }
}
bool SerialTermMgr::input()
{
    if (mPc == NULL) {
        return true;
    }
    bool quit = false;
    char c = 10;
    if (mPc->readable()) {
        c = mPc->getc();
    }
    else {
        return false;  // Do nothing if there is no input
    }
    switch (mCurrScreen) {
    case mainScreenId:
        quit = inputMainPage(c);
        break;
    case genInfoScreenId:
        inputGenInfo(c);
        break;
    case settingsScreenId:
    case statsScreenId:
    case errorLogScreenId:
    case liveLogScreenId:
    case enterSerialBridgeScreenId:
        inputMainPage(c);
        break;
    case enterProgModeScreenId:
        inputEnterProgMode(c);
    }
    return quit;
}

// private methods
bool SerialTermMgr::inputMainPage (char in) {
    bool quit = false;
    switch (in) {
    case '1':
        mCurrScreen = genInfoScreenId;
        break;
    case '2':
        mPc->printf("\r\nNot implemented yet.\r\n");
//        mCurrScreen = settingsScreenId;
        break;
    case '3':
        mPc->printf("\r\nNot implemented yet.\r\n");
//        mCurrScreen = statsScreenId;
        break;
    case '4':
        mPc->printf("\r\nNot implemented yet.\r\n");
//        mCurrScreen = errorLogScreenId;
        break;
    case '5':
        mPc->printf("\r\nNot implemented yet.\r\n");
//        mCurrScreen = liveLogScreenId;
        break;
    case '6':
        mPc->printf("\r\nNot implemented yet.\r\n");
//        mCurrScreen = enterSerialBridgeScreenId;
        break;
    case '7':
        mCurrScreen = enterProgModeScreenId;
        break;
    case 0x11: // ctrl-q
        quit=true;
        break;
    default:
        mCurrScreen = mainScreenId;
    }
    if (!quit) {
        printScreen();
    }
    return quit;
}

void SerialTermMgr::printMainScreen()
{
    if (mPc == NULL) {
        return;
    }
    mPc->printf("\r\n\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= Wireless Bridge Terminal (Firmware: v%0.2f)  =\r\n", mFwVersion);
    mPc->printf("===============================================\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= Selection Options                           =\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= 0: Refresh (Enter and space also work)      =\r\n");
    mPc->printf("= 1: General information                      =\r\n");
    mPc->printf("= 2: Settings                                 =\r\n");
    mPc->printf("= 3: Statistics                               =\r\n");
    mPc->printf("= 4: Error log                                =\r\n");
    mPc->printf("= 5: Live log                                 =\r\n");
    mPc->printf("= 6: Enter serial bridge mode                 =\r\n");
    mPc->printf("= 7: Enter programming mode                   =\r\n");
    mPc->printf("= <ctrl>-q: Exit terminal                     =\r\n");
    mPc->printf("===============================================\r\n");
}

void SerialTermMgr::inputGenInfo (char in) {
    if (mPc == NULL) {
        return;
    }
    switch (in) {
    case 0x1B:
        mCurrScreen = mainScreenId;
        break;
    case 'r':
        mBbio->sampleUserSwitches();
        mPc->printf("User switches sampled.\r\n");
        break;
    default:
        mPc->printf("Invalid key.\r\n");
    }
    printScreen();
}

void SerialTermMgr::printGenInfo()
{
    if (mPc == NULL) {
        return;
    }
    mPc->printf("\r\n\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= General Info (ESC to return to main menu)   =\r\n", mFwVersion);
    mPc->printf("===============================================\r\n");
    mPc->printf("= Press r to sample user switch values        =\r\n"); // FIXME
    mPc->printf("===============================================\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= Firmware version: v%0.2f                     =\r\n", mFwVersion);
    //TODO
//    mPc->printf("= Radio EUI: %s =\r\n", mts::Text::bin2hexString(dot->getDeviceId()).c_str());
    mPc->printf("= Contact closure: %s            =\r\n", mBbio->isCCNO() ? "Normally open  " :
                                                                            "Normally closed");
    mPc->printf("= WB Mode: %s                        =\r\n", mBbio->isTx() ? "Transmitter" :
                                                                              "Receiver   ");
    mPc->printf("= Comm Mode: %s                     =\r\n", mBbio->isLoRaWANMode() ? "LoRaWAN     " :
                                                                                      "Peer-to-peer");
    mPc->printf("= Serial Mode: %s                       =\r\n", mBbio->isSerialEnabled() ? "Enabled " :
                                                                                            "Disabled");
    if (mBbio->isTx()) {
        mPc->printf("= Currently no rotary switches apply for TX   =\r\n");
    }
    else {
        mPc->printf("= Rotary 1 hold setting is %0.1f seconds        =\r\n", HoldTimeSetting::rotVal2Sec(mBbio->rotarySwitch1()));
        mPc->printf("= Rotary 2 currently does not apply for RX    =\r\n");
    }
    mPc->printf("===============================================\r\n");
}

void SerialTermMgr::printEnterProgMode()
{
    if (mPc == NULL) {
        return;
    }
    mPc->printf("\r\n\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= Serial Firmware Prog Mode (Esc to return)    =\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("===============================================\r\n");
    mPc->printf("= To program firmware:                         \r\n");
    mPc->printf("= 1: Have bin file ready                      =\r\n");
    mPc->printf("= 2: Hit <ctrl>-d to enter XMODEM mode        =\r\n");
    mPc->printf("= 3: In terminal program (such as teraterm)   =\r\n");
    mPc->printf("=    select transfer via XMODEM               =\r\n");
    mPc->printf("= 4: Programming may take up to a minute      =\r\n");
    mPc->printf("= 5: If successful terminal will print \"Success\" =\r\n");
    mPc->printf("= 6: Wireless Bridge will then automatically  =\r\n");
    mPc->printf("=    reboot with new firmware.                =\r\n");
    mPc->printf("===============================================\r\n");
}

void SerialTermMgr::inputEnterProgMode (char in) {
    if (mPc == NULL) {
        return;
    }
    switch (in) {
    case 0x1B:
        mCurrScreen = mainScreenId;
        break;
    case 0x04:
        xmodem2Flash();
        break;
    default:
        mPc->printf("Invalid key.\r\n");
    }
    printScreen();
}

bool SerialTermMgr::xmodem2Flash ()
{
    mPc->printf("Ready to receive file");
    // TODO may need to buffer input
    char packetBuf[132];
    unsigned char pktIdx = 0;
    time_t lastValidInput = 0;
    while (1) {
        if ((time(NULL)-lastValidInput) > XMODEM_TIMEOUT){
            mPc->printf("%c", 0x15); // Send NAK
            lastValidInput = time(NULL);
            pc.printf("Total chars: %d\r\n", pktIdx);
            pktIdx = 0;
        }
        if (mPc->readable()) {
            mPc->gets(packetBuf, 132);
            pc.printf("Got full packet.\r\n");
            for (int i=0; i<132; i++) {
                pc.printf("%02X", packetBuf[i]);
            }
//            if (pktIdx >= 132) {
//                pc.printf("Got full packet.\r\n");
//                for (int i=0; i<132; i++) {
//                    pc.printf("%02X", packetBuf[i]);
//                }
//            }
        }
    }
}