Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
BaseboardIO.cpp
00001 /* 00002 * baseboardIO.cpp 00003 * 00004 * Created on: Jan 25, 2017 00005 * Author: mbriggs 00006 */ 00007 00008 #include "BaseboardIO.h" 00009 #include "dot_util.h" // XXX just need the reference to dot somehow 00010 #include "xdot_low_power.h" 00011 #include "MyLog.h" 00012 00013 // Original 00014 //const float COIL_ON_TIME = 0.030; // 30 ms 00015 // Test 00016 const float COIL_ON_TIME = 0.300; // 300 ms 00017 00018 00019 // Port expander 0 (Currently U7) 00020 const uint8_t pEx0232En = 0x01; 00021 const uint8_t pEx0232TxDis = 0x02; 00022 const uint8_t pEx0Rot1B1 = 0x04; 00023 const uint8_t pEx0Rot1B2 = 0x08; 00024 const uint8_t pEx0Rot1B4 = 0x10; 00025 const uint8_t pEx0Rot1B8 = 0x20; 00026 const uint8_t pEx0Rot2B1 = 0x40; 00027 const uint8_t pEx0Rot2B2 = 0x80; 00028 const uint8_t pEx0OutMask = 0x03; // Only allow bits 0,1 to be changed 00029 00030 // Port expander 1 (Currently U8) 00031 const uint8_t pEx1NoNcSel = 0x01; 00032 const uint8_t pEx1RxTxSel = 0x02; 00033 const uint8_t pEx1WanSel = 0x04; 00034 const uint8_t pEx1SerialEn = 0x08; // Labeled as reserved 00035 const uint8_t pEx1Rot2B8 = 0x10; 00036 const uint8_t pEx1Rot2B4 = 0x20; 00037 const uint8_t pEx1RlyB = 0x40; // This is actually a coil 00038 const uint8_t pEx1RlyA = 0x80; // This is actually a coil 00039 const uint8_t pEx1OutMask = 0xC0; // Only allow bits 6,7 to be changed 00040 00041 /** 00042 * Note for interrupt within uC cannot use two pins with the same numeric suffix (e.g. cannot 00043 * use both PA_0 and PB_0). Note 1, 6, 7, 8, and 13 are used by LoRa radio. 00044 */ 00045 00046 BaseboardIO::BaseboardIO() 00047 : mOWMaster(OneWireMasterPinName), 00048 mCCIn(CCInPinName), 00049 mTamper(TamperPinName), 00050 mPairBtn(PairBtnPinName), 00051 mLed(LedPinName), 00052 mLrrLed(LrrLedPinName, 0), 00053 mSwitchedIOCtrl(SwitchedIOCtrlPinName, 0) 00054 { 00055 mPortExpanderVal0 = 0x00; 00056 mPortExpanderVal1 = 0x00; 00057 00058 mPortEx0 = NULL; 00059 mPortEx1 = NULL; 00060 } 00061 CmdResult BaseboardIO::init(bool overwriteNvm) 00062 { 00063 bool storedROMsGood = false; 00064 uint8_t val; 00065 // Setup port expanders 00066 if (readInfoFromNVM() == cmdSuccess && !overwriteNvm) { 00067 myLogInfo("Stored ROM0 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", 00068 mNvmObj.mPortExpanderROM0[7], 00069 mNvmObj.mPortExpanderROM0[6], 00070 mNvmObj.mPortExpanderROM0[5], 00071 mNvmObj.mPortExpanderROM0[4], 00072 mNvmObj.mPortExpanderROM0[3], 00073 mNvmObj.mPortExpanderROM0[2], 00074 mNvmObj.mPortExpanderROM0[1], 00075 mNvmObj.mPortExpanderROM0[0]); 00076 myLogInfo("Stored ROM1 Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", 00077 mNvmObj.mPortExpanderROM1[7], 00078 mNvmObj.mPortExpanderROM1[6], 00079 mNvmObj.mPortExpanderROM1[5], 00080 mNvmObj.mPortExpanderROM1[4], 00081 mNvmObj.mPortExpanderROM1[3], 00082 mNvmObj.mPortExpanderROM1[2], 00083 mNvmObj.mPortExpanderROM1[1], 00084 mNvmObj.mPortExpanderROM1[0]); 00085 myLogInfo("BaseboardIO parameters successfully loaded from NVM"); 00086 // Check that the ROM Addresses are correct and valid 00087 uint8_t portEx0Ctrl, portEx1Ctrl; 00088 mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0); 00089 mPortEx0->registerReadReliable(0x8D, portEx0Ctrl); 00090 // Gets 0xFF if it is not the correct address 00091 myLogInfo("PortEx0 Control register reads %02X", portEx0Ctrl); 00092 00093 mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); 00094 mPortEx1->registerReadReliable(0x8D, portEx1Ctrl); 00095 myLogInfo("PortEx1 Control register reads %02X", portEx1Ctrl); 00096 if ((portEx0Ctrl == 0xFF) || (portEx1Ctrl == 0xFF)) { 00097 myLogError("Stored port expander ROM check failed. Set EEPROM to defaults."); 00098 } 00099 else { 00100 storedROMsGood = true; 00101 } 00102 } 00103 if (!storedROMsGood) 00104 { // EEPROM values not there or corrupt. Should only happen in factory. 00105 mNvmObj.setDefaults(); 00106 // Find ROM address and test which one is which. Requires user 00107 // switches to be in known state. 00108 if (identifyPortExpanders() != cmdSuccess) { 00109 myLogError("Error identifying port expanders"); 00110 return cmdError; 00111 } 00112 if (writeInfoToNVM() == cmdSuccess) { 00113 myLogInfo("Baseboard config saved to NVM"); 00114 } 00115 else { 00116 myLogError("Baseboard config failed to save to NVM"); 00117 } 00118 mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0); 00119 mPortEx0->registerReadReliable(0x8D, val); 00120 // Gets 0xFF if it is not the correct address 00121 myLogInfo("PortEx0 Control register reads %02X", val); 00122 mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); 00123 mPortEx1->registerReadReliable(0x8D, val); 00124 myLogInfo("PortEx1 Control register reads %02X", val); 00125 } 00126 00127 if (sampleUserSwitches() != cmdSuccess) { 00128 myLogError("Error sampling user switches"); 00129 return cmdError; 00130 } 00131 00132 // Put relay in known state 00133 if (relayNormal() != cmdSuccess) { 00134 myLogError("Error setting relay during init"); 00135 return cmdError; 00136 } 00137 ledOff(); 00138 00139 myLogInfo("Baseboard IO initialization successful"); 00140 return cmdSuccess; 00141 } 00142 00143 // Registering for interrupts 00144 void BaseboardIO::regCCInInt(Callback<void()> func) 00145 { 00146 if (isCCNO()) { 00147 // Pulled high, switched low 00148 mCCIn.fall(func); 00149 } 00150 else { 00151 mCCIn.rise(func); 00152 } 00153 mCCIn.mode(PullNone); 00154 mCCIn.enable_irq(); 00155 } 00156 void BaseboardIO::regTamperInt(Callback<void()> func) 00157 { 00158 // Pulled high, switched low 00159 mTamper.mode(PullNone); 00160 mTamper.rise(func); 00161 mTamper.fall(func); 00162 mTamper.enable_irq(); 00163 } 00164 void BaseboardIO::regPairBtnInt(Callback<void()> func) 00165 { 00166 // Pulled low, switched high 00167 mPairBtn.mode(PullNone); 00168 mPairBtn.rise(func); 00169 mPairBtn.enable_irq(); 00170 } 00171 00172 // Input 00173 CmdResult BaseboardIO::sampleUserSwitches() 00174 { 00175 if ((mPortEx0 == NULL) || (mPortEx1 == NULL)) 00176 return cmdError; 00177 // Sample port expanders 00178 enableSwitchedIO(); 00179 wait(0.001); // Wait 1 ms 00180 if (mPortEx0->pioLogicReliableRead(mPortExpanderVal0) != cmdSuccess) { 00181 disableSwitchedIO(); 00182 myLogError("Error reading port expander 0."); 00183 return cmdError; 00184 } 00185 if (mPortEx1->pioLogicReliableRead(mPortExpanderVal1) != cmdSuccess) { 00186 disableSwitchedIO(); 00187 myLogError("Error reading port expander 1."); 00188 return cmdError; 00189 } 00190 disableSwitchedIO(); 00191 return cmdSuccess; 00192 } 00193 bool BaseboardIO::isCCInAlert() 00194 { 00195 if (isCCNO()) { // If NO then the CCIn should float high if not in alert state 00196 return mCCIn == 0; 00197 } 00198 else { // If NC then the CCIN should be held low if not in alert state 00199 return mCCIn == 1; 00200 } 00201 } 00202 bool BaseboardIO::isPairBtn() 00203 { 00204 // Depressed button is high 00205 return mPairBtn.read() == 1; 00206 } 00207 bool BaseboardIO::isCCNO() 00208 { 00209 // When DIP switch is not closed (i.e. value reads high) assume NO 00210 return (mPortExpanderVal1 & pEx1NoNcSel) != 0; // Open NO, closed NC 00211 } 00212 void BaseboardIO::setIsCCNO(bool val) 00213 { 00214 // When DIP switch is not closed (i.e. value reads high) assume NO 00215 if (val) { 00216 mPortExpanderVal1 |= pEx1NoNcSel; // Set bit 00217 } 00218 else { 00219 mPortExpanderVal1 &= ~pEx1NoNcSel; // Clear bit 00220 } 00221 } 00222 bool BaseboardIO::isRx() 00223 { 00224 // When DIP switch is not closed (i.e. value reads high) assume RX 00225 return (mPortExpanderVal1 & pEx1RxTxSel) != 0; 00226 } 00227 void BaseboardIO::setIsRx(bool val) 00228 { 00229 // When DIP switch is not closed (i.e. value reads high) assume RX 00230 if (val) { 00231 mPortExpanderVal1 |= pEx1RxTxSel; // Set bit 00232 } 00233 else { 00234 mPortExpanderVal1 &= ~pEx1RxTxSel; // Clear bit 00235 } 00236 } 00237 bool BaseboardIO::isLoRaWANMode() 00238 { 00239 // When DIP switch is not closed (i.e. value reads high) assume P2P not WAN 00240 return (mPortExpanderVal1 & pEx1WanSel) == 0; 00241 } 00242 bool BaseboardIO::isSerialEnabled() 00243 { 00244 // When DIP switch is not closed (i.e. value reads high) assume not in serial mode 00245 return (mPortExpanderVal1 & pEx1SerialEn) == 0; 00246 } 00247 uint8_t BaseboardIO::rotarySwitch1() 00248 { 00249 // If a bit of a nibble is asserted then the port expander line is switched low. 00250 uint8_t val = 0; 00251 if ((mPortExpanderVal0 & pEx0Rot1B8) == 0) 00252 val |= 0x08; 00253 if ((mPortExpanderVal0 & pEx0Rot1B4) == 0) 00254 val |= 0x04; 00255 if ((mPortExpanderVal0 & pEx0Rot1B2) == 0) 00256 val |= 0x02; 00257 if ((mPortExpanderVal0 & pEx0Rot1B1) == 0) 00258 val |= 0x01; 00259 return val; 00260 } 00261 void BaseboardIO::setRotarySwitch1(uint8_t val) 00262 { 00263 // Clear all then set 00264 mPortExpanderVal0 &= ~pEx0Rot1B8; 00265 mPortExpanderVal0 &= ~pEx0Rot1B4; 00266 mPortExpanderVal0 &= ~pEx0Rot1B2; 00267 mPortExpanderVal0 &= ~pEx0Rot1B1; 00268 00269 if ((val & 0x08) == 0) { 00270 mPortExpanderVal0 |= pEx0Rot1B8; 00271 } 00272 if ((val & 0x04) == 0) { 00273 mPortExpanderVal0 |= pEx0Rot1B4; 00274 } 00275 if ((val & 0x02) == 0) { 00276 mPortExpanderVal0 |= pEx0Rot1B2; 00277 } 00278 if ((val & 0x01) == 0) { 00279 mPortExpanderVal0 |= pEx0Rot1B1; 00280 } 00281 } 00282 uint8_t BaseboardIO::rotarySwitch2() 00283 { 00284 // If a bit of a nibble is asserted then the port expander line is switched low. 00285 uint8_t val = 0; 00286 if ((mPortExpanderVal1 & pEx1Rot2B8) == 0) 00287 val |= 0x08; 00288 if ((mPortExpanderVal1 & pEx1Rot2B4) == 0) 00289 val |= 0x04; 00290 if ((mPortExpanderVal0 & pEx0Rot2B2) == 0) 00291 val |= 0x02; 00292 if ((mPortExpanderVal0 & pEx0Rot2B1) == 0) 00293 val |= 0x01; 00294 return val; 00295 } 00296 00297 // Output 00298 CmdResult BaseboardIO::ledOn() 00299 { 00300 mLed = 1; 00301 #if ALSO_USE_LRR_LED 00302 mLrrLed = 1; 00303 #endif 00304 return cmdSuccess; 00305 } 00306 CmdResult BaseboardIO::ledOff() 00307 { 00308 mLed = 0; 00309 // Always allow setting GPIO0 to 0 00310 //#if ALSO_USE_LRR_LED 00311 mLrrLed = 0; 00312 //#endif 00313 return cmdSuccess; 00314 } 00315 CmdResult BaseboardIO::relayAlert() 00316 { 00317 if (isCCNO()) { // Normally Open 00318 return closeRelay(); 00319 } 00320 else { // Normally Close 00321 return openRelay(); 00322 } 00323 } 00324 CmdResult BaseboardIO::relayNormal() 00325 { 00326 if (isCCNO()) { // Normally Open 00327 return openRelay(); 00328 } 00329 else { // Normally Close 00330 return closeRelay(); 00331 } 00332 } 00333 00334 // Future 00335 CmdResult BaseboardIO::serialRx(bool enable) 00336 { 00337 uint8_t val; 00338 if (mPortEx0 == NULL) { 00339 myLogError("Error enabling 232. Port expanders not initialized."); 00340 return cmdError; 00341 } 00342 mPortEx0->pioLogicReliableRead(val); 00343 00344 // Active low from port expander -> pmos -> 232 (active chip EN) 00345 if (enable) { 00346 val &= ~pEx0232En; 00347 } 00348 else { 00349 val |= pEx0232En; 00350 } 00351 00352 if (mPortEx0->pioLogicReliableWrite(val | ~pEx0OutMask) != cmdSuccess) { 00353 myLogError("Error enabling 232"); 00354 return cmdError; 00355 } 00356 return cmdSuccess; 00357 } 00358 CmdResult BaseboardIO::serialTx(bool enable) 00359 { 00360 uint8_t val; 00361 if (mPortEx0 == NULL) { 00362 myLogError("Error enabling 232 TX. Port expanders not initialized."); 00363 return cmdError; 00364 } 00365 mPortEx0->pioLogicReliableRead(val); 00366 00367 // Active high tx disable therefore active low tx enable (note chip must also be enabled for TX) 00368 if (enable) { 00369 val &= ~pEx0232TxDis; 00370 } 00371 else { 00372 val |= pEx0232TxDis; 00373 } 00374 00375 if (mPortEx0->pioLogicReliableWrite(val | ~pEx0OutMask) != cmdSuccess) { 00376 myLogError("Error enabling 232 TX"); 00377 return cmdError; 00378 } 00379 return cmdSuccess; 00380 } 00381 00382 // private 00383 CmdResult BaseboardIO::readInfoFromNVM() 00384 { 00385 bool nvmReadResult; 00386 uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE]; 00387 00388 nvmReadResult = dot->nvmRead(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE); 00389 if (!nvmReadResult) { 00390 delete [] data; 00391 return cmdError; 00392 } 00393 mNvmObj.fromBytes(data, BASEBOARDIO_NVM_SIZE); 00394 delete [] data; 00395 if (!mNvmObj.validBaseboardIOFlag()) { 00396 myLogWarning("Invalid BaseboardIO Flag. Using default values."); 00397 return cmdError; 00398 } 00399 else if (!mNvmObj.validBaseboardIORev()) { 00400 myLogWarning("Invalid BaseboardIO Rev. Using default values."); 00401 return cmdError; 00402 } 00403 else { 00404 return cmdSuccess; 00405 } 00406 } 00407 CmdResult BaseboardIO::writeInfoToNVM() 00408 { 00409 uint8_t *data = new uint8_t [BASEBOARDIO_NVM_SIZE]; 00410 uint8_t size = BASEBOARDIO_NVM_SIZE; 00411 mNvmObj.toBytes(data, size); 00412 dot->nvmWrite(BASEBOARDIO_NVM_START_ADDR, data, BASEBOARDIO_NVM_SIZE); 00413 00414 delete [] data; 00415 return cmdSuccess; 00416 } 00417 CmdResult BaseboardIO::identifyPortExpanders() 00418 { 00419 uint8_t addr[8]; 00420 uint8_t result; 00421 int i; 00422 00423 // Search Bus 00424 myLogInfo("Starting OneWire Search"); 00425 enableSwitchedIO(); 00426 for (int j=0;j<10;j++) { // Try 5 times 00427 i=0; 00428 mOWMaster.reset(); 00429 mOWMaster.reset_search(); 00430 wait(1.0); 00431 while (true) { 00432 // TODO maybe change to family based search 00433 result = mOWMaster.search(addr); 00434 if (result != 1) { 00435 break; 00436 } 00437 myLogInfo("ROM Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.", 00438 addr[7],addr[6],addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); 00439 if (i == 0) { 00440 std::memcpy(mNvmObj.mPortExpanderROM0, addr, sizeof(mNvmObj.mPortExpanderROM0)); 00441 } 00442 else if (i == 1) { 00443 std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1)); 00444 } 00445 i++; 00446 } 00447 // TODO maybe only allow a reasonable number of Port Expanders 00448 if (i >=2) { 00449 break; 00450 } 00451 } 00452 00453 myLogInfo("Finished OneWire Search"); 00454 if (i != 2) { 00455 myLogError("Incorrect Number of OneWire devices (Got %d. Expected 2) OneWire port expanders found.", i); 00456 return cmdError; 00457 } 00458 00459 // All rotary switches should be at 0. DIPS should be asserted. 00460 // If switches are set in factory default mode then port expander 1 should read 0xFF and 00461 // port expander 2 should read 0xF0. 00462 00463 mPortEx0 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM0); 00464 mPortEx1 = new DS2408(&mOWMaster, mNvmObj.mPortExpanderROM1); 00465 00466 00467 enableSwitchedIO(); 00468 if (mPortEx0->pioLogicReliableRead(mPortExpanderVal0) != cmdSuccess) { 00469 myLogError("Error during port expander ID. Read failed."); 00470 disableSwitchedIO(); 00471 delete mPortEx0; 00472 delete mPortEx1; 00473 return cmdError; 00474 } 00475 if (mPortEx1->pioLogicReliableRead(mPortExpanderVal1) != cmdSuccess) { 00476 myLogError("Error during port expander ID. Read failed."); 00477 disableSwitchedIO(); 00478 delete mPortEx0; 00479 delete mPortEx1; 00480 return cmdError; 00481 } 00482 00483 disableSwitchedIO(); 00484 if ((mPortExpanderVal0 == 0xFF) and (mPortExpanderVal1 == 0xF0)) { // Luckily got it right 00485 myLogInfo("ROMS Swap Not Needed."); 00486 } 00487 else if ((mPortExpanderVal0 == 0xF0) and (mPortExpanderVal1 == 0xFF)) { // Just need to swap 00488 std::memcpy(addr, mNvmObj.mPortExpanderROM0, sizeof(addr)); // Store Orig ROM0 -> addr 00489 std::memcpy(mNvmObj.mPortExpanderROM0, mNvmObj.mPortExpanderROM1, sizeof(mNvmObj.mPortExpanderROM0)); // Store Orig ROM1 -> ROM0 00490 std::memcpy(mNvmObj.mPortExpanderROM1, addr, sizeof(mNvmObj.mPortExpanderROM1)); // Store Orig ROM0 (addr) -> ROM1 00491 myLogInfo("Swapped ROMS."); 00492 } 00493 else { 00494 myLogError("Error during port expander ID. Port expanders not in " 00495 "expected states (0xFF and 0xF0). Check user switches. Got %02X and %02X", 00496 mPortExpanderVal0, mPortExpanderVal1); 00497 delete mPortEx0; 00498 delete mPortEx1; 00499 return cmdError; 00500 } 00501 00502 // Cleanup 00503 delete mPortEx0; 00504 delete mPortEx1; 00505 00506 return cmdSuccess; 00507 } 00508 CmdResult BaseboardIO::openRelay() { 00509 uint8_t val; 00510 mPortEx1->pioLogicReliableRead(val); 00511 00512 val |= pEx1RlyA; // Make sure Relay A is off 00513 val &= ~pEx1RlyB; // Turn on Relay B 00514 00515 if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { 00516 val |= pEx1RlyA; // Turn Relay A off 00517 val |= pEx1RlyB; // Turn Relay B off 00518 mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error 00519 myLogError ("Error turning on coil. Turning both coils off."); 00520 return cmdError; 00521 } 00522 00523 wait(COIL_ON_TIME); 00524 00525 val |= pEx1RlyA; // Turn Relay A off 00526 val |= pEx1RlyB; // Turn Relay B off 00527 00528 if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { 00529 mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); 00530 myLogError ("Error turning off coils. Trying again."); 00531 return cmdError; 00532 } 00533 00534 return cmdSuccess; 00535 } 00536 CmdResult BaseboardIO::closeRelay() { 00537 uint8_t val; 00538 mPortEx1->pioLogicReliableRead(val); 00539 00540 val &= ~pEx1RlyA; // Turn on Relay A 00541 val |= pEx1RlyB; // Make sure Relay B is off 00542 00543 if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { 00544 val |= pEx1RlyA; // Turn Relay A off 00545 val |= pEx1RlyB; // Turn Relay B off 00546 mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error 00547 myLogError ("Error turning on coil. Turning both coils off."); 00548 return cmdError; 00549 } 00550 00551 wait(COIL_ON_TIME); 00552 00553 val |= pEx1RlyA; // Turn Relay A off 00554 val |= pEx1RlyB; // Turn Relay B off 00555 00556 if (mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask) != cmdSuccess) { 00557 mPortEx1->pioLogicReliableWrite(val | ~pEx1OutMask); 00558 myLogError ("Error turning off coils. Trying again."); 00559 return cmdError; 00560 } 00561 00562 return cmdSuccess; 00563 } 00564 00565 CmdResult BaseboardIO::prepareSleep() 00566 { 00567 // Save current GPUIO state 00568 xdot_save_gpio_state(); 00569 00570 // Configure all IO expect for pins for interrupt in lowest mode possible 00571 // GPIO Ports Clock Enable 00572 __GPIOA_CLK_ENABLE(); 00573 __GPIOB_CLK_ENABLE(); 00574 __GPIOC_CLK_ENABLE(); 00575 __GPIOH_CLK_ENABLE(); 00576 00577 GPIO_InitTypeDef GPIO_InitStruct; 00578 00579 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source 00580 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source 00581 // GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; 00582 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_12; 00583 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00584 GPIO_InitStruct.Pull = GPIO_NOPULL; 00585 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00586 00587 // I2C_SDA & I2C_SCL to analog nopull 00588 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; 00589 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00590 GPIO_InitStruct.Pull = GPIO_NOPULL; 00591 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00592 00593 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull 00594 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00595 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00596 GPIO_InitStruct.Pull = GPIO_NOPULL; 00597 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00598 00599 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 00600 if ((CCInPinName != WAKE && TamperPinName != WAKE && PairBtnPinName != WAKE) 00601 || dot->getWakeMode() == mDot::RTC_ALARM) { 00602 GPIO_InitStruct.Pin = GPIO_PIN_0; 00603 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00604 GPIO_InitStruct.Pull = GPIO_NOPULL; 00605 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00606 } 00607 if ((CCInPinName != GPIO0 && TamperPinName != GPIO0 && PairBtnPinName != GPIO0) 00608 || dot->getWakeMode() == mDot::RTC_ALARM) { 00609 GPIO_InitStruct.Pin = GPIO_PIN_4; 00610 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00611 GPIO_InitStruct.Pull = GPIO_NOPULL; 00612 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00613 } 00614 if ((CCInPinName != GPIO1 && TamperPinName != GPIO1 && PairBtnPinName != GPIO1) 00615 || dot->getWakeMode() == mDot::RTC_ALARM) { 00616 GPIO_InitStruct.Pin = GPIO_PIN_5; 00617 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00618 GPIO_InitStruct.Pull = GPIO_NOPULL; 00619 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00620 } 00621 if ((CCInPinName != GPIO2 && TamperPinName != GPIO2 && PairBtnPinName != GPIO2) 00622 || dot->getWakeMode() == mDot::RTC_ALARM) { 00623 GPIO_InitStruct.Pin = GPIO_PIN_0; 00624 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00625 GPIO_InitStruct.Pull = GPIO_NOPULL; 00626 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00627 } 00628 // Changed to always do pull down for now.. Should implement discrete pull on new rev 00629 // if ((CCInPinName != GPIO3 && TamperPinName != GPIO3 && PairBtnPinName != GPIO3) 00630 // || dot->getWakeMode() == mDot::RTC_ALARM) { 00631 // GPIO_InitStruct.Pin = GPIO_PIN_2; 00632 // GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00633 // GPIO_InitStruct.Pull = GPIO_NOPULL; 00634 // HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 00635 // } 00636 00637 // Try doing nothing so that the GPIO3 is still and active output 00638 00639 00640 // Cannot do this and have serial data 00641 // if ((CCInPinName != UART1_RX && TamperPinName != UART1_RX && PairBtnPinName != UART1_RX) 00642 // || dot->getWakeMode() == mDot::RTC_ALARM) { 00643 // GPIO_InitStruct.Pin = GPIO_PIN_10; 00644 // GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00645 // GPIO_InitStruct.Pull = GPIO_NOPULL; 00646 // HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00647 // } 00648 if ((CCInPinName != UART_CTS && TamperPinName != UART_CTS && PairBtnPinName != UART_CTS) 00649 || dot->getWakeMode() == mDot::RTC_ALARM) { 00650 GPIO_InitStruct.Pin = GPIO_PIN_11; 00651 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 00652 GPIO_InitStruct.Pull = GPIO_NOPULL; 00653 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00654 } 00655 00656 return cmdSuccess; 00657 } 00658 00659 CmdResult BaseboardIO::exitSleep() 00660 { 00661 xdot_restore_gpio_state(); 00662 return cmdSuccess; 00663 } 00664 00665 // NvmBBIOObj 00666 NvmBBIOObj::NvmBBIOObj() 00667 { 00668 setDefaults(); 00669 } 00670 void NvmBBIOObj::setDefaults() 00671 { 00672 mBaseboardIOFlag = BASEBOARDIO_FLAG; 00673 mBaseboardIORev = BASEBOARDIO_REV; 00674 mSerialNum = 0x0000; 00675 mBaseboardIOConfig = 0x0000; 00676 std::memset(mPortExpanderROM0, 0x00, 8); 00677 std::memset(mPortExpanderROM1, 0x00, 8); 00678 } 00679 CmdResult NvmBBIOObj::fromBytes(uint8_t *data, uint8_t size) 00680 { 00681 if (size != BASEBOARDIO_NVM_SIZE) { 00682 return cmdError; 00683 } 00684 00685 mBaseboardIOFlag = *((uint16_t *) (data)); 00686 mBaseboardIORev = *((uint16_t *) (data+2)); 00687 mSerialNum = *((uint32_t *) (data+4)); 00688 mBaseboardIOConfig = *((uint32_t *) (data+6)); 00689 00690 std::memcpy(&mPortExpanderROM0, data+0x10, 8); 00691 std::memcpy(&mPortExpanderROM1, data+0x18, 8); 00692 00693 return cmdSuccess; 00694 } 00695 CmdResult NvmBBIOObj::toBytes(uint8_t *data, uint8_t &size) { 00696 // TODO check data size 00697 00698 *((uint16_t *) (data)) = mBaseboardIOFlag; 00699 *((uint16_t *) (data+2)) = mBaseboardIORev; 00700 *((uint32_t *) (data+4)) = mSerialNum; 00701 *((uint32_t *) (data+6)) = mBaseboardIOConfig; 00702 00703 std::memcpy(data+0x10, &mPortExpanderROM0, 8); 00704 std::memcpy(data+0x18, &mPortExpanderROM1, 8); 00705 00706 size = BASEBOARDIO_NVM_SIZE; 00707 00708 return cmdSuccess; 00709 } 00710 uint16_t NvmBBIOObj::getBaseboardIOFlag() 00711 { 00712 return mBaseboardIOFlag; 00713 } 00714 bool NvmBBIOObj::validBaseboardIOFlag() 00715 { 00716 return mBaseboardIOFlag == BASEBOARDIO_FLAG; 00717 } 00718 uint16_t NvmBBIOObj::getBaseboardIORev() 00719 { 00720 return mBaseboardIORev; 00721 } 00722 bool NvmBBIOObj::validBaseboardIORev() 00723 { 00724 return mBaseboardIORev == BASEBOARDIO_REV; 00725 } 00726 uint16_t NvmBBIOObj::getSerialNum() 00727 { 00728 return mSerialNum; 00729 } 00730 void NvmBBIOObj::setSerialNum(uint16_t in) 00731 { 00732 mSerialNum = in; 00733 } 00734 uint32_t NvmBBIOObj::getBaseboardIOConfig() 00735 { 00736 return mBaseboardIOConfig; 00737 } 00738 void NvmBBIOObj::setBaseboardIOConfig(uint32_t in) 00739 { 00740 mBaseboardIOConfig = in; 00741 } 00742 void NvmBBIOObj::getPortExpanderROM0(uint8_t *addr) 00743 { 00744 std::memcpy(addr, &mPortExpanderROM0, 8); 00745 } 00746 void NvmBBIOObj::setPortExpanderROM0(const uint8_t *addr) 00747 { 00748 std::memcpy(&mPortExpanderROM0, addr, 8); 00749 } 00750 void NvmBBIOObj::getPortExpanderROM1(uint8_t *addr) 00751 { 00752 std::memcpy(addr, &mPortExpanderROM1, 8); 00753 } 00754 void NvmBBIOObj::setPortExpanderROM1(const uint8_t *addr) 00755 { 00756 std::memcpy(&mPortExpanderROM1, addr, 8); 00757 }
Generated on Fri Jul 15 2022 14:36:45 by 1.7.2