Skip to content
Snippets Groups Projects
Commit c7a1fa04 authored by Douglas Araujo's avatar Douglas Araujo
Browse files

Add VMM COnfig class, with configVMM method

parent 3e432540
No related branches found
No related tags found
1 merge request!1ICSHWI-14275: Create VMM FEN Epics module
......@@ -56,7 +56,7 @@ void VMM3a::LoadDefault() {
"stlc", "sbip", "srat", "sfrst", "slvsbc",
"slvstp", "slvstk", "slvsdt", "slvsart", "slvstki",
"slvsena", "slvs6b", "sL0enaV", "slh", "slxh",
"stgc", "reset1", "reset2" "nskipm_i", "sL0cktest",
"stgc", "reset1", "reset2", "nskipm_i", "sL0cktest",
"sL0dckinv", "sL0ckinv", "sL0ena", "truncate_i",
"nskip_i", "window_i", "rollover_i", "L0offset_i", "offset_i"
};
......@@ -108,7 +108,7 @@ vmmStatus VMM3a::setRegister(std::string feature, int val, int ch) {
return status;
}
vmmStatus VMM3a::getRegister(std::string feature, int val, unsigned short& result) {
vmmStatus VMM3a::getRegister(std::string feature, unsigned short& result) {
vmmStatus status = vmmSuccess;
if(vmm3aSettings->globalRegisters.find(feature)!=vmm3aSettings->globalRegisters.end())
result = vmm3aSettings->globalRegisters.at(feature);
......@@ -117,7 +117,7 @@ vmmStatus VMM3a::getRegister(std::string feature, int val, unsigned short& resul
return status;
}
vmmStatus VMM3a::getRegister(std::string feature, int val, int ch, unsigned short& result) {
vmmStatus VMM3a::getRegister(std::string feature, int ch, unsigned short& result) {
vmmStatus status = vmmSuccess;
if (ch >= 0 && ch < 64) {
auto it = vmm3aSettings->channels[ch].find(feature);
......@@ -147,7 +147,7 @@ vmmStatus VMM3a::updateRegisterMap(std::string feature, int 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;
vmm3aSettings->globalRegisters.at("sm5_sm0") = value - 63;
} else status = vmmBadValue;
}
else {
......
......@@ -23,8 +23,8 @@ public:
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, int val, unsigned short& result);
vmmStatus getRegister(std::string feature, int val, int ch, unsigned short& result);
vmmStatus getRegister(std::string feature, unsigned short& result);
vmmStatus getRegister(std::string feature, int ch, unsigned short& result);
vmmStatus getInfo(const std::string& feature, std::string& result);
vmmStatus setInfo(const std::string& feature, const std::string& value);
......
#include "vmm_config.h"
#include <sstream>
#include <bitset>
#include <algorithm>
#include "FrontEndBase.h"
FENConfigModule::FENConfigModule(FrontEndBase& frontend) : pVMM3a(), pFEN(&frontend) {
// Retrieve the VMMSettings from the VMM instance
const auto& vmm3a_settings = pVMM3a.getVMM3aSettings();
// Access the globalRegisters member and print its contents
for (const auto& entry : vmm3a_settings.globalRegisters) {
std::cout << "Key: " << entry.first << ", Value: " << entry.second << std::endl;
}
}
FENConfigModule::~FENConfigModule() {
}
bool FENConfigModule::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 firstChRegSPI = 3;
unsigned int lastChRegSPI = 66;
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);
std::cout << "Param: " << param << " - Value: " << value << std::endl;
pFEN->user_reg_write(param, value);
}
//channel SPI
for(unsigned int i = firstChRegSPI; i <= lastChRegSPI; i++) {
std::string param = "vmm_ch" + std::to_string(i - firstChRegSPI);
param += sVmmIndex;
param += std::string(2 - std::to_string(i - firstChRegSPI).length(), '0'); // Right justify with '0'
uint32_t value = std::stoul(channelRegisters[i - firstChRegSPI], nullptr, 2);
std::cout << "Param: " << param << " - Value: " << value << std::endl;
pFEN->user_reg_write(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);
std::cout << "Param: " << param << " - Value: " << value << std::endl;
pFEN->user_reg_write(param, value);
}
uint32_t value = (1 << idx);
pFEN->user_reg_write("sc_cfg_vmm", 0x00000000);
pFEN->user_reg_write("sc_cfg_vmm", value);
pFEN->user_reg_write("sc_cfg_vmm", 0x00000000);
return result;
}
void FENConfigModule::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'
pVMM3a.getRegister(settingName, result);
std::cout << "Setting Name: " << settingName << " Result: " << result << std::endl;
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) {
pVMM3a.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) {
pVMM3a.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 FENConfigModule::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) {
pVMM3a.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 FENConfigModule::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]
pVMM3a.getRegister("nskipm_i", result);
spi0.replace(sequence, 1, std::to_string(result));
global.push_back(spi0);
// GLOBAL SPI 1
std::string spi1 = "00000000000000000000000000000000";
pVMM3a.getRegister("sL0cktest", result);
// clocks when L0 core disabled [0]
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//invert DCK [1]
pVMM3a.getRegister("sL0dckinv", result);
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//invert BCCLK [2]
pVMM3a.getRegister("sL0ckinv", result);
spi1.replace(sequence, 1, std::to_string(result));
sequence++;
//L0 core
pVMM3a.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);
}
#pragma once
#include <vector>
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <iostream>
#include "vmm3a.h"
class FrontEndBase;
class FENConfigModule {
public:
FENConfigModule(FrontEndBase& frontend);
~FENConfigModule();
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);
private:
VMM3a pVMM3a;
FrontEndBase *pFEN;
};
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