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/inc/BaseboardIO.h

Committer:
mbriggs_vortex
Date:
2017-11-29
Revision:
100:0882cf295f8e
Parent:
98:3609f600c2f5

File content as of revision 100:0882cf295f8e:

/*
 * baseboardIO.h
 *
 *  Created on: Jan 25, 2017
 *      Author: mbriggs
 */
#include "DS2408.h"

#ifndef BASEBOARDIO_H_
#define BASEBOARDIO_H_

const uint16_t BASEBOARDIO_NVM_START_ADDR = 0x1100;
const uint16_t BASEBOARDIO_NVM_SIZE = 32; // Bytes
const uint16_t BASEBOARDIO_FLAG = 0x5A00;
const uint16_t BASEBOARDIO_REV = 0x0000;
#define ALSO_USE_LRR_LED 1  // Only set to 1 for debug otherwise it is a waste of power

class NvmBBIOObj {
public:
    NvmBBIOObj();
    void setDefaults();
    CmdResult fromBytes(uint8_t *data, uint8_t size);
    CmdResult toBytes(uint8_t *data, uint8_t &size);

    uint16_t getBaseboardIOFlag();
    bool validBaseboardIOFlag();
    uint16_t getBaseboardIORev();
    bool validBaseboardIORev();

    uint16_t getSerialNum();
    void setSerialNum(uint16_t in);
    uint32_t getBaseboardIOConfig();
    void setBaseboardIOConfig(uint32_t in);
    void getPortExpanderROM0(uint8_t *addr);
    void setPortExpanderROM0(const uint8_t *addr);
    void getPortExpanderROM1(uint8_t *addr);
    void setPortExpanderROM1(const uint8_t *addr);
    // Make public to save memory
    uint8_t mPortExpanderROM0[8];
    uint8_t mPortExpanderROM1[8];

private:
    uint16_t mBaseboardIOFlag;
    uint16_t mBaseboardIORev;
    uint16_t mSerialNum;
    uint16_t mBaseboardIOConfig;
};

/**
 *  @class BaseboardIO
 *  @brief This class abstracts utilizing the IO mostly found on the baseboard
 *  this includes IO which is implemented via portExpanders.  This API currently
 *  does not implement interfaces for communications like UART or for memory like
 *  flash devices.
 */
class BaseboardIO
{
public:
    static const PinName OneWireMasterPinName  = I2C_SDA;
    static const PinName CCInPinName           = WAKE; // Interrupt pin PA_0
    static const PinName TamperPinName         = GPIO1; // Interrupt pin PA_5
    static const PinName PairBtnPinName        = UART_CTS; // Interrupt pin PA_11
    static const PinName LedPinName            = GPIO3;
    static const PinName LrrLedPinName         = GPIO0;
    static const PinName SwitchedIOCtrlPinName = I2C_SCL;

    /**
    * @brief BaseboardIO constructor
    *
    * @details Just initialized internal variables does not configure devices.
    * Should call init before other functions are called.
    *
    * On Entry:
    *
    * On Exit:
    * Internal variables are set to a known state but futher initialziation is required
    *
    * @return
    */
    BaseboardIO();

    /**
    * @brief Initialize IO to current values
    *
    * @details Initialize IO to current state and ensure that class variables
    * are updated to latest values.  The following are initialized.
    * 1.  PortExpanders are setup are read
    * 2.  Relay is forced to known state
    * 3.  Interrupts are setup
    *
    * On Entry:
    *
    * On Exit:
    * Either IO is configured or an error is returned
    *
    * @return CmdResult
    */
    CmdResult init()
    {
        return init(false);  // By default do not overwrite NVM
    }
    CmdResult init(bool overwriteNvm);

    ////////////////////////////////
    // Registering for interrupts //
    ////////////////////////////////
    /**
    * @brief Register for contact closure interrupt
    *
    * @details Pass function pointer which will be called when interrupt occurs.
    *
    * On Entry:
    *
    * On Exit:
    * Callback registered
    *
    * @return
    */
    void regCCInInt(Callback<void()> func);

    /**
    * @brief Register for tamper interrupt
    *
    * @details Pass function pointer which will be called when interrupt occurs.
    *
    * On Entry:
    *
    * On Exit:
    * Callback registered
    *
    * @return
    */
    void regTamperInt(Callback<void()> func);

    /**
    * @brief Register for pair button interrupt
    *
    * @details Pass function pointer which will be called when interrupt occurs.  Note
    * there is a hardware switch which can prevent the tamper sensor from pulling the line
    * down.  If this switch deasserted there is no way in software to reconfigure this.
    *
    * On Entry:
    *
    * On Exit:
    * Callback registered
    *
    * @return
    */
    void regPairBtnInt(Callback<void()> func);

    ///////////
    // Input //
    ///////////
    /**
    * @brief samples current IO including port expanders
    *
    * @details Samples values and stores them so that IO accessors can execute quicker.
    *
    * Future:
    * Add some detail about how robust the values displayed here are.
    * It might be a good idea to add a timestamp for this IO
    *
    * On Entry:
    *
    * On Exit:
    * Internal class variables are updated or error is returned.
    *
    * @return CmdResult
    */
    CmdResult sampleUserSwitches();

    /**
    * @brief Returns the current state of the pair button
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the button is depressed than true is returned other wise false
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isPairBtn();
    bool isCCInAlert();

    /**
    * @brief Returns the current state of the NO/NC switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the switch is in asserted position that the devices is normally closed (NC)
    *  therefore false is returned.  Otherwise device is normally open (NO) and therefore
    *  returns true.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isCCNO();

    void setIsCCNO(bool val);

    void setIsCCNC(bool val) {setIsCCNO(!val);}

    /**
    * @brief Returns the current state of the NO/NC switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the switch is in asserted position that the devices is normally closed (NC)
    *  therefore true is returned.  Otherwise device is normally open (NO) and therefore
    *  returns false.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isCCNC() {return !isCCNO();}

    /**
    * @brief Returns the current state of the Rx/Tx switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the switch is in asserted position that the devices is transmitter (Tx)
    *  therefore false is returned.  Otherwise device is a receiver(Rx) and therefore
    *  returns true.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isRx();

    void setIsRx(bool val);

    void setIsTx(bool val) {setIsRx(!val);}

    /**
    * @brief Returns the current state of the Rx/Tx switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the switch is in asserted position that the devices is transmitter (Tx)
    *  therefore true is returned.  Otherwise device is a receiver(Rx) and therefore
    *  returns false.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isTx() {return !isRx();}

    /**
    * @brief Returns the current state of the LoRaWAN switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If the switch is in asserted position that the device is will report via LoRaWAN
    * otherwise the device will use peer-to-peer mode.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isLoRaWANMode();

    /**
    * @brief Returns the current state of the serial switch
    *
    * @details This just simply uses the last sample of the IO to return a bool.
    * If enabled then the serial chip will be listening for traffic at least in
    * the case of a TX.
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return bool
    */
    bool isSerialEnabled();

    /**
    * @brief Returns value of a rotary switch (TODO give board location)
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return uint8_t
    */
    uint8_t rotarySwitch1();

    void setRotarySwitch1(uint8_t val);

    /**
    * @brief Returns value of a rotary switch (TODO give board location)
    *
    * On Entry:
    * IO should be sampled recently
    *
    * On Exit:
    *
    * @return uint8_t
    */
    uint8_t rotarySwitch2();

//    void setRotarySwitch2(uint8_t val);

    ////////////
    // Output //
    ////////////
    /**
    * @brief Turns LED on
    *
    * @return CmdResult
    */
    CmdResult ledOn();

    /**
    * @brief Turns LED off
    *
    * @return CmdResult
    */
    CmdResult ledOff();

    /**
    * @brief Changes state of relay to alert
    *
    * @details If the configured as normally open then the relay closes and
    * vice versa for normally closed.
    *
    * @return CmdResult
    */
    CmdResult relayAlert();

    /**
    * @brief Changes state of relay to normal
    *
    * @details If the configured as normally open then the relay opens and
    * vice versa for normally closed.
    *
    * @return CmdResult
    */
    CmdResult relayNormal();

    /**
    * @brief Enables/disables serial chip
    *
    * @details This controls IO to ON/~OFF pin of RS232 chip.  If transmitting
    * ensure serialTx is called as well.
    *
    * @return CmdResult
    */
    CmdResult serialRx(bool enable);

    /**
    * @brief Controls serial chip transmission
    *
    * @details This controls IO to Tx_DIS pin of RS232 chip.  Note calling this function will
    * also enable serialRx.
    *
    * @return CmdResult
    */
    CmdResult serialTx(bool enable);

    CmdResult prepareSleep();
    CmdResult exitSleep();

private:
    // Initialized during constructor
    NvmBBIOObj mNvmObj;
    OneWire mOWMaster;
    InterruptIn mCCIn;
    InterruptIn mTamper;
    InterruptIn mPairBtn;
    DigitalOut mLed;
    DigitalOut mLrrLed;
    DigitalOut mSwitchedIOCtrl;

//    uint8_t mPortExpanderROM0[8]; // FIXME could probably get rid of
    uint8_t mPortExpanderVal0;
//    uint8_t mPortExpanderROM1[8];
    uint8_t mPortExpanderVal1;

    DS2408 *mPortEx0;
    DS2408 *mPortEx1;

    void enableSwitchedIO () {
        mSwitchedIOCtrl = 0; // assert since PMOS
    }
    void disableSwitchedIO () {
        mSwitchedIOCtrl = 1; // deassertted since PMOS
    }

    /**
    * @brief Reads baseboard information from non-volatile memory (NVM)
    *
    * @details This data is read from the xDot's internal EEPROM.  This
    * method is called from init().  The following
    * is stored:
    * 1.  Storage code word
    * 2.  8-bit Baseboard configuration data
    * 3.  8-bit Baseboard revision data
    * 4.  16-bit Baseboard serial number
    * 5.  2 x 64-bit OneWire ROM port expander addresses
    *
    * TODO add memory map information
    *
    * @return CmdResult
    */
    CmdResult readInfoFromNVM();

    /**
    * @brief Stores baseboard information to non-volatile memory (NVM)
    *
    * @details This method is called during special configuration events like first time boot or factory reset.
    *
    * TODO add memory map information
    *
    * @return CmdResult
    */
    CmdResult writeInfoToNVM();

    /**
    * @brief Scans OneWire bus for port expanders and attempts to identify each.
    *
    * @details For this method to succeed switches must be in factory reset positions.
    * Rotary 1 and 2 should be at 0
    * DIP Switches should be fully closed
    *
    * @return CmdResult
    */
    CmdResult identifyPortExpanders();

    /**
     * @brief Forces relay to closed state
     *
     * @details Note coil assertion timing is done here
     *
     * @return CmdResult
     */
    CmdResult closeRelay();

    /**
     * @brief Forces relay to open state
     *
     * @details Note coil assertion timing is done here
     *
     * @return CmdResult
     */
    CmdResult openRelay();
};


#endif /* BASEBOARDIO_BASEBOARDIO_H_ */