![](/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/BaseboardIO.cpp
- Committer:
- Matt Briggs
- Date:
- 2017-02-01
- Revision:
- 44:ece6330e9b57
- Parent:
- 41:9ef4c4d77711
- Child:
- 47:a68747642a7a
File content as of revision 44:ece6330e9b57:
/* * baseboardIO.cpp * * Created on: Jan 25, 2017 * Author: mbriggs */ #include "BaseboardIO.h" #include "MTSLog.h" const float coilOnTime = 0.030; // 30 ms // Port expander 0 const uint8_t pEx0232En = 0x01; const uint8_t pEx0232TxDis = 0x02; const uint8_t pEx0Rot1B1 = 0x04; const uint8_t pEx0Rot1B2 = 0x08; const uint8_t pEx0Rot1B4 = 0x10; const uint8_t pEx0Rot1B8 = 0x20; const uint8_t pEx0Rot2B1 = 0x40; const uint8_t pEx0Rot2B2 = 0x80; // Port expander 1 const uint8_t pEx1NoNcSel = 0x01; const uint8_t pEx1RxTxSel = 0x02; const uint8_t pEx1WanSel = 0x04; const uint8_t pEx1SerialEn = 0x08; // Labeled as reserved const uint8_t pEx1Rot2B8 = 0x10; const uint8_t pEx1Rot2B4 = 0x20; const uint8_t pEx1RlyB = 0x40; // This is actually a coil const uint8_t pEx1RlyA = 0x80; // This is actually a coil /** * Note for interrupt within uC cannot use two pins with the same numeric suffix (e.g. cannot * use both PA_0 and PB_0). Note 1, 6, 7, 8, and 13 are used by LoRa radio. */ BaseboardIO::BaseboardIO() : mOWMaster(I2C_SDA), mCCIn(WAKE), // Interrupt pin PA_0 mTamper(GPIO1), // Interrupt pin PA_5 mPairBtn(UART_CTS), // Interrupt pin PA_11 mLed(SWDIO), mSwitchedIOCtrl(I2C_SCL) { // mCCInIntCallback = NULL; // mTamperIntCallback = NULL; // mPairBtnIntCallback = NULL; std::memset(mPortExpanderROM0, 0x00, 8); std::memset(mPortExpanderROM1, 0x00, 8); mPortExpanderVal0 = 0x00; mPortExpanderVal1 = 0x00; mPortEx0 = NULL; mPortEx1 = NULL; } CmdResult BaseboardIO::init() { logError("Not implemented yet!!!"); // Setup port expanders CmdResult result = readInfoFromNVM(); if (result == cmdSuccess) { // Values stored just read them foo logError("Not implemented yet!!!"); } else { // EEPROM values not there or corrupt result = identifyPortExpanders(); // Get ROM addresses if (result != cmdSuccess) { logError("Error identifying port expanders"); return cmdError; } } mPortEx0 = new DS2408(&mOWMaster, mPortExpanderROM0); mPortEx1 = new DS2408(&mOWMaster, mPortExpanderROM1); // Put relay in known state logInfo("Baseboard IO initialization successful"); return cmdSuccess; } // Registering for interrupts void BaseboardIO::regCCInInt(Callback<void()> func) { // Pulled high, switched low mCCIn.fall(func); } void BaseboardIO::regTamperInt(Callback<void()> func) { // Pulled high, switched low mTamper.fall(func); } void BaseboardIO::regPairBtnInt(Callback<void()> func) { // Pulled low, switched high mPairBtn.rise(func); } // Input CmdResult BaseboardIO::sampleUserSwitches() { // Sample port expanders if (mPortEx0->pioLogicRead(mPortExpanderVal0) != cmdSuccess) { logError("Error reading port expander 0."); return cmdError; } if (mPortEx1->pioLogicRead(mPortExpanderVal1) != cmdSuccess) { logError("Error reading port expander 1."); return cmdError; } return cmdSuccess; } bool BaseboardIO::isPairBtn() { // Depressed button is high return mPairBtn.read() == 1; } bool BaseboardIO::isCCOutNO() { // When DIP switch is not closed (i.e. value reads high) assume NO return (mPortExpanderVal1 & pEx1NoNcSel) != 0; } bool BaseboardIO::isRx() { // When DIP switch is not closed (i.e. value reads high) assume RX return (mPortExpanderVal1 & pEx1RxTxSel) != 0; } bool BaseboardIO::isLoRaWANMode() { // When DIP switch is not closed (i.e. value reads high) assume P2P not WAN return (mPortExpanderVal1 & pEx1WanSel) == 0; } uint8_t BaseboardIO::rotarySwitch1() { // If a bit of a nibble is asserted then the port expander line is switched low. uint8_t val = 0; if ((mPortExpanderVal0 & pEx0Rot1B8) == 0) val |= 0x08; if ((mPortExpanderVal0 & pEx0Rot1B4) == 0) val |= 0x04; if ((mPortExpanderVal0 & pEx0Rot1B2) == 0) val |= 0x02; if ((mPortExpanderVal0 & pEx0Rot1B1) == 0) val |= 0x01; return val; } uint8_t BaseboardIO::rotarySwitch2() { // If a bit of a nibble is asserted then the port expander line is switched low. uint8_t val = 0; if ((mPortExpanderVal1 & pEx1Rot2B8) == 0) val |= 0x08; if ((mPortExpanderVal1 & pEx1Rot2B4) == 0) val |= 0x04; if ((mPortExpanderVal0 & pEx0Rot2B2) == 0) val |= 0x02; if ((mPortExpanderVal0 & pEx0Rot2B1) == 0) val |= 0x01; return val; } // Output CmdResult BaseboardIO::ledOn() { mLed = 1; return cmdSuccess; } CmdResult BaseboardIO::ledOff() { mLed = 0; return cmdSuccess; } CmdResult BaseboardIO::relayAlert() { if (isCCOutNO()) { // Normally Open return closeRelay(); } else { // Normally Close return openRelay(); } } CmdResult BaseboardIO::relayNormal() { if (isCCOutNO()) { // Normally Open return openRelay(); } else { // Normally Close return closeRelay(); } } // Future CmdResult BaseboardIO::serialRx(bool enable) { uint8_t val; mPortEx0->pioLogicRead(val); // Active low from port expander -> pmos -> 232 (active chip EN) if (enable) { val &= ~pEx0232En; } else { val |= pEx0232En; } if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { logError("Error enabling 232"); return cmdError; } return cmdSuccess; } CmdResult BaseboardIO::serialTx(bool enable) { uint8_t val; mPortEx0->pioLogicRead(val); // Active high tx disable therefore active low tx enable (note chip must also be enabled for TX) if (enable) { val &= ~pEx0232TxDis; } else { val |= pEx0232TxDis; } if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { logError("Error enabling 232 TX"); return cmdError; } return cmdSuccess; } // private CmdResult BaseboardIO::readInfoFromNVM() { logError("Not implemented yet!!!"); return cmdError; } CmdResult BaseboardIO::writeInfoToNVM() { logError("Not implemented yet!!!"); return cmdError; } CmdResult BaseboardIO::identifyPortExpanders() { uint8_t addr[8]; uint8_t result; // Search Bus logInfo("Starting OneWire Search"); int i=0; while (true) { // TODO maybe change to family based search result = mOWMaster.search(addr); logInfo("ROM Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", addr[7],addr[6],addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); if (result != 1) break; if (i == 0) { std::memcpy(mPortExpanderROM0, addr, sizeof(mPortExpanderROM0)); } else if (i == 1) { std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1)); } i++; } logInfo("Finished OneWire Search"); if (i != 2) { logError("Incorrect Number (Got %d. Expected 2) OneWire port expanders found.", i); return cmdError; } // If switches are set in factory default mode then port expander 1 should read 0xFF and // port expander 2 should read 0xF0. mPortEx0 = new DS2408(&mOWMaster, mPortExpanderROM0); mPortEx1 = new DS2408(&mOWMaster, mPortExpanderROM1); if (mPortEx0->pioLogicRead(mPortExpanderVal0) != cmdSuccess) { logError("Error during port expander ID. Read failed."); delete mPortEx0; delete mPortEx1; return cmdError; } if (mPortEx1->pioLogicRead(mPortExpanderVal1) != cmdSuccess) { logError("Error during port expander ID. Read failed."); delete mPortEx0; delete mPortEx1; return cmdError; } if ((mPortExpanderVal0 == 0xFF) and (mPortExpanderVal1 == 0xF0)) { // Luckily got it right logInfo("ROMS Swap Not Needed."); } else if ((mPortExpanderVal0 == 0xF0) and (mPortExpanderVal1 == 0xFF)) { // Just need to swap std::memcpy(addr, mPortExpanderROM0, sizeof(addr)); // Store Orig ROM0 -> addr std::memcpy(mPortExpanderROM0, mPortExpanderROM1, sizeof(mPortExpanderROM0)); // Store Orig ROM1 -> ROM0 std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1)); // Store Orig ROM0 (addr) -> ROM1 logInfo("Swapped ROMS."); } else { logError("Error during port expander ID. Port expanders not in expected states. Check user switches."); delete mPortEx0; delete mPortEx1; return cmdError; } // Cleanup delete mPortEx0; delete mPortEx1; return cmdSuccess; } CmdResult BaseboardIO::closeRelay() { uint8_t val; mPortEx1->pioLogicRead(val); val |= pEx1RlyA; // Turn on Relay A val &= ~pEx1RlyB; // Make sure Relay B is off if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { val &= ~pEx1RlyA; // Turn Relay A off val &= ~pEx1RlyB; // Turn Relay B off mPortEx1->pioLogicWrite(val); // Write a non assert value just to try to overcome an error logError ("Error turning on coil. Turning both coils off."); return cmdError; } wait(coilOnTime); val &= ~pEx1RlyA; // Turn Relay A off val &= ~pEx1RlyB; // Turn Relay B off if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { mPortEx1->pioLogicWrite(val); logError ("Error turning off coils. Trying again."); return cmdError; } return cmdSuccess; } CmdResult BaseboardIO::openRelay() { uint8_t val; mPortEx1->pioLogicRead(val); val &= ~pEx1RlyA; // Make sure Relay A is off val |= pEx1RlyB; // Turn on Relay B if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { val &= ~pEx1RlyA; // Turn Relay A off val &= ~pEx1RlyB; // Turn Relay B off mPortEx1->pioLogicWrite(val); // Write a non assert value just to try to overcome an error logError ("Error turning on coil. Turning both coils off."); return cmdError; } wait(coilOnTime); val &= ~pEx1RlyA; // Turn Relay A off val &= ~pEx1RlyB; // Turn Relay B off if (mPortEx1->pioLogicWrite(val) != cmdSuccess) { mPortEx1->pioLogicWrite(val); logError ("Error turning off coils. Trying again."); return cmdError; } return cmdSuccess; }