eprintf("Unable to send configuration to module controller: %s\n", err.getString().retStr());
break;
}
}
opuServersLock.unlock();
}
olock.unlock();
return err;
}
BError Control::getConfiguration(ConfigInfo& configInfo){
BError err;
dprintf(DBG_CMD, "Control::getConfiguration: Return: %d\n", oconfigInfo.puReferences.size());
olock.lock();
configInfo = oconfigInfo;
olock.unlock();
return err;
}
BError Control::test(BList<BError>& errors){
BError errRet;
BError err;
BIter i;
BIter i1;
BList<BError> errList;
dprintf(DBG_CMD, "Control::test\n");
opuServersLock.rdLock();
if(!osimulate){
// Local tests
// Disk space
if(diskSpace("/") < 1000){
errors.append(BError(1, "TmsServer: Diskspace /: Low"));
}
else {
errors.append(BError(0, "TmsServer: Diskspace /: Ok"));
}
if(diskSpace("/data") < 1000){
errors.append(BError(1, "TmsServer: Diskspace /data: Low"));
}
else {
errors.append(BError(0, "TmsServer: Diskspace /data: Ok"));
}
// Memory
if(memoryFree() < 200){
errors.append(BError(1, "TmsServer: Memory: Low"));
}
else {
errors.append(BError(0, "TmsServer: Memory: Ok"));
}
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
if(err = opuServers[i]->test(errList)){
errors.append(BError(err.getErrorNo(), BString("Module") + opuServers[i]->getNumber() + ": Status: " + err.getString()));
}
else {
errors.append(BError(0, BString("Module") + opuServers[i]->getNumber() + ": Status: Ok"));
for(errList.start(i1); !errList.isEnd(i1); errList.next(i1)){
errors.append(errList[i1]);
}
}
}
}
opuServersLock.unlock();
return errRet;
}
BError Control::getStatus(BList<NameValue>& statusList){
BError errRet;
BError err;
BIter i;
BIter i1;
BList<NameValue> puStatusList;
dprintf(DBG_CMD, "Control::getStatus\n");
opuServersLock.rdLock();
if(!osimulate){
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
if(err = opuServers[i]->getStatus(puStatusList)){
statusList.append(NameValue(BString("Module") + opuServers[i]->getNumber() + "_Running", "0"));
}
else {
for(puStatusList.start(i1); !puStatusList.isEnd(i1); puStatusList.next(i1)){
statusList.append(puStatusList[i1]);
}
}
}
}
opuServersLock.unlock();
statusList.append(NameValue("TmsServer_Running", "1"));
statusList.append(NameValue("TmsServer_CycleNumber", ocycleNumber.value()));
statusList.append(NameValue("TmsServer_CycleType", ocycleType));
statusList.append(NameValue("TmsServer_ConnectionsNumber", oboapServer.getConnectionsNumber()));
return errRet;
}
BError Control::getStatistics(BList<NameValue>& statsList){
BError err;
BIter i;
BIter i1;
BList<NameValue> puStatsList;
dprintf(DBG_CMD, "Control::getStatistics\n");
opuServersLock.rdLock();
if(!osimulate){
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
puStatsList.clear();
opuServers[i]->getStatistics(puStatsList);
for(puStatsList.start(i1); !puStatsList.isEnd(i1); puStatsList.next(i1)){
statsList.append(puStatsList[i1]);
}
}
}
opuServersLock.unlock();
statsList.append(NameValue("TmsServer_UpTime", getTime() - ostartTime));
statsList.append(NameValue("TmsServer_CycleNumProcessed", ocycleProcessed));
statsList.append(NameValue("TmsServer_NextCycleErrors", onumNextCycleErrors));
statsList.append(NameValue("TmsServer_FpgaStateErrors", onumFpgaStateErrors));
statsList.append(NameValue("TmsServer_DataGoneErrors", onumDataGoneErrors));
return err;
}
BError Control::getPuChannel(UInt32& puChannel, PuChannel& puPhysChannel){
BError err;
dprintf(DBG_CMD, "Control::getPuChannel\n");
olock.lock();
if((puChannel < 1) || (puChannel > oconfigInfo.puReferences.size())){
olock.unlock();
return err.set(ErrorParam, "PuChannel out of range");
}
puPhysChannel = oconfigInfo.puReferences[puChannel - 1];
olock.unlock();
return err;
}
BError Control::puServerStarted(UInt32 number){
BError err;
dprintf(DBG_CMD, "Control::puServerStarted: %u\n", number);
olock.lock();
initPuServer(number);
olock.unlock();
return err;
}
BError Control::setSimulation(Simulation simulation){
BError err;
uint32_t chan;
BArray<UInt32> data;
BFile file;
int nb;
BIter i;
PuChannel puChan;
PupeConfig pupeConfig;
UInt32 cn;
BString ct;
BString testSignalFileName = "beam3-437000-8.psd";
BString cycleType = "SimBeam3";
// Read the test signal file
if(err = file.open(testSignalFileName, "r")){
if(err = file.open(BString("/usr/tms/data/") + testSignalFileName, "r")){
return err.set(ErrorMisc, BString("Error: Opening file: ") + testSignalFileName);
}
}
data.resize(1024);
if((nb = file.read(&data[0], 1024 * sizeof(UInt32))) <= 0){
return err.set(1, BString("Error: Reading 1024 32bit data items from file: ") + testSignalFileName);
}
data.resize(nb / sizeof(UInt32));
// Setup timing
pupeConfig.adcSysclkSync = 0;
if(simulation.timing)
pupeConfig.internalTimingMask = 0x7f; // All internal event signals
else
pupeConfig.internalTimingMask = 0x00; // No internal event signals
pupeConfig.disableBlr = 0;
opuServersLock.rdLock();
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
if(err = opuServers[i]->getMasterPuChannel(puChan)){
opuServersLock.unlock();
return err;
}
if(err = setPupeConfig(puChan, pupeConfig)){
return err;
}
}
opuServersLock.unlock();
// Setup data
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
if(err = setTestData(oconfigInfo.puReferences[chan], simulation.data, data)){
return err;
}
}
// Setup setNextCycle
osimulation = simulation;
if(osimulation.cycleType != "")
cycleType = osimulation.cycleType;
// Sets the CycleType to match the data
if(err = getCycleInfo(cn, ct)){
return err.set(ErrorMisc, BString("Error: Getting Cycle Number: ") + err.getString());
}
// Set NextCycle type
if(err = setNextCycleInternal(cn + 1, cycleType)){
return err.set(ErrorMisc, BString("Error: Setting Next Cycle: ") + err.getString());
}
return err;
}
BError Control::getSimulation(Simulation& simulation){
BError err;
olock.lock();
simulation = osimulation;
olock.unlock();
return err;
}
BError Control::setTestMode(PuChannel puPhysChannel, UInt32 testOutput, UInt32 timingDisableMask){
BError err;
opuServersLock.rdLock();
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->setTestMode(puPhysChannel, testOutput, timingDisableMask);
opuServersLock.unlock();
return err;
}
BError Control::setTimingSignals(PuChannel puPhysChannel, UInt32 timingSignals){
BError err;
opuServersLock.rdLock();
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->setTimingSignals(puPhysChannel, timingSignals);
opuServersLock.unlock();
return err;
}
BError Control::captureDiagnostics(PuChannel puPhysChannel, TestCaptureInfo captureInfo, BArray<UInt64>& data){
BError err;
opuServersLock.rdLock();
if(osimulate){
err = getSimCaptureData(captureInfo, data);
}
else {
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->captureDiagnostics(puPhysChannel, captureInfo, data);
}
opuServersLock.unlock();
return err;
}
BError Control::setTestData(PuChannel puPhysChannel, Int32 on, BArray<UInt32> data){
BError err;
opuServersLock.rdLock();
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->setTestData(puPhysChannel, on, data);
opuServersLock.unlock();
return err;
}
BError Control::setPupeConfig(PuChannel puPhysChannel, PupeConfig pupeConfig){
BError err;
opuServersLock.rdLock();
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->setPupeConfig(puPhysChannel, pupeConfig);
opuServersLock.unlock();
return err;
}
BError Control::getPupeConfig(PuChannel puPhysChannel, PupeConfig& pupeConfig){
BError err;
opuServersLock.rdLock();
if((puPhysChannel.moduleNum < 1) || (puPhysChannel.moduleNum > opuServers.number())){
opuServersLock.unlock();
return err.set(ErrorParam, BString("PuChannel.moduleNum: ") + puPhysChannel.moduleNum + " is invalid");
}
err = opuServers[puPhysChannel.moduleNum - 1]->getPupeConfig(puPhysChannel, pupeConfig);
opuServersLock.unlock();
return err;
}
BError Control::setControlInfo(CycleParam params){
BError err;
BIter i;
BString sptDir = config.findValue("SptDir:");
CycleParamDb cycleParamFiles(sptDir);
int updated = 0;
dprintf(DBG_CMD, "Control::setControlInfo\n");
// Add to internal database
olock.lock();
for(ocycleParms.start(i); !ocycleParms.isEnd(i); ocycleParms.next(i)){
if((ocycleParms[i].cycleType == params.cycleType) && (ocycleParms[i].channel == params.channel)){
ocycleParms[i] = params;
updated = 1;
break;
}
}
if(!updated)
ocycleParms.append(params);
olock.unlock();
opuServersLock.rdLock();
if(!osimulate){
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
if(err = opuServers[i]->setControlInfo(params)){
opuServersLock.unlock();
return err;
}
}
}
opuServersLock.unlock();
// Save to files
olock.lock();
err = cycleParamFiles.setCycleParams(params);
olock.unlock();
return err;
}
BError Control::getControlInfo(BString cycleType, UInt32 puChannel, CycleParam& params){
BError err;
BIter i;
olock.lock();
for(ocycleParms.start(i); !ocycleParms.isEnd(i); ocycleParms.next(i)){
if((ocycleParms[i].cycleType == cycleType) && (ocycleParms[i].channel == puChannel)){
params = ocycleParms[i];
olock.unlock();
return err;
}
}
olock.unlock();
err.set(ErrorMisc, BString("Cycle parameters not found for cycle type: ") + cycleType);
return err;
}
BError Control::delControlInfo(BString cycleType, UInt32 puChannel){
BError err;
BString sptDir = config.findValue("SptDir:");
CycleParamDb cycleParamFiles(sptDir);
BIter i;
dprintf(DBG_CMD, "Control::delControlInfo: %s, %u\n", cycleType.retStr(), puChannel);
olock.lock();
for(ocycleParms.start(i); !ocycleParms.isEnd(i); ocycleParms.next(i)){
if((ocycleParms[i].cycleType == cycleType) && (ocycleParms[i].channel == puChannel)){
ocycleParms.del(i);
break;
}
}
olock.unlock();
// Deleted. I don't want the .spt file wiped out. - JMB
// olock.lock();
// err = cycleParamFiles.deleteCycleParams(cycleType, puChannel);
// olock.unlock();
return err;
}
BError Control::getControlList(BList<CycleParamItem>& itemList){
BError err;
BIter i;
itemList.clear();
olock.lock();
for(ocycleParms.start(i); !ocycleParms.isEnd(i); ocycleParms.next(i)){
itemList.append(CycleParamItem(ocycleParms[i].cycleType, ocycleParms[i].channel));
}
olock.unlock();
return err;
}
BError Control::setNextCycle(UInt32 cycleNumber, BString cycleType){
if(osimulation.setNextCycle)
return BError(ErrorMisc, "System is simulating the setNextCycle call");
else
return setNextCycleInternal(cycleNumber, cycleType);
}
BError Control::setNextCycleInternal(UInt32 cycleNumber, BString cycleType){
BError err;
BIter i;
int t = 0;
double ts, tm[8], te;
static double tmax;
dprintf(DBG_CMD | DBG_EVENT, "Control::setNextCycleInternal: Num(%d) Type(%s)\n", cycleNumber, cycleType.retStr());
ocycleNumberNext = cycleNumber;
ocycleTypeNext = cycleType;
opuServersLock.rdLock();
if(!osimulate){
tm[t++] = ts = getTime();
for(opuServers.start(i); !opuServers.isEnd(i); opuServers.next(i)){
if(err = opuServers[i]->setNextCycle(cycleNumber, cycleType)){
opuServersLock.unlock();
dprintf(DBG_CMD | DBG_EVENT, "Control::setNextCycle: Done: Error: %s\n", err.getString().retStr());
return err;
}
tm[t++] = getTime();
}
te = getTime();
if((te - ts) > tmax){
tmax = te - ts;
}
tm[3] = tm[3] - tm[2];
tm[2] = tm[2] - tm[1];
tm[1] = tm[1] - tm[0];
dprintf(DBG_SETNEXTCYCLE, "Control::setNextCycle: Times: %f,%f,%f = %f MaxTime: %f\n", tm[1],tm[2],tm[3], te - ts, tmax);
}
opuServersLock.unlock();
dprintf(DBG_CMD | DBG_EVENT, "Control::setNextCycle: Done\n");
return err;
}
BError Control::getCycleInfo(UInt32& cycleNumber, BString& cycleType){
BError err;
dprintf(DBG_CMD, "Control::getCycleInfo\n");
cycleNumber = ocycleNumber.value();
cycleType = ocycleType;
return err;
}
BError Control::getCycleInformation(UInt32 cycleNumber, CycleInformation& cycleInformation){
BError err;
PuChannel puPhysChannel(1, 1, 1);
dprintf(DBG_CMD, "Control::getCycleInformation\n");
if(err = waitForData(cycleNumber))
return err;
opuServersLock.rdLock();
err = opuServers[puPhysChannel.moduleNum - 1]->getCycleInformation(cycleNumber, cycleInformation);
opuServersLock.unlock();
return err;
}
BError Control::getCycleTypeInformation(BString cycleType, CycleTypeInformation& cycleTypeInformation){
BError err;
CycleParam params;
BUInt32 n;
CycleTypeInformationPeriod period;
dprintf(DBG_CMD, "Control::getCycleTypeInformation\n");
if(err = getControlInfo(cycleType, 0, params))
return err;
cycleTypeInformation.cycleType = cycleType;
cycleTypeInformation.info = params.info;
for(n = 0; n < params.stateTable.size(); n++){
if(params.stateTable[n].period){
period.cyclePeriod = params.stateTable[n].period;
period.harmonic = params.stateTable[n].harmonic;
period.numBunches = params.stateTable[n].numBunches;
period.bunchMask = params.stateTable[n].bunchMask;
cycleTypeInformation.periods.append(period);
}
}
return err;
}
BError Control::waitForData(BUInt32 cycleNumber){
BError err;
Int32 diff;
// In the initial state we need to check if we have actually captured the cycle
dprintf(DBG_MISC, "Control::waitForData: RequiredCycle: %u CurrentCycle: %u CompletedCycle: %u\n", cycleNumber, ocycleNumber.value(), ocycleCompleteNumber.value());
// First check if we are within the possible cycle range
diff = cycleNumber - ocycleCompleteNumber.value();
if(diff < -4)
return err.set(ErrorDataGone, BString("TmsServer: Cycle's data has already been overwritten: Current: ") + ocycleCompleteNumber.value() + " Requested: " + cycleNumber);
if(diff > 256)
return err.set(ErrorDataFuture, BString("TmsServer: Cycle data required is to far in the future: Current: ") + ocycleCompleteNumber.value() + " Requested: " + cycleNumber);
// Need Timeout
ocycleCompleteNumber.waitMoreThanOrEqual(cycleNumber);
return err;
}
void Control::errorEvent(UInt32 cycleNumber, BError error){
dprintf(DBG_EVENT, "Control::errorEvent: %d %s\n", cycleNumber, error.getString().retStr());
ocycleInfoList.cycleAddError(cycleNumber, error);
if(error.getErrorNo() == ErrorStateTable)
onumFpgaStateErrors++;
oeventServers.errorEvent(cycleNumber, error);
}
void Control::cycleStartEvent(UInt32 cycleNumber){
UInt32 currentCycleNumber = ocycleNumber.value();
dprintf(DBG_EVENT, "Control::cycleStartEvent: Cycle: %u CurrentCycle: %u NextCycle: %u CompleCycle: %u\n", cycleNumber, currentCycleNumber, ocycleNumberNext, ocycleCompleteNumber.value());
ocycleNumber.setValue(cycleNumber);
ocycleType = ocycleTypeNext;
ocycleInfoList.cycleAdd(cycleNumber, ocycleTypeNext);
if(cycleNumber == currentCycleNumber){
onumNextCycleErrors++;
errorEvent(cycleNumber, BError(ErrorCycleNumber, "Cycle Information has not been received"));
}
oeventServers.cycleStartEvent(cycleNumber);
}
void Control::cycleStopEvent(UInt32 cycleNumber){
BIter i;
BError err;
double t1, t2;
dprintf(DBG_EVENT, "Control::cycleStopEvent: %u\n", cycleNumber);
ocycleCompleteNumber.setValue(cycleNumber);
ocycleProcessed++;
// Check all requests
for(orequestList.start(i); !orequestList.isEnd(i); ){
if(cycleNumber >= orequestList[i].dataInfo.cycleNumber){
oeventServers.dataEvent(orequestList[i].dataInfo);
orequestList.del(i);
}
else {
orequestList.next(i);
}
}
oeventServers.cycleStopEvent(cycleNumber);
if(osimulation.setNextCycle){
t1 = getTime();
err = setNextCycleInternal(ocycleNumberNext, ocycleTypeNext);
t2 = getTime();
dprintf(DBG_SETNEXTCYCLE, "Send setNextCycle: %u current: %u Time: %fms Error: %s\n", ocycleNumberNext, cycleNumber, (t2 - t1) * 1000.0, err.getString().retStr());
ocycleNumberNext++;
}
}
BError Control::getData(DataInfo dataInfo, Data& data){
BError err;
BError e;
PuChannel puPhysChannel(0, 0, 1);
BList<BError> errList;
BUInt32 chan;
BUInt32 orbitNumber;
dprintf(DBG_CMD, "Control::getData\n");
// Setup for error return
data.numValues = 0;
data.dataType = 0;
data.numBunches = 0;
data.numChannels = 0;
// Check parameters
if(dataInfo.channel > oconfigInfo.puReferences.size())
return err.set(ErrorParam, "dataInfo.channel parameter is incorrect");
if(dataInfo.cyclePeriod > CyclePeriodEvent9)
return err.set(ErrorParam, "dataInfo.cyclePeriod parameter is incorrect");
if(dataInfo.startTime > 4000)
return err.set(ErrorParam, "dataInfo.startTime parameter is to large (max: 4000)");
if(dataInfo.orbitNumber > 1500000)
return err.set(ErrorParam, "dataInfo.orbitNumber parameter is to large (max: 1500000)");
if(dataInfo.bunchNumber > 500000)
return err.set(ErrorParam, "dataInfo.bunchNumber parameter is to large");
if(dataInfo.numValues > (40 * 8 * 500000))
return err.set(ErrorParam, "dataInfo.numValues parameter is to large (max: 40 * 8 * 500000)");
if(err = waitForData(dataInfo.cycleNumber))
return err;
if(osimulate){
err = odataAquire.getData(dataInfo, data);
}
else {
if(dataInfo.channel){
data.errors.resize(1);
olock.lock();
puPhysChannel = oconfigInfo.puReferences[dataInfo.channel - 1];
olock.unlock();
opuServersLock.rdLock();
if(puPhysChannel.moduleNum > opuServers.number()){
opuServersLock.unlock();
data.errors[0] = err;
return err.set(ErrorMC, BString("Module: ") + puPhysChannel.moduleNum + " is not available");
}
err = opuServers[puPhysChannel.moduleNum - 1]->getData(puPhysChannel, dataInfo, data, orbitNumber);
// Check if there were any Cycle Errors
if(!err){
errList = ocycleInfoList.getCycleErrors(dataInfo.cycleNumber);
if(errList.number()){
err = errList.front();
}
}
if(err.getErrorNo() == ErrorDataGone)
onumDataGoneErrors++;
opuServersLock.unlock();
data.errors[0] = err;
}
else {
BUInt32 numValues = 0;
Data dataSet[oconfigInfo.puReferences.size()];
if(dataInfo.numValues < oconfigInfo.puReferences.size()){
return err.set(ErrorParam, "NumValues to small for request");
}
// Get the data from all PUPE channels. This could be improved with multi-threading and
// geting the data from separate module controllers at the same time to reduce system latency
dataInfo.numValues = dataInfo.numValues / oconfigInfo.puReferences.size();
data.errors.resize(oconfigInfo.puReferences.size());
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
e = BError();
olock.lock();
puPhysChannel = oconfigInfo.puReferences[chan];
olock.unlock();
opuServersLock.rdLock();
if(puPhysChannel.moduleNum > opuServers.number()){
e.set(ErrorMC, BString("Module: ") + puPhysChannel.moduleNum + " is not available");
}
else {
e = opuServers[puPhysChannel.moduleNum - 1]->getData(puPhysChannel, dataInfo, dataSet[chan], orbitNumber);
#if TIME_MS_USE_DATAGET
// If we have set a startTime, use the orbit number for all other channels
if(!e && dataInfo.startTime){
// syslog(LOG_ERR, "GetData: Get orbit number for channel: %d at startTime: %d orbitNumber: %d\n", chan, dataInfo.startTime, orbitNumber);
dataInfo.orbitNumber = orbitNumber;
dataInfo.startTime = 0;
}
#endif
}
data.errors[chan] = e;
if(e && !err)
err = e;
opuServersLock.unlock();
}
// Check if there were any Cycle Errors
if(!err){
errList = ocycleInfoList.getCycleErrors(dataInfo.cycleNumber);
if(errList.number()){
err = errList.front();
}
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
data.errors[chan] = err;
}
}
if(err.getErrorNo() == ErrorDataGone)
onumDataGoneErrors++;
// Now merge the data
// Calculate maximum number of values
numValues = 0;
data.dataType = 0;
data.numBunches = 0;
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
if(!data.errors[chan]){
data.dataType = dataSet[chan].dataType;
data.numBunches = dataSet[chan].numBunches;
if(dataSet[chan].dataValues.size() > numValues)
numValues = dataSet[chan].dataValues.size();
}
}
// Calculate minimum number of values
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
if(!data.errors[chan] && (dataSet[chan].dataValues.size() < numValues))
numValues = dataSet[chan].dataValues.size();
}
// Make sure numValues is a multiple of the number of bunches
if(data.numBunches)
numValues = data.numBunches * (numValues / data.numBunches);
data.numValues = numValues * oconfigInfo.puReferences.size();
data.numChannels = oconfigInfo.puReferences.size();
data.dataValues.resize(data.numValues);
memset(data.dataValues.data(), 0, data.dataValues.size() * sizeof(DataValue));
// Merge the data
for(chan = 0; chan < oconfigInfo.puReferences.size(); chan++){
if(!data.errors[chan])
memcpy(&data.dataValues[chan * numValues], &dataSet[chan].dataValues[0], numValues * sizeof(DataValue));
}
}
}
return err;
}
BError Control::addEventServer(BString name){
dprintf(DBG_CMD, "Control::addEventServer\n");
return oeventServers.append(name);
}
BError Control::requestData(DataInfo dataInfo){
BError err;
dprintf(DBG_CMD, "Control::requestData\n");
olock.lock();
orequestList.append(dataInfo);
olock.unlock();
return err;
}
BError Control::getSimCaptureData(TestCaptureInfo captureInfo, BArray<UInt64>& data){
BError err;
UInt32 num = 1024;
UInt32 i;
Data d;
Sample* samples;
SigGenBeam sigBeam;
UInt64 v, dds_freq, ds;
UInt64 fref, lo1, lo2, blr, gate;
UInt64 mean1, mean2, rfSelect1, rfSelect2, selFilter;
data.resize(num);
samples = new Sample[num];
sigBeam.config(125000000, 437000, 8, 0x3C, 0, 0, 1.0);
sigBeam.generate(samples, num);
for(i = 0; i < num; i++){
ds = UInt64(int(8191.0 * samples[i]) & 0x3FFF);
dds_freq = 300000000 + (i % 16);
lo1 = (i & 0x1) ? 1 : 0;
lo2 = (i & 0x2) ? 1 : 0;
blr = (i & 0x4) ? 1 : 0;
gate = (i & 0x8) ? 1 : 0;
fref = (i & 0x10) ? 1 : 0;
mean1 = (i & 0x20) ? 1 : 0;
mean2 = (i & 0x40) ? 1 : 0;
rfSelect1 = (i & 0x80) ? 1 : 0;
rfSelect2 = (i & 0x100) ? 1 : 0;
selFilter = (i & 0x200) ? 1 : 0;
v = (gate << 47) | (blr << 46) | (ds << 32) | dds_freq;
v |= (selFilter << 55) | (rfSelect2 << 54) | (rfSelect1 << 53) | (fref << 52);
v |= (mean2 << 51) | (mean1 << 50) | (lo2 << 49) | (lo1 << 48);
data[i] = v;
}
return err;
}
#ifdef ZAP
diagnostics(31 downto 0) <= dds_freq;
diagnostics(47 downto 32) <= GATE_pulse & BLR_pulse & sigma;
diagnostics(55 downto 48) <= sel_filter & rf_select2 & rf_select1 & frev_in & phase_table_data(7 downto 6) & LO_pulse2 & LO_pulse1;
diagnostics(63 downto 56) <= "0000" & switch_state;
#endif
BString Control::boapnsHost(){
return oboapnsHost;
}
uint32_t Control::diskSpace(BString dir){
struct statfs s;
uint32_t blocks = 0;
if(!statfs(dir, &s)){
blocks = ((uint64_t)s.f_bsize * s.f_bavail) / 1024;
}
return blocks;
}
uint32_t Control::memoryFree(){
BEntryFile file("/proc/meminfo");
uint32_t mbytes = 0;
BString s;
if(!file.read()){
mbytes = file.findValue("MemFree:").retInt() / 1024;
mbytes += file.findValue("Buffers:").retInt() / 1024;
mbytes += file.findValue("Cached:").retInt() / 1024;
}
return mbytes;
}