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:
- mbriggs_vortex
- Date:
- 2017-11-29
- Revision:
- 100:0882cf295f8e
- Parent:
- 99:83b54c851187
File content as of revision 100:0882cf295f8e:
/* * baseboardIO.cpp * * Created on: Jan 25, 2017 * Author: mbriggs */ #include "BaseboardIO.h" #include "dot_util.h" // XXX just need the reference to dot somehow #include "xdot_low_power.h" #include "MyLog.h" // Original //const float COIL_ON_TIME = 0.030; // 30 ms // Test const float COIL_ON_TIME = 0.300; // 300 ms // Port expander 0 (Currently U7) 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; const uint8_t pEx0OutMask = 0x03; // Only allow bits 0,1 to be changed // Port expander 1 (Currently U8) 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 const uint8_t pEx1OutMask = 0xC0; // Only allow bits 6,7 to be changed /** * 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(OneWireMasterPinName), mCCIn(CCInPinName), mTamper(TamperPinName), mPairBtn(PairBtnPinName), mLed(LedPinName), mLrrLed(LrrLedPinName, 0), mSwitchedIOCtrl(SwitchedIOCtrlPinName, 0) { mPortExpanderVal0 = 0x00; mPortExpanderVal1 = 0x00; mPortEx0 = NULL; mPortEx1 = NULL; } CmdResult BaseboardIO::init(bool overwriteNvm) { bool storedROMsGood = false; uint8_t val; // Setup port expanders if (readInfoFromNVM() == cmdSuccess && !overwriteNvm) { myLogInfo("Stored ROM0 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", mNvmObj.mPortExpanderROM0[7], mNvmObj.mPortExpanderROM0[6], mNvmObj.mPortExpanderROM0[5], mNvmObj.mPortExpanderROM0[4], mNvmObj.mPortExpanderROM0[3], mNvmObj.mPortExpanderROM0[2], mNvmObj.mPortExpanderROM0[1], mNvmObj.mPortExpanderROM0[0]); myLogInfo("Stored ROM1 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", mNvmObj.mPortExpanderROM1[7], mNvmObj.mPortExpanderROM1[6], mNvmObj.mPortExpanderROM1[5], mNvmObj.mPortExpanderROM1[4], mNvmObj.mPortExpanderROM1[3], mNvmObj.mPortExpanderROM1[2], mNvmObj.mPortExpanderROM1[1], mNvmObj.mPortExpanderROM1[0]); myLogInfo("BaseboardIO parameters successfully loaded from NVM"); // Check that the ROM Addresses are correct and valid uint8_t portEx0Ctrl, portEx1Ctrl; mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0); mPortEx0->registerReadReliable(0x8D, portEx0Ctrl); // Gets 0xFF if it is not the correct address myLogInfo("PortEx0 Control register reads %02X", portEx0Ctrl); mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); mPortEx1->registerReadReliable(0x8D, portEx1Ctrl); myLogInfo("PortEx1 Control register reads %02X", portEx1Ctrl); if ((portEx0Ctrl == 0xFF) || (portEx1Ctrl == 0xFF)) { myLogError("Stored port expander ROM check failed. Set EEPROM to defaults."); } else { storedROMsGood = true; } } if (!storedROMsGood) { // EEPROM values not there or corrupt. Should only happen in factory. mNvmObj.setDefaults(); // Find ROM address and test which one is which. Requires user // switches to be in known state. if (identifyPortExpanders() != cmdSuccess) { myLogError("Error identifying port expanders"); return cmdError; } if (writeInfoToNVM() == cmdSuccess) { myLogInfo("Baseboard config saved to NVM"); } else { myLogError("Baseboard config failed to save to NVM"); } mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0); mPortEx0->registerReadReliable(0x8D, val); // Gets 0xFF if it is not the correct address myLogInfo("PortEx0 Control register reads %02X", val); mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); mPortEx1->registerReadReliable(0x8D, val); myLogInfo("PortEx1 Control register reads %02X", val); } if (sampleUserSwitches() != cmdSuccess) { myLogError("Error sampling user switches"); return cmdError; } // Put relay in known state if (relayNormal() != cmdSuccess) { myLogError("Error setting relay during init"); return cmdError; } ledOff(); myLogInfo("Baseboard IO initialization successful"); return cmdSuccess; } // Registering for interrupts void BaseboardIO::regCCInInt(Callback<void()> func) { if (isCCNO()) { // Pulled high, switched low mCCIn.fall(func); } else { mCCIn.rise(func); } mCCIn.mode(PullNone); mCCIn.enable_irq(); } void BaseboardIO::regTamperInt(Callback<void()> func) { // Pulled high, switched low mTamper.mode(PullNone); mTamper.rise(func); mTamper.fall(func); mTamper.enable_irq(); } void BaseboardIO::regPairBtnInt(Callback<void()> func) { // Pulled low, switched high mPairBtn.mode(PullNone); mPairBtn.rise(func); mPairBtn.enable_irq(); } // Input CmdResult BaseboardIO::sampleUserSwitches() { if ((mPortEx0 == NULL) || (mPortEx1 == NULL)) return cmdError; // Sample port expanders enableSwitchedIO(); wait(0.001); // Wait 1 ms if (mPortEx0->pioLogicReliableRead(mPortExpanderVal0) != cmdSuccess) { disableSwitchedIO(); myLogError("Error reading port expander 0."); return cmdError; } if (mPortEx1->pioLogicReliableRead(mPortExpanderVal1) != cmdSuccess) { disableSwitchedIO(); myLogError("Error reading port expander 1."); return cmdError; } disableSwitchedIO(); return cmdSuccess; } bool BaseboardIO::isCCInAlert() { if (isCCNO()) { // If NO then the CCIn should float high if not in alert state return mCCIn == 0; } else { // If NC then the CCIN should be held low if not in alert state return mCCIn == 1; } } bool BaseboardIO::isPairBtn() { // Depressed button is high return mPairBtn.read() == 1; } bool BaseboardIO::isCCNO() { // When DIP switch is not closed (i.e. value reads high) assume NO return (mPortExpanderVal1 & pEx1NoNcSel) != 0; // Open NO, closed NC } void BaseboardIO::setIsCCNO(bool val) { // When DIP switch is not closed (i.e. value reads high) assume NO if (val) { mPortExpanderVal1 |= pEx1NoNcSel; // Set bit } else { mPortExpanderVal1 &= ~pEx1NoNcSel; // Clear bit } } bool BaseboardIO::isRx() { // When DIP switch is not closed (i.e. value reads high) assume RX return (mPortExpanderVal1 & pEx1RxTxSel) != 0; } void BaseboardIO::setIsRx(bool val) { // When DIP switch is not closed (i.e. value reads high) assume RX if (val) { mPortExpanderVal1 |= pEx1RxTxSel; // Set bit } else { mPortExpanderVal1 &= ~pEx1RxTxSel; // Clear bit } } bool BaseboardIO::isLoRaWANMode() { // When DIP switch is not closed (i.e. value reads high) assume P2P not WAN return (mPortExpanderVal1 & pEx1WanSel) == 0; } bool BaseboardIO::isSerialEnabled() { // When DIP switch is not closed (i.e. value reads high) assume not in serial mode return (mPortExpanderVal1 & pEx1SerialEn) == 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; } void BaseboardIO::setRotarySwitch1(uint8_t val) { // Clear all then set mPortExpanderVal0 &= ~pEx0Rot1B8; mPortExpanderVal0 &= ~pEx0Rot1B4; mPortExpanderVal0 &= ~pEx0Rot1B2; mPortExpanderVal0 &= ~pEx0Rot1B1; if ((val & 0x08) == 0) { mPortExpanderVal0 |= pEx0Rot1B8; } if ((val & 0x04) == 0) { mPortExpanderVal0 |= pEx0Rot1B4; } if ((val & 0x02) == 0) { mPortExpanderVal0 |= pEx0Rot1B2; } if ((val & 0x01) == 0) { mPortExpanderVal0 |= pEx0Rot1B1; } } 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; #if ALSO_USE_LRR_LED mLrrLed = 1; #endif return cmdSuccess; } CmdResult BaseboardIO::ledOff() { mLed = 0; // Always allow setting GPIO0 to 0 //#if ALSO_USE_LRR_LED mLrrLed = 0; //#endif return cmdSuccess; } CmdResult BaseboardIO::relayAlert() { if (isCCNO()) { // Normally Open return closeRelay(); } else { // Normally Close return openRelay(); } } CmdResult BaseboardIO::relayNormal() { if (isCCNO()) { // Normally Open return openRelay(); } else { // Normally Close return closeRelay(); } } // Future CmdResult BaseboardIO::serialRx(bool enable) { uint8_t val; if (mPortEx0 == NULL) { myLogError("Error enabling 232. Port expanders not initialized."); return cmdError; } mPortEx0->pioLogicReliableRead(val); // Active low from port expander -> pmos -> 232 (active chip EN) if (enable) { val &= ~pEx0232En; } else { val |= pEx0232En; } if (mPortEx0->pioLogicReliableWrite(val | ~pEx0OutMask) != cmdSuccess) { myLogError("Error enabling 232"); return cmdError; } return cmdSuccess; } CmdResult BaseboardIO::serialTx(bool enable) { uint8_t val; if (mPortEx0 == NULL) { myLogError("Error enabling 232 TX. Port expanders not initialized."); return cmdError; } mPortEx0->pioLogicReliableRead(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 (mPortEx0->pioLogicReliableWrite(val | ~pEx0OutMask) != cmdSuccess) { myLogError("Error enabling 232 TX"); return cmdError; } return cmdSuccess; } // private CmdResult BaseboardIO::readInfoFromNVM() { bool nvmReadResult; uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE]; nvmReadResult = dot->nvmRead(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE); if (!nvmReadResult) { delete [] data; return cmdError; } mNvmObj.fromBytes(data, BASEBOARDIO_NVM_SIZE); delete [] data; if (!mNvmObj.validBaseboardIOFlag()) { myLogWarning("Invalid BaseboardIO Flag. Using default values."); return cmdError; } else if (!mNvmObj.validBaseboardIORev()) { myLogWarning("Invalid BaseboardIO Rev. Using default values."); return cmdError; } else { return cmdSuccess; } } CmdResult BaseboardIO::writeInfoToNVM() { uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE]; uint8_t size = BASEBOARDIO_NVM_SIZE; mNvmObj.toBytes(data, size); dot->nvmWrite(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE); delete [] data; return cmdSuccess; } CmdResult BaseboardIO::identifyPortExpanders() { uint8_t addr[8]; uint8_t result; int i; // Search Bus myLogInfo("Starting OneWire Search"); enableSwitchedIO(); for (int j=0;j<10;j++) { // Try 5 times i=0; mOWMaster.reset(); mOWMaster.reset_search(); wait(1.0); while (true) { // TODO maybe change to family based search result = mOWMaster.search(addr); if (result != 1) { break; } myLogInfo("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 (i == 0) { std::memcpy(mNvmObj.mPortExpanderROM0, addr, sizeof(mNvmObj.mPortExpanderROM0)); } else if (i == 1) { std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1)); } i++; } // TODO maybe only allow a reasonable number of Port Expanders if (i >=2) { break; } } myLogInfo("Finished OneWire Search"); if (i != 2) { myLogError("Incorrect Number of OneWire devices (Got %d. Expected 2) OneWire port expanders found.", i); return cmdError; } // All rotary switches should be at 0. DIPS should be asserted. // 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, mNvmObj.mPortExpanderROM0); mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); enableSwitchedIO(); if (mPortEx0->pioLogicReliableRead(mPortExpanderVal0) != cmdSuccess) { myLogError("Error during port expander ID. Read failed."); disableSwitchedIO(); delete mPortEx0; delete mPortEx1; return cmdError; } if (mPortEx1->pioLogicReliableRead(mPortExpanderVal1) != cmdSuccess) { myLogError("Error during port expander ID. Read failed."); disableSwitchedIO(); delete mPortEx0; delete mPortEx1; return cmdError; } disableSwitchedIO(); if ((mPortExpanderVal0 == 0xFF) and (mPortExpanderVal1 == 0xF0)) { // Luckily got it right myLogInfo("ROMS Swap Not Needed."); } else if ((mPortExpanderVal0 == 0xF0) and (mPortExpanderVal1 == 0xFF)) { // Just need to swap std::memcpy(addr, mNvmObj.mPortExpanderROM0, sizeof(addr)); // Store Orig ROM0 -> addr std::memcpy(mNvmObj.mPortExpanderROM0, mNvmObj.mPortExpanderROM1, sizeof(mNvmObj.mPortExpanderROM0)); // Store Orig ROM1 -> ROM0 std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1)); // Store Orig ROM0 (addr) -> ROM1 myLogInfo("Swapped ROMS."); } else { myLogError("Error during port expander ID. Port expanders not in " "expected states (0xFF and 0xF0). Check user switches. Got %02X and %02X", mPortExpanderVal0, mPortExpanderVal1); delete mPortEx0; delete mPortEx1; return cmdError; } // Cleanup delete mPortEx0; delete mPortEx1; return cmdSuccess; } CmdResult BaseboardIO::openRelay() { uint8_t val; mPortEx1->pioLogicReliableRead(val); val |= pEx1RlyA; // Make sure Relay A is off val &= ~pEx1RlyB; // Turn on Relay B if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { val |= pEx1RlyA; // Turn Relay A off val |= pEx1RlyB; // Turn Relay B off mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error myLogError ("Error turning on coil. Turning both coils off."); return cmdError; } wait(COIL_ON_TIME); val |= pEx1RlyA; // Turn Relay A off val |= pEx1RlyB; // Turn Relay B off if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); myLogError ("Error turning off coils. Trying again."); return cmdError; } return cmdSuccess; } CmdResult BaseboardIO::closeRelay() { uint8_t val; mPortEx1->pioLogicReliableRead(val); val &= ~pEx1RlyA; // Turn on Relay A val |= pEx1RlyB; // Make sure Relay B is off if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { val |= pEx1RlyA; // Turn Relay A off val |= pEx1RlyB; // Turn Relay B off mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error myLogError ("Error turning on coil. Turning both coils off."); return cmdError; } wait(COIL_ON_TIME); val |= pEx1RlyA; // Turn Relay A off val |= pEx1RlyB; // Turn Relay B off if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); myLogError ("Error turning off coils. Trying again."); return cmdError; } return cmdSuccess; } CmdResult BaseboardIO::prepareSleep() { // Save current GPUIO state xdot_save_gpio_state(); // Configure all IO expect for pins for interrupt in lowest mode possible // GPIO Ports Clock Enable __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOH_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source // GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // I2C_SDA & I2C_SCL to analog nopull GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // iterate through potential wake pins - leave the configured wake pin alone if one is needed if ((CCInPinName != WAKE && TamperPinName != WAKE && PairBtnPinName != WAKE) || dot->getWakeMode() == mDot::RTC_ALARM) { GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } if ((CCInPinName != GPIO0 && TamperPinName != GPIO0 && PairBtnPinName != GPIO0) || dot->getWakeMode() == mDot::RTC_ALARM) { GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } if ((CCInPinName != GPIO1 && TamperPinName != GPIO1 && PairBtnPinName != GPIO1) || dot->getWakeMode() == mDot::RTC_ALARM) { GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } if ((CCInPinName != GPIO2 && TamperPinName != GPIO2 && PairBtnPinName != GPIO2) || dot->getWakeMode() == mDot::RTC_ALARM) { GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } // Changed to always do pull down for now.. Should implement discrete pull on new rev // if ((CCInPinName != GPIO3 && TamperPinName != GPIO3 && PairBtnPinName != GPIO3) // || dot->getWakeMode() == mDot::RTC_ALARM) { // GPIO_InitStruct.Pin = GPIO_PIN_2; // GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // GPIO_InitStruct.Pull = GPIO_NOPULL; // HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // } // Try doing nothing so that the GPIO3 is still and active output // Cannot do this and have serial data // if ((CCInPinName != UART1_RX && TamperPinName != UART1_RX && PairBtnPinName != UART1_RX) // || dot->getWakeMode() == mDot::RTC_ALARM) { // GPIO_InitStruct.Pin = GPIO_PIN_10; // GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // GPIO_InitStruct.Pull = GPIO_NOPULL; // HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // } if ((CCInPinName != UART_CTS && TamperPinName != UART_CTS && PairBtnPinName != UART_CTS) || dot->getWakeMode() == mDot::RTC_ALARM) { GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } return cmdSuccess; } CmdResult BaseboardIO::exitSleep() { xdot_restore_gpio_state(); return cmdSuccess; } // NvmBBIOObj NvmBBIOObj::NvmBBIOObj() { setDefaults(); } void NvmBBIOObj::setDefaults() { mBaseboardIOFlag = BASEBOARDIO_FLAG; mBaseboardIORev = BASEBOARDIO_REV; mSerialNum = 0x0000; mBaseboardIOConfig = 0x0000; std::memset(mPortExpanderROM0, 0x00, 8); std::memset(mPortExpanderROM1, 0x00, 8); } CmdResult NvmBBIOObj::fromBytes(uint8_t *data, uint8_t size) { if (size != BASEBOARDIO_NVM_SIZE) { return cmdError; } mBaseboardIOFlag = *((uint16_t *) (data)); mBaseboardIORev = *((uint16_t *) (data+2)); mSerialNum = *((uint32_t *) (data+4)); mBaseboardIOConfig = *((uint32_t *) (data+6)); std::memcpy(&mPortExpanderROM0, data+0x10, 8); std::memcpy(&mPortExpanderROM1, data+0x18, 8); return cmdSuccess; } CmdResult NvmBBIOObj::toBytes(uint8_t *data, uint8_t &size) { // TODO check data size *((uint16_t *) (data)) = mBaseboardIOFlag; *((uint16_t *) (data+2)) = mBaseboardIORev; *((uint32_t *) (data+4)) = mSerialNum; *((uint32_t *) (data+6)) = mBaseboardIOConfig; std::memcpy(data+0x10, &mPortExpanderROM0, 8); std::memcpy(data+0x18, &mPortExpanderROM1, 8); size = BASEBOARDIO_NVM_SIZE; return cmdSuccess; } uint16_t NvmBBIOObj::getBaseboardIOFlag() { return mBaseboardIOFlag; } bool NvmBBIOObj::validBaseboardIOFlag() { return mBaseboardIOFlag == BASEBOARDIO_FLAG; } uint16_t NvmBBIOObj::getBaseboardIORev() { return mBaseboardIORev; } bool NvmBBIOObj::validBaseboardIORev() { return mBaseboardIORev == BASEBOARDIO_REV; } uint16_t NvmBBIOObj::getSerialNum() { return mSerialNum; } void NvmBBIOObj::setSerialNum(uint16_t in) { mSerialNum = in; } uint32_t NvmBBIOObj::getBaseboardIOConfig() { return mBaseboardIOConfig; } void NvmBBIOObj::setBaseboardIOConfig(uint32_t in) { mBaseboardIOConfig = in; } void NvmBBIOObj::getPortExpanderROM0(uint8_t *addr) { std::memcpy(addr, &mPortExpanderROM0, 8); } void NvmBBIOObj::setPortExpanderROM0(const uint8_t *addr) { std::memcpy(&mPortExpanderROM0, addr, 8); } void NvmBBIOObj::getPortExpanderROM1(uint8_t *addr) { std::memcpy(addr, &mPortExpanderROM1, 8); } void NvmBBIOObj::setPortExpanderROM1(const uint8_t *addr) { std::memcpy(&mPortExpanderROM1, addr, 8); }