#include "model/hardware/core/lowLevelApi/TrxBoard.h" template QByteArray TrxBoard::uintLittleEndian2ByteArray(T& data) const { QByteArray byte; QDataStream out(&byte, QIODevice::WriteOnly); out.setByteOrder(QDataStream::LittleEndian); out << data; return byte; } template T TrxBoard::byteArray2UintLittleEndian(QByteArray& byte) const { T data; QDataStream in(byte); in.setByteOrder(QDataStream::LittleEndian); in >> data; return data; } void TrxBoard::sonoLiveTimeout() { _sonoHeartBeats = !_sonoHeartBeats; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); } void TrxBoard::sonoHeartBeatsEnable() const { this->_scenPlayer->control.heartBeatsDisable(false); this->afesHeartBeatDisable(false); } void TrxBoard::sonoHeartBeatsDisable(void) const { this->_scenPlayer->control.heartBeatsDisable(true); this->afesHeartBeatDisable(true); } //void TrxBoard::sendPacket() //{ // auto counter(0); // while(_run) // { // if(_swCounter == 0) // { // std::this_thread::sleep_for(std::chrono::milliseconds(3)); // continue; // } // else if(_swCounter != counter) // { // auto framePacket = QByteArray::fromRawData(_device.getBufferPtr(counter), BUFFER_SIZE); //#ifdef DEVELOP_UI // emit sendFramePacket(framePacket); //#else // packetEngine.newData(framePacket); //#endif // counter++; // if(counter >= SW_BUFFER_NUM) // { // counter = 0; // } // } // } //} void TrxBoard::readData() { _swCounter = _device.getCounter(); while(_run) { auto cnt = _device.getCounter(); if(cnt == 0) { _hwCounter = 0; //std::this_thread::sleep_for(std::chrono::milliseconds(3)); continue; } else if(cnt != _hwCounter) { _hwCounter++; if(_hwCounter > HW_BUFFER_NUM) { _hwCounter = 1; } _device.copy(_hwCounter - 1, _swCounter); auto framePacket = QByteArray::fromRawData(_device.getBufferPtr(_swCounter), BUFFER_SIZE); auto batch = ((static_cast(framePacket[128])) & 0x00FF) | (((static_cast(framePacket[129])) << 8) & 0xFF00); auto subBbatch = ((static_cast(framePacket[130])) & 0x00FF); if((batch == preBatch && subBbatch - preSubBatch != 1) || (preSubBatch == -1 && (batch != 0 || subBbatch != 0)) || (batch - preBatch > 1) || (batch - preBatch == 1 && subBbatch != 0)) { throw HardwareException(DMA_XFER_ERROR, "Batch/subBatch id error occured."); } preBatch = batch; preSubBatch = subBbatch; #ifdef DEVELOP_UI emit sendFramePacket(framePacket); #else packetEngine.newData(framePacket); #endif _swCounter++; if(_swCounter >= SW_BUFFER_NUM) { _swCounter = 0; } } } } void TrxBoard::sramClear(eSramClear clearMode) { quint32 num(0); if(clearMode == all) { while(num < SRAM_SIZE) { this->_device.device.writeLong(BAR_SRAM, static_cast(num), 0); num += sizeof(quint64); } } if(clearMode == first4M) { while(num < SRAM_SIZE / 4) { this->_device.device.writeLong(BAR_SRAM, static_cast(num), 0); num += sizeof(quint64); } } } void TrxBoard::scenParamsFilling(TrxBoard::eScenParams cmd) { static quint8 scenParams = 0; scenParams = cmd ? (scenParams + cmd) : (cmd); if(scenParams >= TOTAL_SCEN_LUT_SRAM) { scenParams = TOTAL_SCEN_LUT_SRAM; _allow = true; } else { _allow = false; } } void TrxBoard::afeAdcsSync(const quint8& slaveMounted) { auto afeSyncStatus = [this](Afe* Slave) { this->_bCtrlMngt->timerShot(1); while(!(Slave->getAfeSyncDone())) { if(this->_bCtrlMngt->checkTimeout()) { throw HardwareException(AFE_ERROR, "The timeout of the afe adcs sync happend without receiving of sync done."); } } this->_bCtrlMngt->timerStop(); if(MOUNTED_SLAVE_FPGA == 7) { quint32 syncErr = Slave->getAfeSyncError(); if(syncErr != 0) { throw HardwareException(AFE_ERROR, "The error of the afe adcs sync happend."); } } }; this->delay(20); this->_misc->setSyncMode(adcSyncMode); this->_misc->setManualSync(true); this->_misc->setManualSync(false); this->_misc->setManualSync(bfSyncMode); if(slaveMounted & 1) { afeSyncStatus(_afeSlave0); } if(slaveMounted & 2) { afeSyncStatus(_afeSlave1); } if(slaveMounted & 4) { afeSyncStatus(_afeSlave2); } } void TrxBoard::waitForCaptureDone(Debug* _dbg) { //Timeout to receive adc capture done. this->_bCtrlMngt->timerShot(1000); while(!(_dbg->getCapDone())) { if(this->_bCtrlMngt->checkTimeout()) { throw HardwareException(AFE_ERROR, "Failure to receive adc capture done."); } } this->_bCtrlMngt->timerStop(); } void TrxBoard::adcCaptureStop(Debug* _dbg) const { _dbg->adcCaptureCmd(captureStop); } void TrxBoard::adcCaptureStart(Debug* _dbg) const { _dbg->adcCaptureCmd(captureStart); } void TrxBoard::adcLogTransferRoutine(Debug* _dbg, quint8 chNumPerFpga) { bool adcSamplerReady(false); bool adcSamplerError(false); //Adc logger start according to selected afe channel. _dbg->adcLoggerTransferCmd(loggerStop); _dbg->adcLoggerChannelNum(chNumPerFpga); _dbg->adcLoggerTransferCmd(loggerStart); //Timeout to receive adc log transfer done. this->_bCtrlMngt->timerShot(20); while(!(_dbg->getTransferDone())) { if(this->_bCtrlMngt->checkTimeout()) { throw HardwareException(AFE_ERROR, "Failure to receive adc log transfer done."); } } this->_bCtrlMngt->timerStop(); //Timeout to receive adc sampler done. this->_bCtrlMngt->timerShot(20); while(!adcSamplerReady && !adcSamplerError) { adcSamplerReady = this->_misc->getAdcSamplerBramReady(); adcSamplerError = this->_misc->getAdcSamplerError(); if(this->_bCtrlMngt->checkTimeout()) { throw HardwareException(AFE_ERROR, "Failure to receive adc sampler done."); } } this->_bCtrlMngt->timerStop(); if(adcSamplerError) { throw HardwareException(AFE_ERROR, "The adc sampler error occured."); } //Adc logger stop _dbg->adcLoggerTransferCmd(loggerStop); } void TrxBoard::debuggerMode(Debug* _dbg, DebugMode& debug, DebugMode& debugRb, QString slaveN) const { _dbg->setDebuggerMode(debug); _dbg->getDebuggerMode(debugRb); if((debugRb.txBfTestModeEn != debug.txBfTestModeEn) || (debugRb.txBfTestModeCfg != debug.txBfTestModeCfg)) { throw ("The debugger mode register configuration of " + slaveN + " is corrupted."); } } void TrxBoard::setSwapVector() { _swapVec.clear(); _swapVec << 0 << 113 << 98 << 19 << 4 << 117 << 102 << 23 << 8 << 121 << 106 << 27 << 12 << 125 << 110 << 31 << 16 << 1 << 114 << 99 << 20 << 5 << 118 << 103 << 24 << 9 << 122 << 107 << 28 << 13 << 126 << 111 << 96 << 17 << 2 << 115 << 100 << 21 << 6 << 119 << 104 << 25 << 10 << 123 << 108 << 29 << 14 << 127 << 112 << 97 << 18 << 3 << 116 << 101 << 22 << 7 << 120 << 105 << 26 << 11 << 124 << 109 << 30 << 15 << 32 << 145 << 130 << 51 << 36 << 149 << 134 << 55 << 40 << 153 << 138 << 59 << 44 << 157 << 142 << 63 << 48 << 33 << 146 << 131 << 52 << 37 << 150 << 135 << 56 << 41 << 154 << 139 << 60 << 45 << 158 << 143 << 128 << 49 << 34 << 147 << 132 << 53 << 38 << 151 << 136 << 57 << 42 << 155 << 140 << 61 << 46 << 159 << 144 << 129 << 50 << 35 << 148 << 133 << 54 << 39 << 152 << 137 << 58 << 43 << 156 << 141 << 62 << 47 << 64 << 177 << 162 << 83 << 68 << 181 << 166 << 87 << 72 << 185 << 170 << 91 << 76 << 189 << 174 << 95 << 80 << 65 << 178 << 163 << 84 << 69 << 182 << 167 << 88 << 73 << 186 << 171 << 92 << 77 << 190 << 175 << 160 << 81 << 66 << 179 << 164 << 85 << 70 << 183 << 168 << 89 << 74 << 187 << 172 << 93 << 78 << 191 << 176 << 161 << 82 << 67 << 180 << 165 << 86 << 71 << 184 << 169 << 90 << 75 << 188 << 173 << 94 << 79; } void TrxBoard::setRomCrc() { unsigned char crcArray[] = {0x4, 0x0, 0x13, 0x0, 0x27, 0x0, 0x28, 0x0, 0xEB, 0x1, 0xAC, 0x5, 0xAC, 0x6, 0x4C, 0x6, 0xB0, 0x6, 0xB2}; for(auto var : crcArray) { _eepromCrc.push_back(static_cast(var)); } } void TrxBoard::setAfeModuleOffset() { _afeModuleOffset.clear(); _afeModuleOffset << 0x1000 << 0x2000 << 0x4000 << 0x8000; } void TrxBoard::setFpgaOffset() { _fpgaOffset.clear(); _fpgaOffset << 0x100000 << 0x200000 << 0x300000; } QList TrxBoard::systemStructure2List(systemE2proms &systemRoms) { QList dataset; dataset.append(systemRoms.trx.id); dataset.append(systemRoms.prbCtrl.id); dataset.append(systemRoms.mps.id); dataset.append(systemRoms.trx.pid); dataset.append(systemRoms.prbCtrl.pid); dataset.append(systemRoms.mps.pid); dataset.append(systemRoms.trx.pcbVersion); dataset.append(systemRoms.prbCtrl.pcbVersion); dataset.append(systemRoms.mps.pcbVersion); dataset.append(systemRoms.trx.firstMbedCodeVersion); dataset.append(systemRoms.mps.firstMbedCodeVersion); dataset.append(systemRoms.trx.secondMbedCodeVersion); dataset.append(systemRoms.mps.secondMbedCodeVersion); // dataset.append(systemRoms.fpgaCodeVersion.masterCode); // dataset.append(systemRoms.fpgaCodeVersion.slave0Code); // dataset.append(systemRoms.fpgaCodeVersion.slave1Code); // dataset.append(systemRoms.fpgaCodeVersion.slave2Code); return dataset; } //QList TrxBoard::signedVector2unsignedList (QVector& sgnVec) //{ //_unsignedQntzrList.clear(); //// std::list _usgnList (sgnVec.begin(), sgnVec.end()); //// _unsignedQntzrList.fromStdList(_usgnList); //foreach (auto i, sgnVec) //{ //_unsignedQntzrList.push_back(static_cast(i)); //} //return _unsignedQntzrList; //} TrxBoard::TrxBoard() : _offsetSlave0(0), _offsetSlave1(0x400000), _offsetSlave2(0x800000) { _beamFormerSlave0 = new BeamFormer(&_device, _offsetSlave0); _beamFormerSlave1 = new BeamFormer(&_device, _offsetSlave1); _beamFormerSlave2 = new BeamFormer(&_device, _offsetSlave2); _debugSlave0 = new Debug(&_device, _offsetSlave0); _debugSlave1 = new Debug(&_device, _offsetSlave1); _debugSlave2 = new Debug(&_device, _offsetSlave2); _clkDistributer = new ClockDistributer(&_device); _afeSlave0 = new Afe(&_device, _offsetSlave0); _afeSlave1 = new Afe(&_device, _offsetSlave1); _afeSlave2 = new Afe(&_device, _offsetSlave2); _bCtrlMngt = new BoardsCtrlMngt(&_device); _builtInTest = new BuiltInTest(&_device); _fpgaProgram = new FpgaProgram(&_device); _scenPlayer = new ScenPalyer(&_device); _spiFlash = new SpiFlash(&_device); _bpiFlash = new BpiFlash(&_device); _emul = new Emulator(&_device); _misc = new Misc(&_device); _sram = new Sram(&_device); _dsp = new Dsp(&_device); _adc = new AdcVoltages; _pg = new VoltagesPg; _tachoRpm = new FanRpm; _coreVolt = new criticalComponentVoltages; _coreTemp = new criticalComponentTemperature; _scenParams = new ScenGenHardwareParam; _sonoLiveTimer = new QTimer; connect(_sonoLiveTimer, &QTimer::timeout, this, &TrxBoard::sonoLiveTimeout); _sonoHeartBeats = false; _allow = false; _run = false; setSwapVector(); setRomCrc(); setFpgaOffset(); setAfeModuleOffset(); preSubBatch = -1; preBatch = 0; } TrxBoard::ScenHwRegister::ScenHwRegister() { elementPosition = new ProbeElementPosition; rxBeamformer = new RxBeamformerProperties; configLut = new ReceiverConfiguration; freqPoint = new FreqPoint; pulse = new PulseProperties; } TrxBoard::ScenGenHardwareParam::ScenGenHardwareParam() { hwRegister = new ScenHwRegister; indexParams = new SramIndex; rxParams = new SramRx; txParams = new SramTx; } TrxBoard::~TrxBoard() { delete _beamFormerSlave0; delete _beamFormerSlave1; delete _beamFormerSlave2; delete _clkDistributer; delete _debugSlave0; delete _debugSlave1; delete _debugSlave2; delete _fpgaProgram; delete _builtInTest; delete _scenPlayer; delete _afeSlave0; delete _afeSlave1; delete _afeSlave2; delete _bCtrlMngt; delete _spiFlash; delete _bpiFlash; delete _emul; delete _misc; delete _sram; delete _dsp; delete _adc; delete _pg; delete _tachoRpm; delete _coreVolt; delete _coreTemp; delete _scenParams; delete _sonoLiveTimer; } TrxBoard::ScenHwRegister::~ScenHwRegister() { delete elementPosition; delete rxBeamformer; delete configLut; delete freqPoint; delete pulse; } TrxBoard::ScenGenHardwareParam::~ScenGenHardwareParam() { delete indexParams; delete hwRegister; delete rxParams; delete txParams; } void TrxBoard::init(bool reset) { this->_device.init(); this->_bCtrlMngt->prbCtrlInit(); if(!reset) { return; } #ifdef MPS_BOARD mpsReset(); #endif sramClear(all); } void TrxBoard::delay(quint16 ms) const { this->_bCtrlMngt->timerShot(ms); //uncrustify off while(!(this->_bCtrlMngt->checkTimeout())); //uncrustify on } void TrxBoard::fpgaProgram(const QString path, const quint8& slaveMounted) const { if(slaveMounted <= 0 || slaveMounted >= 8) { throw HardwareException(SLAVE_PROG_FAILED, "Wrong mounted slave fpga has selected."); } QByteArray bitFileData; QFile bitFile(path); bitFileData.clear(); if(bitFile.fileName().isEmpty()) { throw HardwareException(SLAVE_PROG_FAILED, "No file has selected."); } if(!bitFile.open(QIODevice::ReadOnly)) { throw HardwareException(SLAVE_PROG_FAILED, "Couldn't open bit file programming."); } bitFileData = bitFile.readAll(); bitFile.close(); this->_fpgaProgram->program(bitFileData, slaveMounted); } void TrxBoard::gtReadReset() { QList errorList; bool error(false); QList offsetRd = {0x14008 * 4, 0x114008 * 4, 0x214008 * 4, 0x314008 * 4, 0x1400B * 4, 0x11400B * 4, 0x21400B * 4, 0x31400B * 4, 0x1400C * 4, 0x11400C * 4, 0x21400C * 4, 0x31400C * 4, 0x1400D * 4, 0x11400D * 4, 0x21400D * 4, 0x31400D * 4, 0x14010 * 4, 0x114010 * 4, 0x214010 * 4, 0x314010 * 4, 0x14011 * 4, 0x114011 * 4, 0x214011 * 4, 0x314011 * 4}; QList correctVal = {0x0, 0xFF43, 0xFF43, 0xFF43, 0x0, 0xFFFF, 0xFFFF, 0xFFFF, 0x0, 0xF0F, 0xF0F, 0xF0F, 0xFF43, 0xF04F, 0xFF43, 0xFF43, 0xFFFF, 0xFF00, 0xFFFF, 0xFFFF, 0xF0F, 0xF00, 0xF0F, 0xF0F}; /**************************** GT Read ****************************/ for(auto i = 0; i < 24; i++) { quint32 value = this->_device.device.readWord(BAR_REG, offsetRd.at(i)); if(value == correctVal.at(i)) { errorList.append(false); } else { errorList.append(true); } } foreach(auto& er, errorList) { error |= er; } if(error && MOUNTED_SLAVE_FPGA == 7) { /*************************** GT Reset ***************************/ QList resetAddr; resetAddr << 0x14000 << 0x14003 << 0x114000 << 0x114003 << 0x214000 << 0x214003 << 0x314000 << 0x314003; for(auto value = 2; value >= 0; value--) { foreach(auto& offset, resetAddr) { this->_device.device.writeWord(BAR_REG, offset * 4, static_cast(value)); } } /*************************** Delay (1s) ***************************/ this->delay(1000); /**************************** GT Read *****************************/ for(auto i = 0; i < 24; i++) { quint32 value = this->_device.device.readWord(BAR_REG, offsetRd.at(i)); if(value == correctVal.at(i)) { errorList.append(false); } else { errorList.append(true); } } foreach(auto& er, errorList) { error |= er; } if(error) { throw HardwareException(SCEN_GT_ERROR, "The GT error happened and it didn't solve by gt reset."); } } } void TrxBoard::mcsRead(const QString path) const { QList mcsList; QByteArray byte; quint32 value(0); qint32 num(0); QFile mcsFile(path + "/BPI_bin_rdback.bin"); if(path.isEmpty()) { throw HardwareException(TRX_READ_FAILED, "No file has selected."); } if(!mcsFile.open(QIODevice::WriteOnly)) { throw HardwareException(TRX_READ_FAILED, "Couldn't open BPI bin file programming."); } mcsList = this->_bpiFlash->readMcs(); while(num < BPI_FLASH_SIZE / 4) { value = mcsList[num]; byte = uintLittleEndian2ByteArray(value); mcsFile.write(byte); byte.clear(); num++; } mcsFile.flush(); mcsFile.close(); } void TrxBoard::setProbeDependParams(ScenPrbDepHardwareParam& prbDepParams) { /////////////////////////// AFE setting /////////////////////////// setAfeConfig(prbDepParams.afeCfg); // setAfesPwr(afePwrdnEnable); // setAfesFastPwr(afePwrdnEnable); } void TrxBoard::setScenario(ScenHardware& scenGenHw) { if(this->_scenPlayer->control.getCommand()) { scenPlayerStop(); } emulatorStop(); sramClear(first4M); if(scenGenHw.focusTypeNumber > FOCUS_TYPE_NUMBER_MAX) { throw HardwareException(SCN_ERROR, "Focus type number is out of range."); } _scenParams->focusTypeNumber = scenGenHw.focusTypeNumber; if(scenGenHw.totalTxShotNumber > TOTAL_TX_SHOT_NUMBER_MAX) { throw HardwareException(SCN_ERROR, "Total tx-shot number is out of range."); } _scenParams->totalTxShotNumber = scenGenHw.totalTxShotNumber; if(scenGenHw.rxBeamFormerNumber.size() > RX_BEAMFORMER_NUMBER_MAX) { throw HardwareException(SCN_ERROR, "Rx beamformer number is out of range."); } _scenParams->rxBeamFormerNumber = scenGenHw.rxBeamFormerNumber; if(scenGenHw.hwRegister.scenarioEndIndex > SCENARIO_INDEX_MAX) { throw HardwareException(SCN_ERROR, "Scenario end index is out of range."); } if(scenGenHw.hwRegister.scenarioEndIndex < scenGenHw.hwRegister.scenarioStartIndex) { throw HardwareException(SCN_ERROR, "The scenario end index must be greater than or equal to the scenario start index."); } if(scenGenHw.hwRegister.scenarioEndIndex != (scenGenHw.totalTxShotNumber - 1)) { throw HardwareException(SCN_ERROR, "The scenario end index must be equal to the total tx-shot number minus one."); } _scenParams->scenarioStartIndex = scenGenHw.hwRegister.scenarioStartIndex; _scenParams->scenarioEndIndex = scenGenHw.hwRegister.scenarioEndIndex; if(scenGenHw.hwRegister.blendWeight.size() != BLENDWEIGHT_LUT_MAX) { throw HardwareException(SCN_ERROR, "Blend weight lut is out of range."); } _scenParams->hwRegister->blendWeight = scenGenHw.hwRegister.blendWeight; if(scenGenHw.hwRegister.elementXPosition.size() != ELEMENT_POSITION_LUT_MAX) { throw HardwareException(SCN_ERROR, "Element position x is out of range."); } _scenParams->hwRegister->elementPosition->xPosition = scenGenHw.hwRegister.elementXPosition; if(scenGenHw.hwRegister.elementYPosition.size() != ELEMENT_POSITION_LUT_MAX) { throw HardwareException(SCN_ERROR, "Element position y is out of range."); } _scenParams->hwRegister->elementPosition->yPosition = scenGenHw.hwRegister.elementYPosition; if(scenGenHw.hwRegister.elementZPosition.size() != ELEMENT_POSITION_LUT_MAX) { throw HardwareException(SCN_ERROR, "Element position z is out of range."); } _scenParams->hwRegister->elementPosition->zPosition = scenGenHw.hwRegister.elementZPosition; //if(scenGenHw.hwRegister.freqLut.size() != FREQUENCY_LUT_MAX) //{ //throw HardwareException(SCN_ERROR, "Frequency lut is out of range."); //} //_scenParams->hwRegister->freqLut = scenGenHw.hwRegister.freqLut; if(scenGenHw.hwRegister.dtgcLut.size() != DTGC_LUT_MAX) { throw HardwareException(SCN_ERROR, "Dtgc lut is out of range."); } _scenParams->hwRegister->dtgcLut = scenGenHw.hwRegister.dtgcLut; if(scenGenHw.hwRegister.dualPathWeight.size() != DUAL_PATH_MAX) { throw HardwareException(SCN_ERROR, "Dual path weight is out of range."); } _scenParams->hwRegister->dualPathWeight = scenGenHw.hwRegister.dualPathWeight; if(scenGenHw.hwRegister.pulseTypeNumber > PULSE_LUT_MAX) { throw HardwareException(SCN_ERROR, "Pulse type number is out of range."); } _scenParams->hwRegister->pulseTypeNumber = scenGenHw.hwRegister.pulseTypeNumber; if(scenGenHw.hwRegister.rxBeamFormerTypeNumber > RXBEAMFORMER_LUT_MAX) { throw HardwareException(SCN_ERROR, "Rx beamformer type number is out of range."); } _scenParams->hwRegister->rxBeamFormerTypeNumber = scenGenHw.hwRegister.rxBeamFormerTypeNumber; if(scenGenHw.hwRegister.receiverConfigTypeNumber > RRECEIVER_CONFIGURATION_LUT_MAX) { throw HardwareException(SCN_ERROR, "Receiver config type number is out of range."); } _scenParams->hwRegister->receiverConfigTypeNumber = scenGenHw.hwRegister.receiverConfigTypeNumber; if(scenGenHw.hwRegister.ddcParams.startLpf.size() != LPF_LUT_MAX) { throw HardwareException(SCN_ERROR, "Start lpf lut is out of range."); } if(scenGenHw.hwRegister.ddcParams.endLpf.size() != LPF_LUT_MAX) { throw HardwareException(SCN_ERROR, "End lpf lut is out of range."); } _scenParams->hwRegister->lpfLut.clear(); for(qint8 i = 0; i < LPF_LUT_MAX; i++) { Lpf lpfObj; lpfObj.startLpf = scenGenHw.hwRegister.ddcParams.startLpf.at(i); lpfObj.endLpf = scenGenHw.hwRegister.ddcParams.endLpf.at(i); _scenParams->hwRegister->lpfLut.push_back(lpfObj); } if(scenGenHw.hwRegister.ddcParams.lpfScale.size() != LPF_SCALE_MAX) { throw HardwareException(SCN_ERROR, "Lpf scale coefficient is out of range."); } _scenParams->hwRegister->lpfScaleCoeff = scenGenHw.hwRegister.ddcParams.lpfScale; if(scenGenHw.hwRegister.ddcParams.startFreqLut.size() != START_FREQ_LUT_MAX) { throw HardwareException(SCN_ERROR, "Start freq lut is out of range."); } _scenParams->hwRegister->startFreqLut = scenGenHw.hwRegister.ddcParams.startFreqLut; if(scenGenHw.hwRegister.ddcParams.endFreqLut.size() != END_FREQ_LUT_MAX) { throw HardwareException(SCN_ERROR, "End freq lut is out of range."); } _scenParams->hwRegister->endFreqLut = scenGenHw.hwRegister.ddcParams.endFreqLut; if(scenGenHw.hwRegister.ddcParams.startFreqPoint.size() != FREQ_POINT_LUT_MAX) { throw HardwareException(SCN_ERROR, "Start freq point lut is out of range."); } if(scenGenHw.hwRegister.ddcParams.endFreqPoint.size() != FREQ_POINT_LUT_MAX) { throw HardwareException(SCN_ERROR, "End freq point lut is out of range."); } _scenParams->hwRegister->freqPoint->clear(); for(qint8 i = 0; i < FREQ_POINT_LUT_MAX; i++) { _scenParams->hwRegister->freqPoint->startFreqPoint = scenGenHw.hwRegister.ddcParams.startFreqPoint; _scenParams->hwRegister->freqPoint->endFreqPoint = scenGenHw.hwRegister.ddcParams.endFreqPoint; } if(scenGenHw.hwRegister.ddcParams.freqStepLut.size() != FREQ_STEP_LUT_MAX) { throw HardwareException(SCN_ERROR, "Freq step lut is out of range."); } _scenParams->hwRegister->freqStepLut = scenGenHw.hwRegister.ddcParams.freqStepLut; if(scenGenHw.hwRegister.ddcParams.lpfWeightStepLut.size() != LPF_WEIGHT_STEP_LUT_MAX) { throw HardwareException(SCN_ERROR, "Lpf weight step lut is out of range."); } _scenParams->hwRegister->lpfWeightStepLut = scenGenHw.hwRegister.ddcParams.lpfWeightStepLut; if(scenGenHw.hwRegister.ddcParams.startLpfWeightLut.size() != START_LPF_WEIGHT_LUT_MAX) { throw HardwareException(SCN_ERROR, "Lpf weight step lut is out of range."); } _scenParams->hwRegister->startLpfWeightLut = scenGenHw.hwRegister.ddcParams.startLpfWeightLut; if(scenGenHw.hwRegister.apodizationParams.winOpenStartPoint.size() > RXBEAMFORMER_LUT_MAX) { throw HardwareException(SCN_ERROR, "Apodization parameters are out of range."); } _scenParams->hwRegister->apodizationParams.clear(); for(qint32 j = 0; j < scenGenHw.hwRegister.apodizationParams.winOpenStartPoint.size(); j++) { ApoParams params; params.winOpenStepVal = scenGenHw.hwRegister.apodizationParams.winOpenStepVal.at(j); params.winOpenStopVal = scenGenHw.hwRegister.apodizationParams.winOpenStopVal.at(j); params.maxApertureSize = scenGenHw.hwRegister.apodizationParams.maxApertureSize.at(j); params.minApertureSize = scenGenHw.hwRegister.apodizationParams.minApertureSize.at(j); params.winOpenStartVal = scenGenHw.hwRegister.apodizationParams.winOpenStartVal.at(j); params.winOpenStopPoint = scenGenHw.hwRegister.apodizationParams.winOpenStopPoint.at(j); params.winOpenStartPoint = scenGenHw.hwRegister.apodizationParams.winOpenStartPoint.at(j); params.rxActiveElementStep1 = scenGenHw.hwRegister.apodizationParams.rxActiveElementStep1.at(j); params.rxActiveElementStep2 = scenGenHw.hwRegister.apodizationParams.rxActiveElementStep2.at(j); params.rxActiveElementStepStopPoint = scenGenHw.hwRegister.apodizationParams.rxActiveElementStepStopPoint.at(j); params.rxActiveElementStepStartPoint = scenGenHw.hwRegister.apodizationParams.rxActiveElementStepStartPoint.at(j); params.rxActiveElementStepChangePoint = scenGenHw.hwRegister.apodizationParams.rxActiveElementStepChangePoint.at(j); _scenParams->hwRegister->apodizationParams.push_back(params); } _scenParams->hwRegister->pulse->clear(); foreach(auto i, scenGenHw.hwRegister.pulseProps) { _scenParams->hwRegister->pulse->halfPeriod.append(i.halfPeriod); _scenParams->hwRegister->pulse->startPhase.append(i.startPhase); _scenParams->hwRegister->pulse->halfCycleNo.append(i.halfCycleNo); _scenParams->hwRegister->pulse->pulseVoltSel.append(i.pulseVoltSel); _scenParams->hwRegister->pulse->dampingPulseWidth.append(i.dampingPulseWidth); } _scenParams->hwRegister->rxBeamformer->clear(); foreach(auto j, scenGenHw.hwRegister.rxBeamFormerProps) { _scenParams->hwRegister->rxBeamformer->lag.append(j.lag); _scenParams->hwRegister->rxBeamformer->mla.append(j.mla); _scenParams->hwRegister->rxBeamformer->apodization.append(j.apodizationSel); } _scenParams->hwRegister->configLut->clear(); foreach(auto k, scenGenHw.hwRegister.receiverConfigProps) { _scenParams->hwRegister->configLut->mla.append(k.mla); _scenParams->hwRegister->configLut->stb.append(k.stb); _scenParams->hwRegister->configLut->absEn.append(k.absEn); _scenParams->hwRegister->configLut->ddcEn.append(k.ddcEn); _scenParams->hwRegister->configLut->logEn.append(k.logEn); _scenParams->hwRegister->configLut->stbEn.append(k.stbEn); _scenParams->hwRegister->configLut->lpfSel.append(k.lpfSel); _scenParams->hwRegister->configLut->dTgcEn.append(k.dTgcEn); _scenParams->hwRegister->configLut->blendEn.append(k.blendEn); _scenParams->hwRegister->configLut->aTgcSel.append(k.aTgcSel); _scenParams->hwRegister->configLut->focusNo.append(k.focusNo); _scenParams->hwRegister->configLut->lineMode.append(k.lineMode); _scenParams->hwRegister->configLut->frameType.append(k.frameType); _scenParams->hwRegister->configLut->ncoFreqSel.append(k.ncoFreqSel); _scenParams->hwRegister->configLut->dualPathEn.append(k.dualPathEn); _scenParams->hwRegister->configLut->dcCancelerEn.append(k.dcCancelEn); _scenParams->hwRegister->configLut->iqDataCrossEn.append(k.iqDataCrossEn); _scenParams->hwRegister->configLut->noiseRejectionEn.append(k.noiseRejectEn); _scenParams->hwRegister->configLut->subtractFilterEn.append(k.subtractFilterEn); } _scenParams->hwRegister->mlaOffsetAddr = scenGenHw.hwRegister.mlaOffsetAddr; _scenParams->hwRegister->noiseReject = scenGenHw.hwRegister.noiseRejectValue; _scenParams->hwRegister->frameLoggerControl = scenGenHw.hwRegister.frameLoggerControl; _scenParams->indexParams->endOfEnsemble = scenGenHw.indexParams.endOfEnsemble; _scenParams->indexParams->endOfSubBatch = scenGenHw.indexParams.endOfSubBatch; _scenParams->indexParams->endOfSubFrame = scenGenHw.indexParams.endOfSubFrame; _scenParams->indexParams->isLastSubBatch = scenGenHw.indexParams.isLastSubBatch; _scenParams->indexParams->startOfSubBatch = scenGenHw.indexParams.startOfSubBatch; _scenParams->indexParams->firstLineInFrame = scenGenHw.indexParams.firstLineInFrame; _scenParams->indexParams->shotPropertiesIndex = scenGenHw.indexParams.shotPropertiesIndex; _scenParams->indexParams->pulsePropertiesIndex = scenGenHw.indexParams.pulsePropertiesIndex; _scenParams->indexParams->receiverConfigurationIndex = scenGenHw.indexParams.receiverConfigurationIndex; _scenParams->txParams->maxDelayQ = scenGenHw.txParams.maxDelayQ; _scenParams->txParams->txFocusXPos = scenGenHw.txParams.txFocusXPos; _scenParams->txParams->txFocusYPos = scenGenHw.txParams.txFocusYPos; _scenParams->txParams->txFocusZPos = scenGenHw.txParams.txFocusZPos; _scenParams->txParams->pulseInterval = scenGenHw.pulseInterval; _scenParams->txParams->txActiveElementNumber = scenGenHw.txParams.txActiveElementNumber; _scenParams->txParams->txStartActiveElementNumber = scenGenHw.txParams.txStartActiveElementNumber; _scenParams->rxParams->phiCos = scenGenHw.rxParams.phiCos; _scenParams->rxParams->phiSin = scenGenHw.rxParams.phiSin; _scenParams->rxParams->thetaCos = scenGenHw.rxParams.thetaCos; _scenParams->rxParams->thetaSin = scenGenHw.rxParams.thetaSin; _scenParams->rxParams->r0Position = scenGenHw.rxParams.r0Position; _scenParams->rxParams->interceptXPos = scenGenHw.rxParams.interceptXPos; _scenParams->rxParams->interceptYPos = scenGenHw.rxParams.interceptYPos; _scenParams->rxParams->interceptZPos = scenGenHw.rxParams.interceptZPos; _scenParams->rxParams->rxR0MaxDelayQ = scenGenHw.rxParams.rxR0MaxDelayQ; _scenParams->rxParams->rxR0MinDelayQ = scenGenHw.rxParams.rxR0MinDelayQ; _scenParams->rxParams->txR0MinDelayQ = scenGenHw.rxParams.txR0MinDelayQ; _scenParams->rxParams->rxFocusPointNumber = scenGenHw.rxParams.rxFocusPointNumber; _scenParams->rxParams->rxActiveElementStep = scenGenHw.rxParams.rxActiveElementStep; _scenParams->rxParams->rxR0ActiveElementNumber = scenGenHw.rxParams.rxR0ActiveElementNumber; _scenParams->rxParams->interceptPointFiringTime = scenGenHw.rxParams.interceptPointFiringTime; _scenParams->rxParams->rxR0CenterActiveElementNumber = scenGenHw.rxParams.rxR0CenterActiveElementNumber; if(scenGenHw.apodizationLut.size() != APODIZATIONLUT_LUT_MAX) { throw HardwareException(SCN_ERROR, "Apodization lut is out of range."); } _scenParams->apodizationLut = scenGenHw.apodizationLut; if(scenGenHw.atgcLut.size() != ATGC_LUT_MAX) { throw HardwareException(SCN_ERROR, "Atgc lut is out of range."); } _scenParams->atgcLut = scenGenHw.atgcLut; this->setScenario(_scenParams); } void TrxBoard::setScenario (ScenGenHardwareParam* _scenParams) { ///////////////////////////////// BeamFormer setting /////////////////////////////// QList > elementPosition; QList x; QList y; QList z; //_signedQntzrVec.clear(); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->elementPosition->xPosition, 1, 18, 0, 0, true, true, true); QList xPosQ = _unsignedQntzrVec.toList(); //QList xPosQ = signedVector2unsignedList(_signedQntzrVec); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->elementPosition->yPosition, 1, 18, 0, 0, true, true, true); QList yPosQ = _unsignedQntzrVec.toList(); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->elementPosition->zPosition, 0, 17, 0, 0, true, true, true); QList zPosQ = _unsignedQntzrVec.toList(); for(quint8 i = 0; i < 3; i++) { for(quint8 j = 0; j < SLAVE_ELEMENT_SEGMENT; j++) { x.append(xPosQ.at(_swapVec.at(j + i * SLAVE_ELEMENT_SEGMENT))); y.append(yPosQ.at(_swapVec.at(j + i * SLAVE_ELEMENT_SEGMENT))); z.append(zPosQ.at(_swapVec.at(j + i * SLAVE_ELEMENT_SEGMENT))); } elementPosition.append(x); elementPosition.append(y); elementPosition.append(z); switch(i) { case 0: this->_beamFormerSlave0->probeElementPosition(elementPosition); break; case 1: this->_beamFormerSlave1->probeElementPosition(elementPosition); break; case 2: this->_beamFormerSlave2->probeElementPosition(elementPosition); break; } x.clear(); y.clear(); z.clear(); elementPosition.clear(); } scenParamsFilling(set); this->_beamFormerSlave0->rxBeamformerProperties(_scenParams->hwRegister->rxBeamFormerTypeNumber, _scenParams->hwRegister->rxBeamformer); this->_beamFormerSlave1->rxBeamformerProperties(_scenParams->hwRegister->rxBeamFormerTypeNumber, _scenParams->hwRegister->rxBeamformer); this->_beamFormerSlave2->rxBeamformerProperties(_scenParams->hwRegister->rxBeamFormerTypeNumber, _scenParams->hwRegister->rxBeamformer); scenParamsFilling(set); this->_beamFormerSlave0->pulseProperties(_scenParams->hwRegister->pulseTypeNumber, _scenParams->hwRegister->pulse); this->_beamFormerSlave1->pulseProperties(_scenParams->hwRegister->pulseTypeNumber, _scenParams->hwRegister->pulse); this->_beamFormerSlave2->pulseProperties(_scenParams->hwRegister->pulseTypeNumber, _scenParams->hwRegister->pulse); scenParamsFilling(set); this->_beamFormerSlave0->apodizationParameters(_scenParams->hwRegister->apodizationParams); this->_beamFormerSlave1->apodizationParameters(_scenParams->hwRegister->apodizationParams); this->_beamFormerSlave2->apodizationParameters(_scenParams->hwRegister->apodizationParams); scenParamsFilling(set); ////this->_beamFormerSlave0->afeLut(_scenParams->hwRegister->afe); ////this->_beamFormerSlave1->afeLut(_scenParams->hwRegister->afe); ////this->_beamFormerSlave2->afeLut(_scenParams->hwRegister->afe); ////scenParamsFilling(set); ///////////////////////////////// DSP setting /////////////////////////////// this->_dsp->receiverConfigurationLut(_scenParams->hwRegister->receiverConfigTypeNumber, _scenParams->hwRegister->configLut); //_unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->freqLut, 0, 24, 0, 0, true); //QList freqLutQ = _unsignedQntzrVec.toList(); //this->_dsp->frequencyLut(freqLutQ); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->freqStepLut, 1, 32, 16, 0, true, true, true); QList freqStepLutQ = _unsignedQntzrVec.toList(); this->_dsp->freqStepLut(freqStepLutQ); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->lpfWeightStepLut, 0, 16, 23, 0, true); QList lpfWeightStepLutQ = _unsignedQntzrVec.toList(); this->_dsp->lpfWeightStepLut(lpfWeightStepLutQ); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->startLpfWeightLut, 0, 17, 16, 0, true); QList startLpfWeightLutQ = _unsignedQntzrVec.toList(); this->_dsp->startLpfWeightLut(startLpfWeightLutQ); _unsignedQntzrVec = Calculation::qntzr(_scenParams->hwRegister->dtgcLut, 0, 12, 8, 0, true, false); QList dtgcLutQ = _unsignedQntzrVec.toList(); this->_dsp->dtgcLut(dtgcLutQ); //_unsignedQntzrVec = //Calculation::qntzr(_scenParams->hwRegister->dualPathWeight, 0, 16, 15, 0, true, false); //QList dualPathQ = _unsignedQntzrVec.toList(); //this->_dsp->dualPathWeight(dualPathQ); QList temp; QList > blendWeightQ; //_signedQntzrVec.clear(); foreach(auto vec, _scenParams->hwRegister->blendWeight) { temp.clear(); _unsignedQntzrVec = Calculation::qntzr(vec, 0, 9, 8, 0, true, false, true); temp = _unsignedQntzrVec.toList(); blendWeightQ.push_back(temp); } this->_dsp->blendWeight(blendWeightQ); this->_dsp->mlaOffsetAddr(_scenParams->hwRegister->mlaOffsetAddr); this->_dsp->startFreqLut(_scenParams->hwRegister->startFreqLut); this->_dsp->endFreqLut(_scenParams->hwRegister->endFreqLut); this->_dsp->freqPointLut(_scenParams->hwRegister->freqPoint); this->_dsp->noiseReject(_scenParams->hwRegister->noiseReject); this->_dsp->frameLoggerCtrl(_scenParams->hwRegister->frameLoggerControl); this->_dsp->lpfLut(_scenParams->hwRegister->lpfLut); this->_dsp->lpfScaleCoefficient(_scenParams->hwRegister->lpfScaleCoeff); this->_dsp->dualPathWeight(_scenParams->hwRegister->dualPathWeight); this->_beamFormerSlave0->apodizationLut(_scenParams->apodizationLut); this->_beamFormerSlave1->apodizationLut(_scenParams->apodizationLut); this->_beamFormerSlave2->apodizationLut(_scenParams->apodizationLut); scenParamsFilling(set); this->_dsp->atgcLut(_scenParams->atgcLut); ///////////////////////////////// Sram setting /////////////////////////////// this->_sram->setSramIndex(_scenParams->totalTxShotNumber, _scenParams->indexParams); this->_sram->setSramTx(_scenParams->focusTypeNumber, _scenParams->txParams); this->_sram->setSramRx(_scenParams->rxBeamFormerNumber, _scenParams->focusTypeNumber, _scenParams->rxParams); scenParamsFilling(set); ////////////////////////////// Scen Index setting //////////////////////////// this->_scenPlayer->setStartIndex(_scenParams->scenarioStartIndex); this->_scenPlayer->setEndIndex(_scenParams->scenarioEndIndex); } void TrxBoard::setLineFilterCoefficient(QVector& lineFilterLut) { if(lineFilterLut.size() != LINE_FILTER_LUT_MAX) { throw HardwareException(SCN_ERROR, "Line filter lut is out of range."); } _unsignedQntzrVec = Calculation::qntzr(lineFilterLut, 0, 9, 8, 0, true, false); QList lineFilterLutQ = _unsignedQntzrVec.toList(); this->_dsp->lineFilterCoefficient(lineFilterLutQ); } void TrxBoard::setStbCoefficient(QVector& stbLut) { if(stbLut.size() != STB_COEFFICIENT_LUT_MAX) { throw HardwareException(STB_ERROR, "Stb lut is out of range."); } QList stbLutQ = stbLut.toList(); this->_dsp->stbCoefficient(stbLutQ); } void TrxBoard::setAtgcMode(eAtgcMode mode, quint16 value) const { this->_dsp->atgcMode(mode, value); } void TrxBoard::setDtgcLut(QVector& dtgcLut) { if(dtgcLut.size() != DTGC_LUT_MAX) { throw HardwareException(DTGC_ERROR, "Dtgc lut is out of range."); } _unsignedQntzrVec = Calculation::qntzr(dtgcLut, 0, 12, 8, 0, true, false); QList dtgcLutQ = _unsignedQntzrVec.toList(); this->_dsp->dtgcLut(dtgcLutQ); } void TrxBoard::setFramesMetaData(const QByteArray& metaData) { preSubBatch = -1; preBatch = 0; qint32 metaLength = metaData.length(); if(!metaLength) { throw HardwareException(SCEN_SRAM_ERROR, "Meta data array is empty."); } if(static_cast(metaLength) > META_DATA_LENGTH * 8) { throw HardwareException(SCEN_SRAM_ERROR, "Meta data byte array is out of range."); } QList clear; for(quint8 i = 0; i < META_DATA_LENGTH; i++) { clear.append(0); } this->_sram->setSramMetaData(clear); QList data; QByteArray temp; qint32 num(0); while(metaLength) { for(quint8 j = 0; j < sizeof(quint64); j++) { if(metaLength) { temp.append(metaData[j + num]); metaLength--; } else { temp.append(qint8(0)); } } data.push_back(byteArray2UintLittleEndian(temp)); temp.clear(); num += sizeof(quint64); } this->_sram->setSramMetaData(data); } void TrxBoard::setMChangeParams(SramTx* tx, SramRx* rx) const { quint32 focusTypeNumber = 1; QVector rxBeamFormerNumber = {1}; this->_sram->setSramTx(focusTypeNumber, tx); this->_sram->setSramRx(rxBeamFormerNumber, focusTypeNumber, rx); } void TrxBoard::setBiteDacData(const QByteArray& iData, const QByteArray& qData) const { this->_builtInTest->biteDacEnable(BITE_INTERVAL, false); this->_builtInTest->biteDacMemoryWrite(iData, qData); } void TrxBoard::biteScenPlayerStart() { setDebuggerMode(pulserTr, true); setAdgCfg(adgIQ); setTxDacEnable(BITE_INTERVAL, true); this->scenPlayerStart(true); } void TrxBoard::biteScenPlayerStop() { this->scenPlayerStop(true); setTxDacEnable(BITE_INTERVAL, false); setAdgCfg(adgGnd); setDebuggerMode(pulserHz, true); setDebuggerMode(pulserHz, false); } void TrxBoard::setScenarioCompare(const QString scenPath) { /******************* Create SRAM Binary File *******************/ QString createSramBinary = "/hardware/sramScenarioReadback.bin"; QString saveFile = scenPath + createSramBinary; QFile sramFile(saveFile); if(!sramFile.open(QIODevice::WriteOnly)) { throw HardwareException(SRAM_CMP_ERROR, "Couldn't create the sram binary file due to the wrong path probably."); } quint32 num(0); quint64 value(0); while(num < SRAM_SIZE / 4) { value = _device.device.readLong(BAR_SRAM, static_cast(num)); sramFile.write(uintLittleEndian2ByteArray(value)); num += sizeof(quint64); } sramFile.flush(); sramFile.close(); #ifdef DEVELOP_UI emit sramBinaryCreateFlag(); #endif /******************* Compare Register CSV File *******************/ QString registerScenario = "/hardware/register.csv"; QString regReadParamsPath = scenPath + registerScenario; QFile csvReadFile(regReadParamsPath); if(!csvReadFile.open(QFile::ReadOnly)) { throw HardwareException(SRAM_CMP_ERROR, "Could not open the register's scenario params due to the wrong path probably."); } QString registerCompareScenario = "/hardware/registerCompare.csv"; QString regCompareParamsPath = scenPath + registerCompareScenario; QFile csvWriteFile(regCompareParamsPath); if(!csvWriteFile.open(QFile::WriteOnly)) { throw HardwareException(SRAM_CMP_ERROR, "Couldn't create the register compare file due to the wrong path probably."); } quint32 bar = 0; qint64 readSize = 0; QString line; auto size = csvReadFile.size(); while(readSize < size) { line = csvReadFile.readLine(); auto sl = line.split(','); auto address = sl[0].toUInt(Q_NULLPTR, 16); auto baseValue = sl[1].toUInt(Q_NULLPTR, 16); auto boardValue = _device.device.readWord(bar, address); auto res = "NOK"; if(boardValue == baseValue) { res = "OK"; } auto str = QStringLiteral("%1,%2,%3,%4") .arg(address, 8, 16, QLatin1Char('0')) .arg(baseValue, 8, 16, QLatin1Char('0')) .arg(boardValue, 8, 16, QLatin1Char('0')).arg(res); csvWriteFile.write(str.toStdString().c_str(), str.length()); csvWriteFile.write("\r\n", 2); readSize += static_cast(line.length()); } csvReadFile.close(); csvWriteFile.flush(); csvWriteFile.close(); #ifdef DEVELOP_UI emit registerCsvCompareFlag(); #endif /******************* Compare & Verify SRAM Params *******************/ QString sramScenario = "/hardware/sramScenario.bin"; QString sramReadParamsPath = scenPath + sramScenario; QFile sramReadFile(sramReadParamsPath); if(!sramReadFile.open(QFile::ReadOnly)) { throw HardwareException(SRAM_CMP_ERROR, "Could not open the sram's scenario params due to the wrong path probably."); } qint64 sramScenarioLength = sramReadFile.size(); QByteArray fileByte; fileByte = sramReadFile.readAll(); sramReadFile.close(); num = 0; quint64 boardValue(0); quint64 fileValue(0); QByteArray temp; while(num < sramScenarioLength) { boardValue = _device.device.readLong(BAR_SRAM, static_cast(num)); for(quint8 j = 0; j < sizeof(quint64); j++) { temp.append(fileByte[j + num]); } fileValue = byteArray2UintLittleEndian(temp); if(boardValue != fileValue) { throw HardwareException(SRAM_CMP_ERROR, "The sram scenario file is different to the sram params of board."); } temp.clear(); num += sizeof(quint64); } #ifdef DEVELOP_UI emit sramVerifyMessage("Successful comparision without any difference."); #endif } QList TrxBoard::getAfeReg(eSlaveSelect sel, quint32 afeRegAddr) { QList afeRegValue; quint32 offset(0); afeRegValue.clear(); switch(sel) { case slave0: this->_afeSlave0->setReadRegEnable(true); this->delay(1); for(quint8 i = 0; i < _afeModuleOffset.size(); i++) { offset = (_fpgaOffset.at(slave0) + _afeModuleOffset.at(i) + afeRegAddr) * 4; afeRegValue.push_back(this->_device.device.readWord(BAR_REG, offset)); } this->_afeSlave0->setReadRegEnable(false); break; case slave1: this->_afeSlave1->setReadRegEnable(true); this->delay(1); for(quint8 i = 0; i < _afeModuleOffset.size(); i++) { offset = (_fpgaOffset.at(slave1) + _afeModuleOffset.at(i) + afeRegAddr) * 4; afeRegValue.push_back(this->_device.device.readWord(BAR_REG, offset)); } this->_afeSlave1->setReadRegEnable(false); break; case slave2: this->_afeSlave2->setReadRegEnable(true); this->delay(1); for(quint8 i = 0; i < _afeModuleOffset.size(); i++) { offset = (_fpgaOffset.at(slave2) + _afeModuleOffset.at(i) + afeRegAddr) * 4; afeRegValue.push_back(this->_device.device.readWord(BAR_REG, offset)); } this->_afeSlave2->setReadRegEnable(false); break; } return afeRegValue; } void TrxBoard::setAdgCfg(eBiteDacOutput adg) const { this->_builtInTest->biteAdgCfg(adg); } void TrxBoard::setTxDacEnable(quint8 biteInterval, bool cmd) const { this->_builtInTest->biteDacEnable(biteInterval, cmd); } void TrxBoard::powerAo(bool flag) { if(flag) { this->_bCtrlMngt->mpsDacsOn(); } else { this->_bCtrlMngt->mpsDacsOff(); } } void TrxBoard::slaveFpgaProgram(const QString path) { scenParamsFilling(clear); fpgaProgram(path, MOUNTED_SLAVE_FPGA); #ifndef DEVELOP_UI afeAdcsSync(MOUNTED_SLAVE_FPGA); gtReadReset(); sonoHeartBeatsEnable(); #endif } void TrxBoard::setBeamFormerMode(eClkMode mode) const { this->_clkDistributer->clockMode(CLOCK_DIVISION, mode); } void TrxBoard::afesHvDacsOn() const { setAfesPwr(afePwrdnDisable); // setAfesFastPwr(afePwrdnDisable); #ifdef MPS_BOARD this->_bCtrlMngt->mpsDacsOn(); #endif } void TrxBoard::afesHvDacsOff() const { setAfesPwr(afePwrdnEnable); // setAfesFastPwr(afePwrdnEnable); #ifdef MPS_BOARD this->_bCtrlMngt->mpsDacsOff(); #endif } #ifndef DEVELOP_UI void TrxBoard::scenPlayerStart(int count, bool afeHvPwrOn) { if(_allow) { _run = false; this->_beamFormerSlave0->regValid(true); this->_beamFormerSlave1->regValid(true); this->_beamFormerSlave2->regValid(true); this->_misc->setGtSendMode(bfMode); this->_misc->setSyncMode(bfSyncMode); this->_emul->setEmulatorDis(); this->_device.resetCounter(); this->_device.startDma(); if(afeHvPwrOn) { this->_afeSlave0->setAfeGblPwr(afePwrdnDisable); this->_afeSlave1->setAfeGblPwr(afePwrdnDisable); this->_afeSlave2->setAfeGblPwr(afePwrdnDisable); //quint32 afeFastPdn = 0x43C36C; //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0, static_cast(0)); //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0x400000, //static_cast(0)); //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0x800000, //static_cast(0)); #ifdef MPS_BOARD this->_bCtrlMngt->mpsDacsOn(); #endif this->delay(170); } this->_scenPlayer->control.setCommand(true); _sonoLiveTimer->start(5000); _sonoHeartBeats = true; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); packetEngine.init(); _run = true; QtConcurrent::run(this, &TrxBoard::readLimitedData, count); } else { throw HardwareException(SCEN_START_ERROR, "Total scenario luts and sram parameters have not written compeletely."); } } void TrxBoard::readLimitedData(int count) { int generatedFrame = 0; preBatch = 0; _swCounter = _device.getCounter(); do { auto cnt = _device.getCounter(); if(cnt == 0) { _hwCounter = 0; std::this_thread::sleep_for(std::chrono::milliseconds(3)); continue; } else if(cnt != _hwCounter) { _hwCounter++; if(_hwCounter > HW_BUFFER_NUM) { _hwCounter = 1; } _device.copy(_hwCounter - 1, _swCounter); auto framePacket = QByteArray::fromRawData(_device.getBufferPtr(_swCounter), BUFFER_SIZE); auto batch = ((static_cast(framePacket[128])) & 0x00FF) | (((static_cast(framePacket[129])) << 8) & 0xFF00); auto subBbatch = ((static_cast(framePacket[130])) & 0x00FF); if((batch == preBatch && subBbatch - preSubBatch != 1) || (preSubBatch == -1 && (batch != 0 || subBbatch != 0)) || (batch - preBatch > 1) || (batch - preBatch == 1 && subBbatch != 0)) { //throw; } if(batch != preBatch) { generatedFrame++; } qDebug() << "*******************batch " << batch << "|geteratedFrame " << generatedFrame; preBatch = batch; preSubBatch = subBbatch; packetEngine.newData(framePacket); _swCounter++; if(_swCounter >= SW_BUFFER_NUM) { _swCounter = 0; } } }while (generatedFrame < count); scenStopAfterReadLimited(); } void TrxBoard::scenStopAfterReadLimited() { _run = false; this->_device.stopDma(); //uncrustify off while(_device.isDmaBusy()); //uncrustify on _sonoLiveTimer->stop(); _sonoHeartBeats = false; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); this->_scenPlayer->control.setCommand(false); this->_afeSlave0->setAfeGblPwr(afePwrdnEnable); this->_afeSlave1->setAfeGblPwr(afePwrdnEnable); this->_afeSlave2->setAfeGblPwr(afePwrdnEnable); //quint32 afeFastPdn = 0x43C36C; //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0, static_cast(1)); //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0x400000, static_cast(1)); //this->_device.device.writeWord(BAR_REG, afeFastPdn + 0x800000, static_cast(1)); #ifdef MPS_BOARD this->_bCtrlMngt->mpsDacsOff(); #endif QThread::msleep(140); } #endif /* set afeHvPwrOn true when unfreeze happen */ void TrxBoard::scenPlayerStart(bool unfreezeWithoutScenChanging) { if(isScenarioStart()) { return; } if(_allow) { _run = false; this->_beamFormerSlave0->regValid(true); this->_beamFormerSlave1->regValid(true); this->_beamFormerSlave2->regValid(true); this->_misc->setGtSendMode(bfMode); this->_misc->setSyncMode(bfSyncMode); this->_emul->setEmulatorDis(); this->_device.resetCounter(); this->_device.startDma(); if(unfreezeWithoutScenChanging) { afesHvDacsOn(); this->delay(170); } this->_scenPlayer->control.setCommand(true); #ifndef DEVELOP_UI packetEngine.init(); #endif _sonoLiveTimer->start(5000); _sonoHeartBeats = true; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); _run = true; QtConcurrent::run(this, &TrxBoard::readData); } else { throw HardwareException(SCEN_START_ERROR, "Total scenario luts and sram parameters have not written compeletely."); } } /* set afeHvPwrOff true when freeze happen */ void TrxBoard::scenPlayerStop(bool freezeWithoutScenChanging) { if(!isScenarioStart()) { return; } _run = false; this->_device.stopDma(); this->_scenPlayer->control.setCommand(false); //uncrustify off // while(_device.isDmaBusy()); //uncrustify on _sonoLiveTimer->stop(); _sonoHeartBeats = false; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); if(freezeWithoutScenChanging) { afesHvDacsOff(); this->delay(140); } } bool TrxBoard::isScenarioStart() const { return this->_scenPlayer->control.getCommand(); } //void TrxBoard::scenPlayerPause(bool pause) const //{ //this->_scenPlayer->control.pause(pause); //} void TrxBoard::emulatorInit(EmulatorProperties* config) const { this->_emul->setTransferMode(config->emulOption, config->emulMode, config->transferLength); this->_emul->setRamOffsetAddress(config->ramBufAddress); this->_emul->setTransferRate(config->transferRate); } void TrxBoard::fillRam(QString path) { if(this->_scenPlayer->control.getCommand()) { scenPlayerStop(true); } emulatorStop(); QFile emulFile(path); QByteArray sramData; QByteArray temp; qint32 num(0); sramData.clear(); temp.clear(); if(emulFile.fileName().isEmpty()) { throw HardwareException(EMU_DMA_ERROR, "No file has selected."); } if(!emulFile.open(QIODevice::ReadOnly)) { throw HardwareException(EMU_DMA_ERROR, "Couldn't open frame file to emulator test."); } sramData = emulFile.readAll(); emulFile.close(); while(num < sramData.size()) { for(quint8 j = 0; j < sizeof(quint64); j++) { temp.append(sramData[j + num]); } this->_device.device.writeLong(BAR_SRAM, static_cast(num), byteArray2UintLittleEndian(temp)); temp.clear(); num += sizeof(quint64); } } void TrxBoard::emulatorStart() { _run = false; this->_scenPlayer->control.setCommand(false); this->_emul->setEmulatorEn(); this->_device.resetCounter(); this->_device.startDma(); _sonoLiveTimer->start(5000); _sonoHeartBeats = true; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); _run = true; QtConcurrent::run(this, &TrxBoard::readData); } void TrxBoard::emulatorStop() { _sonoLiveTimer->stop(); _sonoHeartBeats = false; this->_scenPlayer->control.setHeartBeats(_sonoHeartBeats); this->setAfesHeartBeat(_sonoHeartBeats); _run = false; this->_device.stopDma(); this->_emul->setEmulatorDis(); } quint32 TrxBoard::deviceId() const { auto pid = this->_bCtrlMngt->getPid(); return pid; } quint32 TrxBoard::vendorId() const { auto vid = this->_bCtrlMngt->getVid(); return vid; } void TrxBoard::systemCompare(QList ¤tSystem, QList> &systemDataset) const { foreach(auto &lut, systemDataset) { if(lut == currentSystem) { return; } } throw HardwareException(TRX_READ_FAILED, "The system parameters are not compatible."); } void TrxBoard::checkSystemCompatibility(QList &systemLut) { EepromStatus trxE2prom, prbCtrlE2prom, mpsE2prom; this->trxState(trxE2prom); this->prbCtrlState(prbCtrlE2prom); this->mpsState(mpsE2prom); systemE2proms currentSystemRoms; currentSystemRoms.trx = trxE2prom; currentSystemRoms.prbCtrl = prbCtrlE2prom; currentSystemRoms.mps = mpsE2prom; // getFpgasCodeVersion(¤tSystemRoms.fpgaCodeVersion); QList currentSystem = systemStructure2List(currentSystemRoms); QList> systemDataset; foreach(auto lut, systemLut) { systemDataset.append(systemStructure2List(lut)); } systemCompare(currentSystem, systemDataset); } quint8 TrxBoard::crcGenerator(QByteArray inputByteArray) const { quint8 arrayLength = static_cast(inputByteArray.length()); quint8 *input = new quint8[arrayLength]; memcpy(input, inputByteArray, arrayLength); quint8 crcInitialValue(0x00); int i; while(arrayLength--) { crcInitialValue = crcInitialValue ^ *input++; // Apply Byte for(i=0; i<8; i++) // Eight rounds of 1-bit { if (crcInitialValue & 0x80) crcInitialValue = static_cast((crcInitialValue << 1) ^ CRC_POLYNOMIAL); else crcInitialValue = static_cast(crcInitialValue << 1); // Left Shifting } } return(crcInitialValue); } void TrxBoard::crcCheck(const QByteArray array, quint8 crcRom) const { quint8 crcGen = crcGenerator(array); if(crcGen != crcRom) { throw HardwareException(PROBE_CRC_ERROR, "CRC check error happend."); } } void TrxBoard::trxCrcCheck(const QByteArray array, quint32 offset) const { quint8 crcRom = static_cast((this->_bCtrlMngt->trxEepromRead(offset, CRC8_BYTE_NUMBER)).at(0)); crcCheck(array, crcRom); } void TrxBoard::prbCtrlCrcCheck(const QByteArray array, quint32 offset) const { quint8 crcRom = static_cast((this->_bCtrlMngt->prbCtrlEepromRead(offset, CRC8_BYTE_NUMBER)).at(0)); crcCheck(array, crcRom); } void TrxBoard::mpsCrcCheck(const QByteArray array, quint32 offset) const { quint8 crcRom = static_cast((this->_bCtrlMngt->mpsEepromRead(offset, CRC8_BYTE_NUMBER)).at(0)); crcCheck(array, crcRom); } QByteArray TrxBoard::trxRomHeader() const { QByteArray header = (this->_bCtrlMngt->trxEepromRead(EEPROM_HEADER_BEGIN, EEPROM_HEADER_NUMBER)); if(headerArray != header) { throw HardwareException(TRX_READ_FAILED, "The header checksum of the TRX e2prom corrupted."); } return header; } QByteArray TrxBoard::trxRomId() const { QByteArray id = (this->_bCtrlMngt->trxEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER)); trxCrcCheck(id, EEPROM_ID_CRC); return id; } QByteArray TrxBoard::trxRomPid() const { QByteArray pid = (this->_bCtrlMngt->trxEepromRead(EEPROM_PID_BEGIN, EEPROM_PID_NUMBER)); trxCrcCheck(pid, EEPROM_PID_CRC); return pid; } QByteArray TrxBoard::trxRomPcbVersion() const { QByteArray pcb = (this->_bCtrlMngt->trxEepromRead(EEPROM_PCB_VERSION_BEGIN, EEPROM_PCB_VERSION_NUMBER)); trxCrcCheck(pcb, EEPROM_PCB_VERSION_CRC); return pcb; } QByteArray TrxBoard::trxRomSerialNo() const { QByteArray serial = (this->_bCtrlMngt->trxEepromRead(EEPROM_BOARD_SERIAL_NO_BEGIN, EEPROM_BOARD_SERIAL_NO_NUMBER)); trxCrcCheck(serial, EEPROM_BOARD_SERIAL_NO_CRC); return serial; } QByteArray TrxBoard::trxRomFirstMbedCode() const { QByteArray mbed1 = (this->_bCtrlMngt->trxEepromRead(EEPROM_FIRST_MBED_CODE_VERSION_BEGIN, EEPROM_FIRST_MBED_CODE_VERSION_NUMBER)); trxCrcCheck(mbed1, EEPROM_FIRST_MBED_CODE_VERSION_CRC); return mbed1; } QByteArray TrxBoard::trxRomSecondMbedCode() const { QByteArray mbed2 = (this->_bCtrlMngt->trxEepromRead(EEPROM_SECOND_MBED_CODE_VERSION_BEGIN, EEPROM_SECOND_MBED_CODE_VERSION_NUMBER)); trxCrcCheck(mbed2, EEPROM_SECOND_MBED_CODE_VERSION_CRC); return mbed2; } void TrxBoard::trxState(EepromStatus& romStatus) const { QByteArray header; QByteArray id; QByteArray pid; QByteArray pcbVersion; QByteArray serialNo; QByteArray firstMbedCode; QByteArray secondMbedCode; romStatus.ConnectionMode = connected; romStatus.errorCode = EEPROM_NO_ERROR; header = trxRomHeader(); romStatus.header = byteArray2UintBigEndian(header); id = trxRomId(); romStatus.id = byteArray2UintBigEndian(id); pid = trxRomPid(); romStatus.pid = byteArray2UintBigEndian(pid); pcbVersion = trxRomPcbVersion(); romStatus.pcbVersion = byteArray2UintBigEndian(pcbVersion); serialNo = trxRomSerialNo(); romStatus.boardSerialNumber = byteArray2UintBigEndian(serialNo); firstMbedCode = trxRomFirstMbedCode(); romStatus.firstMbedCodeVersion = byteArray2UintBigEndian(firstMbedCode); secondMbedCode = trxRomSecondMbedCode(); romStatus.secondMbedCodeVersion = byteArray2UintBigEndian(secondMbedCode); } QByteArray TrxBoard::mpsRomHeader() const { QByteArray header = (this->_bCtrlMngt->mpsEepromRead(EEPROM_HEADER_BEGIN, EEPROM_HEADER_NUMBER)); if(headerArray != header) { throw HardwareException(MPS_READ_FAILED, "The header checksum of the MPS e2prom corrupted."); } return header; } QByteArray TrxBoard::mpsRomId() const { QByteArray id = (this->_bCtrlMngt->mpsEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER)); mpsCrcCheck(id, EEPROM_ID_CRC); return id; } QByteArray TrxBoard::mpsRomPid() const { QByteArray pid = (this->_bCtrlMngt->mpsEepromRead(EEPROM_PID_BEGIN, EEPROM_PID_NUMBER)); mpsCrcCheck(pid, EEPROM_PID_CRC); return pid; } QByteArray TrxBoard::mpsRomPcbVersion() const { QByteArray pcb = (this->_bCtrlMngt->mpsEepromRead(EEPROM_PCB_VERSION_BEGIN, EEPROM_PCB_VERSION_NUMBER)); mpsCrcCheck(pcb, EEPROM_PCB_VERSION_CRC); return pcb; } QByteArray TrxBoard::mpsRomSerialNo() const { QByteArray serial = (this->_bCtrlMngt->mpsEepromRead(EEPROM_BOARD_SERIAL_NO_BEGIN, EEPROM_BOARD_SERIAL_NO_NUMBER)); mpsCrcCheck(serial, EEPROM_BOARD_SERIAL_NO_CRC); return serial; } QByteArray TrxBoard::mpsRomFirstMbedCode() const { QByteArray mbed1 = (this->_bCtrlMngt->mpsEepromRead(EEPROM_FIRST_MBED_CODE_VERSION_BEGIN, EEPROM_FIRST_MBED_CODE_VERSION_NUMBER)); mpsCrcCheck(mbed1, EEPROM_FIRST_MBED_CODE_VERSION_CRC); return mbed1; } QByteArray TrxBoard::mpsRomSecondMbedCode() const { QByteArray mbed2 = (this->_bCtrlMngt->mpsEepromRead(EEPROM_SECOND_MBED_CODE_VERSION_BEGIN, EEPROM_SECOND_MBED_CODE_VERSION_NUMBER)); mpsCrcCheck(mbed2, EEPROM_SECOND_MBED_CODE_VERSION_CRC); return mbed2; } void TrxBoard::mpsState(EepromStatus& romStatus) const { QByteArray header; QByteArray id; QByteArray pid; QByteArray pcbVersion; QByteArray serialNo; QByteArray firstMbedCode; QByteArray secondMbedCode; romStatus.ConnectionMode = connected; romStatus.errorCode = EEPROM_NO_ERROR; header = mpsRomHeader(); romStatus.header = byteArray2UintBigEndian(header); id = mpsRomId(); romStatus.id = byteArray2UintBigEndian(id); pid = mpsRomPid(); romStatus.pid = byteArray2UintBigEndian(pid); pcbVersion = mpsRomPcbVersion(); romStatus.pcbVersion = byteArray2UintBigEndian(pcbVersion); serialNo = mpsRomSerialNo(); romStatus.boardSerialNumber = byteArray2UintBigEndian(serialNo); firstMbedCode = mpsRomFirstMbedCode(); romStatus.firstMbedCodeVersion = byteArray2UintBigEndian(firstMbedCode); secondMbedCode = mpsRomSecondMbedCode(); romStatus.secondMbedCodeVersion = byteArray2UintBigEndian(secondMbedCode); } QByteArray TrxBoard::prbCtrlRomHeader() const { QByteArray header = (this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_HEADER_BEGIN, EEPROM_HEADER_NUMBER)); if(headerArray != header) { throw HardwareException(RELAY_READ_FAILED, "The header checksum of the relay e2prom corrupted."); } return header; } QByteArray TrxBoard::prbCtrlRomId() const { QByteArray id = (this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER)); prbCtrlCrcCheck(id, EEPROM_ID_CRC); return id; } QByteArray TrxBoard::prbCtrlRomPid() const { QByteArray pid = (this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_PID_BEGIN, EEPROM_PID_NUMBER)); prbCtrlCrcCheck(pid, EEPROM_PID_CRC); return pid; } QByteArray TrxBoard::prbCtrlRomPcbVersion() const { QByteArray pcb = (this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_PCB_VERSION_BEGIN, EEPROM_PCB_VERSION_NUMBER)); prbCtrlCrcCheck(pcb, EEPROM_PCB_VERSION_CRC); return pcb; } QByteArray TrxBoard::prbCtrlRomSerialNo() const { QByteArray serial = (this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_BOARD_SERIAL_NO_BEGIN, EEPROM_BOARD_SERIAL_NO_NUMBER)); prbCtrlCrcCheck(serial, EEPROM_BOARD_SERIAL_NO_CRC); return serial; } void TrxBoard::prbCtrlState(EepromStatus& romStatus) const { QByteArray header; QByteArray id; QByteArray pid; QByteArray pcbVersion; QByteArray serialNo; QByteArray firstMbedCode; QByteArray secondMbedCode; romStatus.ConnectionMode = connected; romStatus.errorCode = EEPROM_NO_ERROR; header = prbCtrlRomHeader(); romStatus.header = byteArray2UintBigEndian(header); id = prbCtrlRomId(); romStatus.id = byteArray2UintBigEndian(id); pid = prbCtrlRomPid(); romStatus.pid = byteArray2UintBigEndian(pid); pcbVersion = prbCtrlRomPcbVersion(); romStatus.pcbVersion = byteArray2UintBigEndian(pcbVersion); serialNo = prbCtrlRomSerialNo(); romStatus.boardSerialNumber = byteArray2UintBigEndian(serialNo); } void TrxBoard::selectedPrbState(EepromStatus& romStatus, eSelectProbe prbSel) const { QVector vec; QByteArray id; QByteArray crcChk; vec = this->_bCtrlMngt->getConnectedPrb(); if(prbSel == prbA && !vec.at(0)) { throw HardwareException(PROBE_SEL_FAILED, "This probe has disconnected."); } if(prbSel == prbB && !vec.at(1)) { throw HardwareException(PROBE_SEL_FAILED, "This probe has disconnected."); } if(prbSel == prbC && !vec.at(2)) { throw HardwareException(PROBE_SEL_FAILED, "This probe has disconnected."); } if(prbSel == prbD && !vec.at(3)) { throw HardwareException(PROBE_SEL_FAILED, "This probe has disconnected."); } romStatus.ConnectionMode = connected; id = this->_bCtrlMngt->prbEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER, prbSel - 1); romStatus.id = byteArray2UintBigEndian(id); crcChk = this->_bCtrlMngt->prbEepromRead(EEPROM_CRC_BEGIN, EEPROM_CRC_NUMBER, prbSel - 1); if(crcChk == _eepromCrc) { romStatus.errorCode = EEPROM_NO_ERROR; } else { romStatus.errorCode = EEPROM_CRC_ERROR; } } void TrxBoard::prbState(PrbCase* prb) const { QVector vec; QByteArray id; QByteArray crcChk; vec = this->_bCtrlMngt->getConnectedPrb(); for(quint8 i(0); i < vec.size(); i++) { switch(i) { case 0: if(vec.at(i)) { prb->prbA.ConnectionMode = connected; id = this->_bCtrlMngt->prbEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER, i); prb->prbA.id = byteArray2UintBigEndian(id); crcChk = this->_bCtrlMngt->prbEepromRead(EEPROM_CRC_BEGIN, EEPROM_CRC_NUMBER, i); if(crcChk == _eepromCrc) { prb->prbA.errorCode = EEPROM_NO_ERROR; } else { prb->prbA.errorCode = EEPROM_CRC_ERROR; } } else { prb->prbA.ConnectionMode = disconnected; prb->prbA.id = 0; prb->prbA.errorCode = EEPROM_NO_ERROR; } break; case 1: if(vec.at(i)) { prb->prbB.ConnectionMode = connected; id = this->_bCtrlMngt->prbEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER, i); prb->prbB.id = byteArray2UintBigEndian(id); crcChk = this->_bCtrlMngt->prbEepromRead(EEPROM_CRC_BEGIN, EEPROM_CRC_NUMBER, i); if(crcChk == _eepromCrc) { prb->prbB.errorCode = EEPROM_NO_ERROR; } else { prb->prbB.errorCode = EEPROM_CRC_ERROR; } } else { prb->prbB.ConnectionMode = disconnected; prb->prbB.id = 0; prb->prbB.errorCode = EEPROM_NO_ERROR; } break; case 2: if(vec.at(i)) { prb->prbC.ConnectionMode = connected; id = this->_bCtrlMngt->prbEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER, i); prb->prbC.id = byteArray2UintBigEndian(id); crcChk = this->_bCtrlMngt->prbEepromRead(EEPROM_CRC_BEGIN, EEPROM_CRC_NUMBER, i); if(crcChk == _eepromCrc) { prb->prbC.errorCode = EEPROM_NO_ERROR; } else { prb->prbC.errorCode = EEPROM_CRC_ERROR; } } else { prb->prbC.ConnectionMode = disconnected; prb->prbC.id = 0; prb->prbC.errorCode = EEPROM_NO_ERROR; } break; case 3: if(vec.at(i)) { prb->prbD.ConnectionMode = connected; id = this->_bCtrlMngt->prbEepromRead(EEPROM_ID_BEGIN, EEPROM_ID_NUMBER, i); prb->prbD.id = byteArray2UintBigEndian(id); crcChk = this->_bCtrlMngt->prbEepromRead(EEPROM_CRC_BEGIN, EEPROM_CRC_NUMBER, i); if(crcChk == _eepromCrc) { prb->prbD.errorCode = EEPROM_NO_ERROR; } else { prb->prbD.errorCode = EEPROM_CRC_ERROR; } } else { prb->prbD.ConnectionMode = disconnected; prb->prbD.id = 0; prb->prbD.errorCode = EEPROM_NO_ERROR; } break; } id.clear(); crcChk.clear(); } } //QString TrxBoard::trxInfo() const //{ // FpgaCodeVersion version; // getFpgasCodeVersion(&version); // QString info = QString(this->_bCtrlMngt->trxEepromRead(EEPROM_INFO_BEGIN, EEPROM_INFO_NUMBER)); // return (info + "(FPM-V " + QString::number(version.masterCode, 10) + // ", FPS-V " + QString::number(version.slave0Code, 10) + ")"); //} //QString TrxBoard::mpsInfo() const //{ // return QString(this->_bCtrlMngt->mpsEepromRead(EEPROM_INFO_BEGIN, EEPROM_INFO_NUMBER)); //} //QString TrxBoard::prbCtrlInfo() const //{ // return QString(this->_bCtrlMngt->prbCtrlEepromRead(EEPROM_INFO_BEGIN, EEPROM_INFO_NUMBER)); //} QByteArray TrxBoard::selectedPrbImpulseResponse(quint8 prbSel) const { return this->_bCtrlMngt->prbEepromRead(EEPROM_IMPULSE_RESPONSE_BEGIN, EEPROM_IMPULSE_RESPONSE_NUMBER, prbSel); } void TrxBoard::prbImpulseResponse(ConnectedPrbInfo* prbInfo) const { QByteArray info; QVector vec; info.clear(); vec.clear(); vec = this->_bCtrlMngt->getConnectedPrb(); for(quint8 i = 0; i < vec.size(); i++) { if(vec.at(i)) { info = this->_bCtrlMngt->prbEepromRead(EEPROM_IMPULSE_RESPONSE_BEGIN, EEPROM_IMPULSE_RESPONSE_NUMBER, i); } else { info.append(nullptr); } switch(i) { case 0: prbInfo->prbA = info; break; case 1: prbInfo->prbB = info; break; case 2: prbInfo->prbC = info; break; case 3: prbInfo->prbD = info; break; } info.clear(); } } void TrxBoard::supervisorRbValue(SupervisorRbValue* sValue) const { this->_bCtrlMngt->getSupervisorValue(sValue); } void TrxBoard::mpsFaultStatus(MpsFaultStatus* faultStatus) const { this->_bCtrlMngt->getMpsFault(faultStatus); } void TrxBoard::mpsPwrOn() const { this->_bCtrlMngt->mpsInit(); } void TrxBoard::mpsPwrOff() const { this->_bCtrlMngt->mpsDeInit(); } void TrxBoard::mpsReset() const { this->_bCtrlMngt->setMpsReset(); } void TrxBoard::mpsSetAo(float voltA, float voltB) const { this->_bCtrlMngt->mpsHvSet(voltA, voltB); } void TrxBoard::selectProbe(eSelectProbe prbSel) { if(this->_scenPlayer->control.getCommand()) { scenPlayerStop(true); } this->_bCtrlMngt->setProbeSelect(prbSel); } void TrxBoard::getHealthStatus(HealthStatus* healStat) const { this->_bCtrlMngt->getFanRpm(_tachoRpm); this->_bCtrlMngt->getTrxVoltagesPg(_pg); this->_bCtrlMngt->getFpgaTemp(_coreTemp); this->_bCtrlMngt->getTrxBoardVoltages(_adc, _pg); this->_bCtrlMngt->getFpgaVccInt(_coreVolt->vccInt); this->_bCtrlMngt->getFpgaVccAux(_coreVolt->vccAux); this->_bCtrlMngt->getFpgaVccBram(_coreVolt->vccBram); healStat->voltsPg = _pg; healStat->adcMon = _adc; healStat->fanRpm = _tachoRpm; healStat->fpgaCoreVoltages = _coreVolt; healStat->fpgaCoreTemperature = _coreTemp; healStat->systemTemperature = this->_bCtrlMngt->getTrxTempSensor(); //healStat->mpsTemperature = this->_bCtrlMngt->getMpsTempSensor(); } void TrxBoard::setTrxFanRpm(const eFanPwm& fan, const quint8& dutyCyclePercent) const { if(dutyCyclePercent > 100) { throw HardwareException(FAN_FAULT_DETECTED, "Out of range for fan duty cycle."); } this->_bCtrlMngt->setFanPwm(fan, dutyCyclePercent); } void TrxBoard::setRegulatorSyncClk(const eRegSync& regType, const regulatorSync& regSyncParams) const { if(regSyncParams.halfPeriod > 8192) { throw HardwareException(TRX_READ_FAILED, "Out of range for PLL sync clk."); } this->_bCtrlMngt->setPllRefClk(regType, regSyncParams); } void TrxBoard::mcsProgram(QString path) { QFile mcsFile(path); if(mcsFile.fileName().isEmpty()) { throw HardwareException(TRX_READ_FAILED, "No file has selected."); } if(!mcsFile.open(QIODevice::ReadOnly)) { throw HardwareException(TRX_READ_FAILED, "Couldn't open BPI bin file programming."); } QByteArray mcsFileData = mcsFile.readAll(); mcsFile.close(); this->_bpiFlash->writeMcs(mcsFileData); } void TrxBoard::mcsVerify(QString path) const { mcsRead(path); } void TrxBoard::spiFlashProgram(QString path) { QFile binFile(path); if(binFile.fileName().isEmpty()) { throw HardwareException(TRX_READ_FAILED, "No file has selected."); } if(!binFile.open(QIODevice::ReadOnly)) { throw HardwareException(TRX_READ_FAILED, "Couldn't open SPI flash bin file programming."); } bin = binFile.readAll(); binFile.close(); this->_spiFlash->writeBin(bin, update); } void TrxBoard::spiFlashRead(QString path) { for(quint8 i(0); i < 2; i++) { QByteArray binArray; QFile binFile(path + "/SPI_bin_rdback.bin"); if(path.isEmpty()) { throw HardwareException(TRX_READ_FAILED, "No file has selected."); } if(!binFile.open(QIODevice::WriteOnly)) { throw HardwareException(TRX_READ_FAILED, "Couldn't open SPI bin file programming."); } binArray = this->_spiFlash->readBin(); binFile.write(binArray); binFile.flush(); binFile.close(); } } void TrxBoard::spiFlashVerify() { QList data; quint32 baseAddr = 0x4000000; bool firstFifo(true); for(qint32 i(0); i < bin.size() / 16; i++) { this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x68, 0x3); for(quint8 i(0); i < 15; i++) { this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x68, 0x0); } this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x70, 0xFFFFFFFE); this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x60, 0x86); delay(1); this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x60, 0x186); delay(1); for(quint8 j(0); j < 16; j++) { data.push_back(this->_device.device.readWord(BAR_SRAM, baseAddr + 0x6C)); if(firstFifo) { if(j >= 4) { if(data[j] != static_cast(bin[j - 4])) { qDebug() << "Error at index: " << (j - 4) << "---" << "rdData=" << QString::number(data[j], 16) << "***" << "binFile=" << QString::number(static_cast(bin[j - 4]), 16); } } } else { if(data[j] != static_cast(bin[(j - 4) + 16 * i])) { qDebug() << "Error at index: " << (j - 4) + 16 * i << "rdData=" << QString::number( data[j], 16) << "***" << "binFile=" << QString::number(static_cast(bin[(j - 4) + 16 * i]), 16); } } } firstFifo = false; data.clear(); } for(quint8 i(0); i < bin.size() % 16; i++) { this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x68, 0x0); } this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x70, 0xFFFFFFFE); delay(1); this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x60, 0x86); delay(1); this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x60, 0x186); delay(1); for(quint8 i(0); i < bin.size() % 16; i++) { data.push_back(this->_device.device.readWord(BAR_SRAM, baseAddr + 0x6C)); if(data[i] != static_cast(bin[(i - 4) + 16 * (bin.size() / 16)])) { qDebug() << "Error at index: " << (i - 4) + 16 * (bin.size() / 16) << "rdData=" << QString::number( data[i], 16) << "***" << "binFile=" << QString::number(static_cast(bin[(i - 4) + 16 * (bin.size() / 16)]), 16); } delay(1); } this->_device.device.writeWord(BAR_SRAM, baseAddr + 0x70, 0x1); qDebug() << "Verification End."; } void TrxBoard::getTrxStatus(StatusVec* status) const { this->_misc->getStatusVector(status); } void TrxBoard::getFpgasCodeVersion(FpgaCodeVersion* version) const { this->_misc->getFpgaVersion(version); } void TrxBoard::sramParityClear() { quint64 val; val = this->_device.device.readLong(BAR_SRAM, 0); this->_device.device.writeLong(BAR_SRAM, 0, val); } quint32 TrxBoard::getFrameLostCounter() const { return (this->_misc->getFrameLostCount()); } void TrxBoard::elementActiveEnable(eActiveElements& slaveElements, quint64& elements) const { QList littleEndianList; quint32 highElements = elements >> 32; quint32 lowElements = elements & 0xFFFFFFFF; littleEndianList.push_back(lowElements); littleEndianList.push_back(highElements); switch(slaveElements) { case slave0Elements: this->_beamFormerSlave0->elementActiveEn(littleEndianList); break; case slave1Elements: this->_beamFormerSlave1->elementActiveEn(littleEndianList); break; case slave2Elements: this->_beamFormerSlave2->elementActiveEn(littleEndianList); break; } } void TrxBoard::adcCaptureConfig(captureConfig& capCfg) const { //ADC capture config this->_debugSlave0->adcLoggerConfig(capCfg); this->_debugSlave1->adcLoggerConfig(capCfg); this->_debugSlave2->adcLoggerConfig(capCfg); } void TrxBoard::adcCaptureStart(void) const { //ADC capture reset this->_debugSlave0->adcLoggerRst(true); this->_debugSlave1->adcLoggerRst(true); this->_debugSlave2->adcLoggerRst(true); this->_debugSlave0->adcLoggerRst(false); this->_debugSlave1->adcLoggerRst(false); this->_debugSlave2->adcLoggerRst(false); //ADC capture start adcCaptureStart(_debugSlave0); adcCaptureStart(_debugSlave1); adcCaptureStart(_debugSlave2); } void TrxBoard::setCaptureManualSync(void) const { this->_misc->setSyncMode(otherAdcLogMode); this->_misc->setManualSync(true); this->_misc->setManualSync(false); this->_misc->setSyncMode(bfSyncMode); } void TrxBoard::adcCaptureDone(void) { if(MOUNTED_SLAVE_FPGA & 1) { waitForCaptureDone(_debugSlave0); } if(MOUNTED_SLAVE_FPGA & 2) { waitForCaptureDone(_debugSlave1); } if(MOUNTED_SLAVE_FPGA & 4) { waitForCaptureDone(_debugSlave2); } adcCaptureStop(_debugSlave0); adcCaptureStop(_debugSlave1); adcCaptureStop(_debugSlave2); } void TrxBoard::adcLoggerStart(const QString path, const QString fileName) { quint8 fpgaSel(0); quint8 chNumPerFpga(0); QTime t = QTime::currentTime(); QString logPath = path + "/" + fileName + "_adcLog" + QString("_%1_%2_%3.csv") .arg(t.hour()) .arg(t.minute()) .arg(t.second()); QFile logFile(logPath); QTextStream log(&logFile); if(logPath.isEmpty()) { throw HardwareException(AFE_ERROR, "No file has selected."); } if(!logFile.open(QIODevice::WriteOnly)) { throw HardwareException(AFE_ERROR, "Couldn't open file for logging."); } log << "SYNC Offset(ns): "; if(MOUNTED_SLAVE_FPGA & 1) { log << this->_debugSlave0->getCapSyncOffset() * 5 << ", "; } if(MOUNTED_SLAVE_FPGA & 2) { log << this->_debugSlave1->getCapSyncOffset() * 5 << ", "; } if(MOUNTED_SLAVE_FPGA & 4) { log << this->_debugSlave2->getCapSyncOffset() * 5; } log << endl; log << "ADC Sample Latancy(ns): "; if(MOUNTED_SLAVE_FPGA & 1) { log << this->_afeSlave0->getAdcLatency() * 2.5f << ", "; } if(MOUNTED_SLAVE_FPGA & 2) { log << this->_afeSlave1->getAdcLatency() * 2.5f << ", "; } if(MOUNTED_SLAVE_FPGA & 4) { log << this->_afeSlave2->getAdcLatency() * 2.5f; } log << endl; log << "ADC Sample Logger Offset(sample): "; if(MOUNTED_SLAVE_FPGA & 1) { log << this->_debugSlave0->getCaptureSampleNo() << ", "; } if(MOUNTED_SLAVE_FPGA & 2) { log << this->_debugSlave1->getCaptureSampleNo() << ", "; } if(MOUNTED_SLAVE_FPGA & 4) { log << this->_debugSlave2->getCaptureSampleNo(); } log << endl; //Set gt to adc mode. this->_misc->setGtSendMode(adcMode); //Stop adc log transfer. this->_debugSlave0->adcLoggerTransferCmd(loggerStop); this->_debugSlave1->adcLoggerTransferCmd(loggerStop); this->_debugSlave2->adcLoggerTransferCmd(loggerStop); quint8 afeChannelNum = AFE_CHANNEL_NUM_PER_SLAVE * ( ((MOUNTED_SLAVE_FPGA & 4) >> 2) + ((MOUNTED_SLAVE_FPGA & 2) >> 1) + (MOUNTED_SLAVE_FPGA & 1)); for(quint8 chNum = 0; chNum < afeChannelNum; chNum++) { fpgaSel = chNum / AFE_CHANNEL_NUM_PER_SLAVE; chNumPerFpga = chNum % AFE_CHANNEL_NUM_PER_SLAVE; //ADC sampler start according to selected fpga. this->_misc->setAdcSamplerCmd(samplerStop); this->_misc->setAdcSamplerFpgaSel(fpgaSel); this->_misc->setAdcSamplerCmd(samplerStart); switch(fpgaSel) { case 0: this->adcLogTransferRoutine(_debugSlave0, chNumPerFpga); break; case 1: this->adcLogTransferRoutine(_debugSlave1, chNumPerFpga); break; case 2: this->adcLogTransferRoutine(_debugSlave2, chNumPerFpga); break; } //Read adc data bram. QList adcDataList = this->_misc->getAdcDataBram(); foreach(auto data, adcDataList) { log << data << ','; } log << endl; //ADC sampler stop. this->_misc->setAdcSamplerCmd(samplerStop); } logFile.flush(); logFile.close(); //Set gt to beamformer mode. this->_misc->setGtSendMode(bfMode); } void TrxBoard::setDebuggerMode(eDebugMode bfMode, bool enable) { DebugMode debug; DebugMode debugRb; debug.rxBfDbgModeEn = false; debug.rxBfSimDataGenModeEn = false; debug.txBfTestModeEn = enable; debug.txBfTestModeCfg = bfMode; this->debuggerMode(_debugSlave0, debug, debugRb, "slave0"); this->debuggerMode(_debugSlave1, debug, debugRb, "slave1"); this->debuggerMode(_debugSlave2, debug, debugRb, "slave2"); } void TrxBoard::setAfeConfig(AfeConfig& afeCfg) const { this->_afeSlave0->setAfeParams(afeCfg); this->_afeSlave1->setAfeParams(afeCfg); this->_afeSlave2->setAfeParams(afeCfg); } void TrxBoard::setAfesPwr(eAfePwrdnMode pwrMode) const { this->_afeSlave0->setAfeGblPwr(pwrMode); this->_afeSlave1->setAfeGblPwr(pwrMode); this->_afeSlave2->setAfeGblPwr(pwrMode); } void TrxBoard::setAfesFastPwr(eAfePwrdnMode pwrMode) const { this->_afeSlave0->setAfeFastPwr(pwrMode); this->_afeSlave1->setAfeFastPwr(pwrMode); this->_afeSlave2->setAfeFastPwr(pwrMode); } void TrxBoard::setAfesHeartBeat(const bool heartBeat) const { this->_afeSlave0->setAfeHeartBeat(heartBeat); this->_afeSlave1->setAfeHeartBeat(heartBeat); this->_afeSlave2->setAfeHeartBeat(heartBeat); } void TrxBoard::afesHeartBeatDisable(const bool mode) const { this->_afeSlave0->heartBeatsDisable(mode); this->_afeSlave1->heartBeatsDisable(mode); this->_afeSlave2->heartBeatsDisable(mode); }