Skip to content
Snippets Groups Projects
Commit ef5d3b97 authored by Marco Filho's avatar Marco Filho
Browse files

Remove all files that should be on API

parent d1df55d9
2 merge requests!7Major refactor,!6Take API out of EPICS module
......@@ -11,11 +11,7 @@ TMPS += $(APPDB)/hybrid.template
TMPS += $(APPDB)/vmm_tbl.template
SUBS = $(APPDB)/channels.sub
SOURCES += $(APPSRC)/hybrid.cpp
SOURCES += $(APPSRC)/vmm3a.cpp
SOURCES += $(APPSRC)/VmmTblAPI.cpp
SOURCES += $(APPSRC)/vmm_tbl.cpp
SOURCES += $(APPSRC)/VmmTblRegsMap.cpp
DBDS += $(APPSRC)/vmm_tbl.dbd
......
#include "VmmTblAPI.h"
#include <sstream>
#include <bitset>
#include <algorithm>
#include <chrono>
#include <thread>
#include <array>
#include "FrontEndBase.h"
void delayMilliseconds(int milliseconds) {
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}
VmmTblAPI::VmmTblAPI(RMMAPI* rmmApi, int ring, int node, std::string name)
: FrontEndBase(rmmApi, ring, node, name)
{
}
VmmTblAPI::~VmmTblAPI() {
}
void VmmTblAPI::acquire(bool acquire) {
if (acquire) {
enableAcquisition(false);
sendAll(true);
enableAcquisition(true);
} else {
enableAcquisition(false);
}
}
void VmmTblAPI::sendAll(bool useConfigCheck) {
configFE();
for(int hybrid = 0; hybrid <= HYBRIDS_PER_FEN; hybrid++) {
if (isHybridEnabled(hybrid)) {
configHybrid(hybrid);
for(int vmm = 0; vmm < VMMS_PER_HYBRID; vmm++) {
configVMM(hybrid, vmm, useConfigCheck);
}
}
}
}
void VmmTblAPI::enableAcquisition(bool enabled) {
userRegWrite("app_acq_enable", enabled);
userRegWrite("sc_acq_on_off", 0x00000000);
userRegWrite("sc_acq_on_off", 0x00000001);
userRegWrite("sc_acq_on_off", 0x00000000);
}
std::string VmmTblAPI::checkLinkStatus(int hyb) {
uint32_t result = readWriteRegs("sc_app_link_status", 0, "app_link_status");
int pos = 7 - hyb;
return intToHexString(result).substr(pos, 1);
}
void VmmTblAPI::configFE() {
userRegWrite("app_debug_data_format", 0);
userRegWrite("app_latency_reset", 27);
userRegWrite("app_latency_data_max", 1024);
userRegWrite("app_latency_data_jitter", 0);
userRegWrite("app_tp_offset_first", 100);
userRegWrite("app_tp_offset", 1000);
userRegWrite("app_tp_latency", 46);
userRegWrite("app_tp_number", 1);
userRegWrite("app_chmask", getChMap());
userRegWrite("sc_cfg_app", 0x00000000);
userRegWrite("sc_cfg_app", 0x00000001);
userRegWrite("sc_cfg_app", 0x00000000);
}
uint16_t VmmTblAPI::getChMap() {
std::string chMapString = "0000000000000000";
for (int hybrid = 0; hybrid < HYBRIDS_PER_FEN; hybrid++) {
if (isHybridEnabled(hybrid)) {
for (int vmm = 0; vmm < VMMS_PER_HYBRID; vmm++) {
chMapString.replace(15 - (hybrid * 2 + vmm), 1, "1");
}
}
}
uint16_t chMap = std::stoi(chMapString, nullptr, 2);
return chMap;
}
bool VmmTblAPI::enableHybrid(int hybrid, bool onOff) {
if(hybrid < HYBRIDS_PER_FEN) {
enabled_hybrids[hybrid] = onOff;
return true;
} else return false;
}
bool VmmTblAPI::isHybridEnabled(int hybrid) {
if(hybrid < HYBRIDS_PER_FEN) return enabled_hybrids[hybrid];
else return false;
}
Hybrid& VmmTblAPI::getHybrid(int index) {
if (index < 0 || index >= HYBRIDS_PER_FEN)
throw std::out_of_range("Invalid hybrid index");
return hybrids[index];
}
void VmmTblAPI::configHybrid(int hybrid_index) {
std::array<std::string, 3> registers = {"hyb_tp_skew0", "hyb_tp_width0", "hyb_tp_polarity0"};
for (const auto& reg : registers) {
unsigned short result = 0;
hybrids[hybrid_index].getRegister(reg, result);
userRegWrite(reg + std::to_string(hybrid_index), result);
}
uint32_t value = (1 << hybrid_index);
userRegWrite("sc_cfg_hyb", 0x0);
userRegWrite("sc_cfg_hyb", value);
userRegWrite("sc_cfg_hyb", 0x0);
}
std::string VmmTblAPI::readFwVersion(int hyb) {
uint32_t result = readWriteRegs("sc_i2c_firmware_version",
hyb,
"hyb_i2c_firmware_version0" + std::to_string(hyb));
return intToHexString(result);
}
std::string VmmTblAPI::readGeoPos(int hyb) {
uint32_t result = readWriteRegs("sc_i2c_geo_id", hyb, "hyb_i2c_geoid0" + std::to_string(hyb));
return intToHexString(result).substr(6);
}
std::string VmmTblAPI::readIDChip(int hyb) {
std::string full_string;
uint32_t result = 0;
result = readWriteRegs("sc_i2c_hybrid_id", hyb, "hyb_i2c_hybrid_id00" + std::to_string(hyb));
full_string += intToHexString(result);
result = readWriteRegs("sc_i2c_hybrid_id", hyb, "hyb_i2c_hybrid_id10" + std::to_string(hyb));
full_string += intToHexString(result);
result = readWriteRegs("sc_i2c_hybrid_id", hyb, "hyb_i2c_hybrid_id20" + std::to_string(hyb));
full_string += intToHexString(result);
result = readWriteRegs("sc_i2c_hybrid_id", hyb, "hyb_i2c_hybrid_id30" + std::to_string(hyb));
full_string += intToHexString(result);
return full_string;
}
bool VmmTblAPI::configVMM(int hybrid_index, int vmm_index, bool enableConfigCheck)
{
bool result = true;
bool ok;
std::vector<std::string> globalRegisters;
globalRegisters.clear();
fillGlobalRegisters(globalRegisters, hybrid_index, vmm_index);
std::cout << "Global Registers:" << std::endl;
for (const auto& reg : globalRegisters) {
std::cout << reg << std::endl;
}
if(globalRegisters.size()!=3){
std::cout << "ERROR Global SPI does not have 3 words" << std::endl;
return -1;
}
std::vector<std::string> channelRegisters;
channelRegisters.clear();
fillChRegisters(channelRegisters, hybrid_index, vmm_index);
if(channelRegisters.size() != 64){
std::cout << "ERROR Channel registers do not have 64 values" << std::endl;
return -1;
}
std::vector<std::string> globalRegisters2;
globalRegisters2.clear();
fillGlobalRegisters2(globalRegisters2, hybrid_index, vmm_index);
if(globalRegisters2.size()!=3){
std::cout << "ERROR Global SPI does not have 3 words" << std::endl;
return -1;
}
int idx = hybrid_index * 2 + vmm_index;
std::string sVmmIndex = "99";
if(idx < 10) sVmmIndex = "0" + std::to_string(idx);
else if(idx < 16) sVmmIndex = std::to_string(idx);
bool g_use_config_check = true;
if(g_use_config_check) {
//reset I2C address 65 register 0
if(enableConfigCheck) {
// TODO: Check with we need that (the enableConfigCheck is always false in the VMM code)
//uint32_t value = (1 << hybrid_index);
//ESS_WriteSc("sc_i2c_reset_config_check", 0x00000000, ok);
//ESS_WriteSc("sc_i2c_reset_config_check", value, ok);
//ESS_WriteSc("sc_i2c_reset_config_check", 0x00000000, ok);
}
}
unsigned int firstGlobalRegSPI_2 = 0;
unsigned int lastGlobalRegSPI_2 = 2;
unsigned int firstGlobalRegSPI_1 = 67;
unsigned int lastGlobalRegSPI_1 = 69;
// global SPI / VMM3: global bank 0
for(unsigned int i = firstGlobalRegSPI_2; i <= lastGlobalRegSPI_2; i++) {
std::string param = "vmm_global_bank2_sp" + std::to_string(i - firstGlobalRegSPI_2) + sVmmIndex;
uint32_t value = std::stoul(globalRegisters2[i - firstGlobalRegSPI_2], nullptr, 2);
userRegWrite(param, value);
}
//channel SPI
for(unsigned int i = 0; i < CHANNELS_PER_VMM; i++) {
std::string position_str = std::to_string(i);
if (position_str.size() == 1) position_str = "0" + position_str;
std::string param = "vmm_ch" + position_str + sVmmIndex;
uint32_t value = std::stoul(channelRegisters[i], nullptr, 2);
std::cout << "param: " << param << std::endl;
userRegWrite(param, value);
}
// global SPI / VMM3: global bank 1
for(unsigned int i = firstGlobalRegSPI_1; i <= lastGlobalRegSPI_1; i++) {
std::string param = "vmm_global_bank1_sp" + std::to_string(i - firstGlobalRegSPI_1) + sVmmIndex;
uint32_t value = std::stoul(globalRegisters[i - firstGlobalRegSPI_1], nullptr, 2);
userRegWrite(param, value);
}
uint32_t value = (1 << idx);
userRegWrite("sc_cfg_vmm", 0x00000000);
userRegWrite("sc_cfg_vmm", value);
userRegWrite("sc_cfg_vmm", 0x00000000);
return result;
}
void VmmTblAPI::fillGlobalRegisters(std::vector<std::string>& global, int hybrid_index, int vmm_index)
{
unsigned short result;
global.clear();
int sequence = 0;
// GLOBAL SPI 0
std::string spi0 = "00000000000000000000000000000000";
//[0,3] reserved
sequence += 4;
// Function to replace a bit in the spi0 string with a value from VMM settings
auto replaceVMMBit = [&](int index, const std::string& settingName) {
// Convert value to '1' if it's not zero, otherwise '0'
hybrids[hybrid_index].getVMM(vmm_index).getRegister(settingName, result);
spi0[index] = '0' + (result != 0);
};
const std::vector<std::string> settings = {"slvs", "s32", "stcr", "ssart", "srec", "stlc", "sbip", "srat", "sfrst",
"slvsbc", "slvstp", "slvstk", "slvsdt", "slvsart", "slvstki", "slvsena",
"slvs6b", "slh", "slxh", "stgc", "reset1", "reset2"};
for (const auto& setting : settings) {
if (setting == "reset1") sequence += 5; //[25,29] not used
replaceVMMBit(sequence, setting);
sequence++;
}
global.push_back(spi0);
// GLOBAL SPI 1
// Define a function to populate spi string based on VMM settings
auto populateSPI1 = [&](const std::vector<std::pair<std::string, int>>& settings) {
std::string spi;
int sequence = 0;
for (const auto& setting : settings) {
hybrids[hybrid_index].getVMM(vmm_index).getRegister(setting.first, result);
std::string binary_string = std::bitset<16>(result).to_string().substr(16 - setting.second);
if (setting.first == "sdt") {
// Populate threshold DAC lowest 6 bits
for (int i = 4; i < 10; ++i) spi += binary_string[i];
} else spi += binary_string;
sequence += setting.second;
}
// Append '0' to the end of spi to reserve the last bit: [31] reserved
spi += '0';
// Push back the populated spi string to the global vector
global.push_back(spi);
};
// Populate SPI 1 settings
populateSPI1({{"sdt", 10},{"sdp10", 10}, {"sc10b", 2}, {"sc8b", 2},
{"sc6b", 3}, {"s8b", 1}, {"s6b", 1}, {"s10b", 1},
{"sdcks", 1}, {"sdcka", 1}, {"sdck6b", 1}, {"sdrv", 1},
{"stpp", 1}});
// GLOBAL SPI 2
// Define a function to populate spi string based on VMM settings
auto populateSPI2 = [&](const std::vector<std::pair<std::string, int>>& settings) {
std::string spi;
int sequence = 0;
for (const auto& setting : settings) {
hybrids[hybrid_index].getVMM(vmm_index).getRegister(setting.first, result);
std::string binary_string = std::bitset<16>(result).to_string().substr(16 - setting.second);
if (setting.first == "sdt") {
// Populate threshold DAC highest 4 bits
for (int i = 0; i < 4; ++i) {
spi += binary_string[i];
sequence++;
}
} else {
spi += binary_string;
sequence += setting.second;
}
}
// Push back the populated spi string to the global vector
global.push_back(spi);
};
// Populate SPI 2 settings
populateSPI2({{"sp", 1}, {"sdp", 1}, {"sbmx", 1}, {"sbft", 1}, {"sbfp", 1},
{"sbfm", 1}, {"slg", 1}, {"sm5_sm0", 6}, {"scmx", 1}, {"sfa", 1},
{"sfam", 1}, {"st", 2}, {"sfm", 1}, {"sg", 3}, {"sng", 1}, {"stot", 1},
{"sttt", 1}, {"ssh", 1}, {"stc", 2}, {"sdt", 10}});
}
void VmmTblAPI::fillChRegisters(std::vector<std::string>& registers, int hybrid_index, int vmm_index)
{
registers.clear();
unsigned short result;
auto populateRegisters = [&](const std::vector<std::pair<std::string, int>>& regs, int channel) {
std::string _reg = "00000000";
int sequence = 8;
for (const auto& reg : regs) {
hybrids[hybrid_index].getVMM(vmm_index).getRegister(reg.first, channel, result);
std::string binary_string = std::bitset<16>(result).to_string().substr(16 - reg.second);
if (reg.first == "sd" || reg.first == "sz10b" ||
reg.first == "sz08b" || reg.first == "sz06b") {
//According to ATLAS software, has to be reversed
std::reverse(binary_string.begin(), binary_string.end());
}
_reg += binary_string;
sequence += reg.second;
}
// Append '0' to the end of spi to reserve the last bit: [31] reserved
_reg += "0";
// Push back the populated _reg string to the registers vector
registers.push_back(_reg);
};
std::vector<std::pair<std::string, int>> registers_map = {{"sc", 1}, {"sl", 1}, {"st", 1},
{"sth", 1}, {"sm", 1}, {"smx", 1},
{"sd", 5}, {"sz10b", 5}, {"sz08b", 4},
{"sz06b", 3}};
for(int ch = 0; ch < CHANNELS_PER_VMM; ch++) {
populateRegisters(registers_map, ch);
}
}
void VmmTblAPI::fillGlobalRegisters2(std::vector<std::string>& global, int hybrid_index, int vmm_index)
{
unsigned short result;
int sequence = 0;
// GLOBAL SPI 0
std::string spi0 = "00000000000000000000000000000000";
//[0,30] not used
sequence+=31;
// magic number on BCID [31]
hybrids[hybrid_index].getVMM(vmm_index).getRegister("nskipm_i", result);
spi0.replace(sequence, 1, std::to_string(result));
global.push_back(spi0);
// GLOBAL SPI 1
std::string spi1 = "00000000000000000000000000000000";
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sL0cktest", result);
// clocks when L0 core disabled [0]
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//invert DCK [1]
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sL0dckinv", result);
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//invert BCCLK [2]
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sL0ckinv", result);
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//L0 core
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sL0ena", result);
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
global.push_back(spi1);
// GLOBAL SPI 2
std::string spi2 = "00000000000000000000000000000000";
global.push_back(spi2);
}
int VmmTblAPI::readADC(int hybrid_index, int vmm_index) {
int adc_result = 0;
int vmm = hybrid_index * 2 + vmm_index;
std::string sVmmIndex = "99";
if(vmm < 10) sVmmIndex = "0" + std::to_string(vmm);
else if(vmm < 16) sVmmIndex = std::to_string(vmm);
uint32_t result = readWriteRegs("sc_i2c_vmm_adc", vmm, "vmm_i2c_adc" + sVmmIndex);
adc_result = (result & 0xFFFF) >> 4; // bit shift
unsigned short sp_value = 0;
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sp", sp_value);
unsigned sm5_sm0_value = 0;
hybrids[hybrid_index].getVMM(vmm_index).getRegister("sm5_sm0", sp_value);
if((sp_value != 0) && (sm5_sm0_value == 1)) adc_result = 1200 - adc_result;
return adc_result;
}
uint32_t VmmTblAPI::readWriteRegs(std::string command_reg, int index, std::string read_reg) {
unsigned int data = 0x00000000;
userRegWrite(command_reg, data);
data = (1 << index);
userRegWrite(command_reg, data);
//Do not read registers back too soon, otherwise old ADC value is read
delayMilliseconds(7);
uint32_t value = userRegRead(read_reg);
userRegWrite(command_reg, 0x0);
return value;
}
#pragma once
#include <vector>
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <iostream>
#include "FrontEndBase.h"
#include "FrontEndFactory.h"
#include "VmmTblRegsMap.h"
#include "hybrid.h"
class VmmTblAPI : public FrontEndBase {
public:
VmmTblAPI(RMMAPI* rmmApi, int ring, int node, std::string name);
~VmmTblAPI();
void configHybrid(int hybrid_index);
bool configVMM(int hybrid_index, int vmm_index, bool enableConfigCheck=false);
void fillGlobalRegisters(std::vector<std::string>& global, int hybrid_index, int vmm_index);
void fillGlobalRegisters2(std::vector<std::string>& global, int hybrid_index, int vmm_index);
void fillChRegisters(std::vector<std::string>& registers, int hybrid_index, int vmm_index);
int readADC(int hybrid_index, int vmm_index);
Hybrid& getHybrid(int index);
bool enableHybrid(int hybrid, bool onOff);
bool isHybridEnabled(int hybrid);
void acquire(bool acquire);
std::string readFwVersion(int hyb);
std::string readIDChip(int hyb);
std::string readGeoPos(int hyb);
std::string checkLinkStatus(int hyb);
void configFE();
private:
Hybrid hybrids[HYBRIDS_PER_FEN];
bool enabled_hybrids[HYBRIDS_PER_FEN] = {};
uint32_t readWriteRegs(std::string command_reg, int index, std::string read_reg);
uint16_t getChMap();
void sendAll(bool useConfigCheck);
void enableAcquisition(bool enabled);
uint8_t linkStatus[HYBRIDS_PER_FEN];
};
This diff is collapsed.
#pragma once
#include <unordered_map>
#include <string>
extern const std::unordered_map<std::string, uint32_t> vmm_tbl_register_map;
\ No newline at end of file
#include "hybrid.h"
Hybrid::Hybrid() {
loadDefault();
}
Hybrid::~Hybrid() {}
void Hybrid::loadDefault(){
hybrid_registers = {{"TP_skew", 0}, {"TP_width", 0}, {"TP_pol", 0}};
hybrid_info = {{"firmware_version", ""}, {"geo_id", ""}, {"hybrid_id", ""},{"link_status", "0"}, {"description", ""}};
}
VMM3a& Hybrid::getVMM(int index) {
if (index < 0 || index >= VMMS_PER_HYBRID)
throw std::out_of_range("Invalid VMM index");
return vmms[index];
}
vmmStatus Hybrid::getRegister(std::string feature, unsigned short& result) {
vmmStatus status = vmmSuccess;
if(hybrid_registers.find(feature) != hybrid_registers.end())
result = hybrid_registers[feature];
else
status = vmmParamNotFound;
return status;
}
#pragma once
#include <string>
#include <map>
#include <iostream>
#include "vmm_params.h"
#include "vmm3a.h"
class Hybrid {
public:
Hybrid();
~Hybrid();
void loadDefault();
VMM3a& getVMM(int index);
vmmStatus getRegister(std::string feature, unsigned short& result);
private:
VMM3a vmms[VMMS_PER_HYBRID];
std::map<std::string, unsigned short> hybrid_registers;
std::map<std::string, std::string> hybrid_info;
};
#include "vmm3a.h"
// Define a map to store the valid range for each feature
std::map<std::string, std::pair<int, int>> featureRanges = {
{"sm5_sm0", {0, 67}},
{"sfam", {0, 1}},
{"st", {0, 3}},
{"sg", {0, 7}},
{"stc", {0, 3}},
{"sdt", {0, 1023}},
{"sdp10", {0, 1023}},
{"sc10b", {0, 3}},
{"sc8b", {0, 3}},
{"truncate_i", {0, 63}},
{"nskip_i", {0, 127}},
{"window_i", {0, 7}},
{"rollover_i", {0, 4095}},
{"L0offset_i", {0, 4095}},
{"offset_i", {0, 4095}}
};
std::map<std::string, std::pair<int, int>> featureChannelRanges = {
{"sd", {0, 31}},
{"sz10b", {0, 31}},
{"sz08b", {0, 15}},
{"sz06b", {0, 7}},
{"sc", {0, 1}},
{"sl", {0, 1}},
{"st", {0, 1}},
{"sth", {0, 1}},
{"sc8b", {0, 3}},
{"sm", {0, 1}},
{"smx", {0, 1}}
};
VMM3a::VMM3a(): vmm3aSettings(std::make_unique<VMM3aSettings>()) {
LoadDefault();
}
void VMM3a::LoadDefault() {
//VMM3a channel registers
for(int ch=0; ch<CHANNELS_PER_VMM; ch++){
vmm3aSettings->channels[ch] = {{"sc", 0}, {"sl", 0}, {"st", 0}, {"sth", 0}, {"sm", 0}, {"sd", 0}, {"smx", 0}, {"sz10b", 0}, {"sz08b", 0}, {"sz06b", 0} };
}
//Fill default values to map for Global Register
std::vector<std::string> reg_names = {
"sp", "sdp", "sbmx", "sbft", "sbfp",
"sbfm", "slg", "sm5_sm0", "scmx", "sfa",
"sfam", "st", "sfm", "sg", "sng",
"stot", "sttt", "ssh", "stc",
"sdt", "sdp10", "sc10b", "sc8b", "sc6b",
"s8b", "s6b", "s10b", "sdcks", "sdcka",
"sdck6b", "sdrv", "stpp",
"slvs", "s32", "stcr", "ssart", "srec",
"stlc", "sbip", "srat", "sfrst", "slvsbc",
"slvstp", "slvstk", "slvsdt", "slvsart", "slvstki",
"slvsena", "slvs6b", "sL0enaV", "slh", "slxh",
"stgc", "reset1", "reset2", "nskipm_i", "sL0cktest",
"sL0dckinv", "sL0ckinv", "sL0ena", "truncate_i",
"nskip_i", "window_i", "rollover_i", "L0offset_i", "offset_i"
};
for(const std::string& reg: reg_names) {
vmm3aSettings->globalRegisters.insert(std::pair<std::string, unsigned short>(reg, 0));
}
setRegister("sg", 2);//corrsponds to 3 mV/fC
setRegister("sm5_sm0", 67); //Temperature_sensor
setRegister("sdp10", 300);
setRegister("sdt",300);
setRegister("s10b",1);
setRegister("s8b",1);
setRegister("stc",0);
setRegister("sc8b",3);
setRegister("sc10b",3);
setRegister("srat",0);
setRegister("sbip",true);
setRegister("sbfm",true);
setRegister("sdcks",false);
}
const VMM3a::VMM3aSettings& VMM3a::getVMM3aSettings() const {
return *vmm3aSettings;
}
vmmStatus VMM3a::setRegister(std::string feature, int val) {
vmmStatus status = vmmSuccess;
status = updateRegisterMap(feature, val);
if (status == vmmParamNotFound)
std::cout << "ERROR register " << feature << " does not exist." << std::endl;
else if (status == vmmBadValue)
std::cout << "Value " << val << " is not valid to register: " << feature << std::endl;
return status;
}
vmmStatus VMM3a::setRegister(std::string feature, int val, int ch) {
vmmStatus status = vmmSuccess;
status = updateRegisterMap(feature, val, ch);
if (status == vmmParamNotFound)
std::cout << "ERROR register " << feature << " does not exist." << std::endl;
else if (status == vmmBadValue)
std::cout << "Value " << val << " is not valid to register: " << feature << std::endl;
else if (status == vmmChannelOutRange)
std::cout << "Channel " << ch << " out of the range (0 - 63)" << std::endl;
return status;
}
vmmStatus VMM3a::getRegister(std::string feature, unsigned short& result) const {
vmmStatus status = vmmSuccess;
if(vmm3aSettings->globalRegisters.find(feature)!=vmm3aSettings->globalRegisters.end())
result = vmm3aSettings->globalRegisters.at(feature);
else
status = vmmParamNotFound;
return status;
}
vmmStatus VMM3a::getRegister(std::string feature, int ch, unsigned short& result) const {
vmmStatus status = vmmSuccess;
if (ch >= 0 && ch < 64) {
auto it = vmm3aSettings->channels[ch].find(feature);
if (it != vmm3aSettings->channels[ch].end())
result = it->second;
else
status = vmmParamNotFound;
}
else status = vmmChannelOutRange;
return status;
}
vmmStatus VMM3a::updateRegisterMap(std::string feature, int value) {
vmmStatus status = vmmSuccess;
auto it = vmm3aSettings->globalRegisters.find(feature);
if (it != vmm3aSettings->globalRegisters.end()) {
auto range = featureRanges.find(feature);
if (range != featureRanges.end()) {
int minVal = range->second.first;
int maxVal = range->second.second;
if (feature == "sm5_sm0") {
if(value >= 0 && value <= 63) {
vmm3aSettings->globalRegisters.at("scmx") = 1;
vmm3aSettings->globalRegisters.at("sm5_sm0") = value;
} else if (value >= 64 && value <= 67) {
//Attention: Starts at 1: 1=Pulser_DAC, 2=Threshold_DAC, 3=Bandgap_reference, 4=Temperature_sensor
vmm3aSettings->globalRegisters.at("scmx") = 0;
vmm3aSettings->globalRegisters.at("sm5_sm0") = value - 63;
} else status = vmmBadValue;
}
else {
if (value >= minVal && value <= maxVal)
vmm3aSettings->globalRegisters.at(feature) = value;
else status = vmmBadValue;
}
}
// If not in the featureRanges, the param expects boolean value.
else {
if(value >= 0 && value <= 1)
vmm3aSettings->globalRegisters.at(feature) = value;
else status = vmmBadValue;
}
}
else { status = vmmParamNotFound; }
return status;
}
vmmStatus VMM3a::updateRegisterMap(std::string feature, int value, int ch) {
vmmStatus status = vmmSuccess;
if(ch >= 0 && ch < 64) {
auto range = featureChannelRanges.find(feature);
if (range != featureChannelRanges.end()) {
int minVal = range->second.first;
int maxVal = range->second.second;
if (value >= minVal && value <= maxVal)
vmm3aSettings->channels[ch][feature] = value;
else status = vmmBadValue;
}
else status = vmmParamNotFound;
}
else status = vmmChannelOutRange;
return status;
}
vmmStatus VMM3a::getInfo(const std::string& feature, std::string& result) {
vmmStatus status = vmmSuccess;
if (vmmInfo.find(feature) != vmmInfo.end())
result = vmmInfo[feature];
else
status = vmmParamNotFound;
return status;
}
vmmStatus VMM3a::setInfo(const std::string& feature, const std::string& value) {
vmmStatus status = vmmSuccess;
if (vmmInfo.find(feature) != vmmInfo.end())
vmmInfo[feature] = value;
else
status = vmmParamNotFound;
return status;
}
VMM3a::~VMM3a(){}
#pragma once
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <iostream>
#include "vmm_params.h"
class VMM3a {
public:
VMM3a();
~VMM3a();
void LoadDefault();
struct VMM3aSettings{
std::map<std::string, unsigned short> channels[CHANNELS_PER_VMM];
std::map<std::string, unsigned short> globalRegisters;
};
const VMM3aSettings& getVMM3aSettings() const;
vmmStatus setRegister(std::string feature, int val);
vmmStatus setRegister(std::string feature, int val, int ch);
vmmStatus getRegister(std::string feature, unsigned short& result) const;
vmmStatus getRegister(std::string feature, int ch, unsigned short& result) const;
vmmStatus getInfo(const std::string& feature, std::string& result);
vmmStatus setInfo(const std::string& feature, const std::string& value);
private:
vmmStatus updateRegisterMap(std::string feature, int value);
vmmStatus updateRegisterMap(std::string feature, int value, int ch);
std::unique_ptr<VMM3aSettings> vmm3aSettings;
std::map<std::string, std::string> vmmInfo = {{"all_sc", "0"}, {"all_sl", "0"}, {"all_st", "0"}, {"all_sth", "0"},{"all_sm", "0"}, {"all_sd", "0"},{"all_smx", "0"},
{"all_sz10b", "0"},{"all_sz08b", "0"}, {"all_sz06b", "0"},{"adc_value", ""}, {"description",""}};
};
\ No newline at end of file
#pragma once
#define CHANNELS_PER_VMM 64
#define VMMS_PER_HYBRID 2
#define HYBRIDS_PER_FEN 5
typedef enum {
vmmSuccess,vmmTimeout,vmmParamNotFound,vmmBadValue,vmmChannelOutRange
}vmmStatus;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment