void WirelessNode_Impl::writeEeprom(uint16 location, uint16 value) { eeprom().writeEeprom(location, value); }
uint16 WirelessNode_Impl::readEeprom(uint16 location) const { return eeprom().readEeprom(location); }
void WirelessNode_Impl::writeEeprom(const EepromLocation& location, const Value& val) { eeprom().writeEeprom(location, val); }
Value WirelessNode_Impl::readEeprom(const EepromLocation& location) const { return eeprom().readEeprom(location); }
AutoBalanceResult WirelessNode_Impl::autoBalance(const ChannelMask& mask, float targetPercent) { Utils::checkBounds_min(targetPercent, 0.0f); Utils::checkBounds_max(targetPercent, 100.0f); //attempt a few pings first //(legacy (v1) autobalance doesn't have a response packet, so need to check communication) uint8 retryCounter = 0; bool pingSuccess = false; while(!pingSuccess && retryCounter < 3) { pingSuccess = ping().success(); retryCounter++; } if(!pingSuccess) { throw Error_NodeCommunication(nodeAddress()); } //find the eeprom location that the autobalance will adjust //Note: this also verifies that it is supported for this mask const EepromLocation& eepromLoc = features().findEeprom(WirelessTypes::chSetting_autoBalance, mask); //currently, autobalance is always per channel, so get the channel from the mask uint8 channelNumber = mask.lastChEnabled(); AutoBalanceResult result; //perform the autobalance command with the parent base station m_baseStation.node_autoBalance(protocol(), m_address, channelNumber, targetPercent, result); //clear the cache of the hardware offset eeprom location we adjusted eeprom().clearCacheLocation(eepromLoc.location()); Utils::threadSleep(200); //if we used the legacy command, we don't get result info, need to do more work to get it if(result.m_errorCode == WirelessTypes::autobalance_legacyNone) { result.m_errorCode = WirelessTypes::autobalance_maybeInvalid; //force the read eeprom retries to a minimum of 3 uint8 startRetries = m_eepromSettings.numRetries; //when this goes out of scope, it will change back the original retries value ScopeHelper writebackRetries(std::bind(&WirelessNode_Impl::setReadWriteRetries, this, startRetries)); //if there are less than 10 retries if(startRetries < 10) { //we want to retry at least a few times setReadWriteRetries(10); } else { //don't need to write back the retries since we didn't make a change writebackRetries.cancel(); } //read the updated hardware offset from the node result.m_hardwareOffset = readEeprom(eepromLoc).as_uint16(); bool readSensorSuccess = false; uint8 readSensorTry = 0; do { //perform the read single sensor command uint16 sensorVal = 0; readSensorSuccess = m_baseStation.node_readSingleSensor(m_address, channelNumber, sensorVal); if(readSensorSuccess) { //find the max bits value of the node uint32 maxBitsVal = 0; switch(model()) { case WirelessModels::node_vLink: case WirelessModels::node_sgLink_rgd: case WirelessModels::node_shmLink: maxBitsVal = 65536; break; default: maxBitsVal = 4096; break; } //calculate and store the percent achieved result.m_percentAchieved = static_cast<float>(sensorVal) / static_cast<float>(maxBitsVal) * 100.0f; } readSensorTry++; } while(!readSensorSuccess && readSensorTry <= 3); if(readSensorSuccess) { //mark as questionable if not close enough to the target percentage if(std::abs(result.m_percentAchieved - targetPercent) > 5.0) { result.m_errorCode = WirelessTypes::autobalance_maybeInvalid; } else { result.m_errorCode = WirelessTypes::autobalance_success; } } } return result; }
bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile) { QFile file(fileName); if (!file.exists()) { QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); return false; } int fileType = getFileType(fileName); #if 0 if (fileType==FILE_TYPE_XML) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"), tr("Error opening file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } QTextStream inputStream(&file); XmlInterface(inputStream).load(radioData); } else #endif if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"), tr("Error opening file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } QDomDocument doc(ER9X_EEPROM_FILE_TYPE); bool xmlOK = doc.setContent(&file); if(xmlOK) { std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEepromXml(radioData, doc)); if (errors.test(NO_ERROR)) { ui->modelsList->refreshList(); if(resetCurrentFile) setCurrentFile(fileName); return true; } } file.reset(); QTextStream inputStream(&file); if (fileType==FILE_TYPE_EEPE) { // read EEPE file header QString hline = inputStream.readLine(); if (hline!=EEPE_EEPROM_FILE_HEADER) { file.close(); return false; } } QByteArray eeprom(EESIZE_MAX, 0); int eeprom_size = HexInterface(inputStream).load((uint8_t *)eeprom.data(), EESIZE_MAX); if (!eeprom_size) { QMessageBox::critical(this, tr("Error"), tr("Invalid EEPROM File %1") .arg(fileName)); file.close(); return false; } file.close(); std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(radioData, (uint8_t *)eeprom.data(), eeprom_size)); if (!errors.test(NO_ERROR)) { ShowEepromErrors(this, tr("Error"), tr("Invalid EEPROM File %1").arg(fileName), errors.to_ulong()); return false; } if (errors.test(HAS_WARNINGS)) { ShowEepromWarnings(this, tr("Warning"), errors.to_ulong()); } ui->modelsList->refreshList(); if(resetCurrentFile) setCurrentFile(fileName); return true; } else if (fileType==FILE_TYPE_BIN) { //read binary int eeprom_size = file.size(); if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support QMessageBox::critical(this, tr("Error"), tr("Error opening file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); memset(eeprom, 0, eeprom_size); long result = file.read((char*)eeprom, eeprom_size); file.close(); if (result != eeprom_size) { QMessageBox::critical(this, tr("Error"), tr("Error reading file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } std::bitset<NUM_ERRORS> errorsEeprom((unsigned long long)LoadEeprom(radioData, eeprom, eeprom_size)); if (!errorsEeprom.test(NO_ERROR)) { std::bitset<NUM_ERRORS> errorsBackup((unsigned long long)LoadBackup(radioData, eeprom, eeprom_size, 0)); if (!errorsBackup.test(NO_ERROR)) { ShowEepromErrors(this, tr("Error"), tr("Invalid binary EEPROM File %1").arg(fileName), (errorsEeprom | errorsBackup).to_ulong()); return false; } if (errorsBackup.test(HAS_WARNINGS)) { ShowEepromWarnings(this, tr("Warning"), errorsBackup.to_ulong()); } } else if (errorsEeprom.test(HAS_WARNINGS)) { ShowEepromWarnings(this, tr("Warning"), errorsEeprom.to_ulong()); } ui->modelsList->refreshList(); if(resetCurrentFile) setCurrentFile(fileName); free(eeprom); return true; } return false; }