.. _program_listing_file_device.cpp: Program Listing for File device.cpp =================================== |exhale_lsh| :ref:`Return to documentation for file ` (``device.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include #include "device.hpp" #include "log.hpp" #define BROADCAST_NONE 0 #define BROADCAST_ALL 1 #define BROADCAST_CHANNEL 2 #define BROADCAST_ELINK 3 #define MAX_BROADCAST_CHANNELS (32) #define MAX_BROADCAST_ELINKS (1 + 32 + 64) Device::Device(unsigned dev_no, uint8_t vid, uint16_t did, uint16_t cid) : m_device_number(dev_no), m_vid(vid), m_did(did), m_cid(cid) {} bool Device::has_wrong_rm() { unsigned int regmap = get_regmap_version(); #if REGMAP_VERSION < 0x0500 return ((regmap < 0x0400) || (regmap >= 0x0500)); #else return ((regmap < 0x0500) || (regmap >= 0x0600)); #endif } bool Device::is_full_mode() { return (m_firmware_type == FIRMW_FULL or m_firmware_type == FIRMW_MROD or m_firmware_type == FIRMW_INTERLAKEN); } bool Device::is_lpgbt_mode() { u_int mode = m_firmware_type; return (mode == FIRMW_PIXEL or mode == FIRMW_STRIP or mode == FIRMW_LPGBT or mode == FIRMW_HGTD_LUMI or mode == FIRMW_BCM_PRIME); } uint64_t Device::get_elink(u_int channel, u_int egroup, u_int epath) { bool lpgbt = this->is_lpgbt_mode(); int egroup_shift = (lpgbt) ? 2 : 3; return (channel << 6) + (egroup << egroup_shift) + epath; } uint32_t Device::get_channel(uint32_t elink) { return (elink >> 6); } uint32_t Device::get_egroup(uint32_t elink) { bool lpgbt = this->is_lpgbt_mode(); int egroup_shift = (lpgbt) ? 2 : 3; return (elink & 0x3f) >> egroup_shift; } uint32_t Device::get_epath(uint32_t elink) { bool lpgbt = this->is_lpgbt_mode(); int egroup_shift = (lpgbt) ? 2 : 3; return egroup_shift == 2 ? elink & 0x03 : elink & 0x07; } u_int Device::get_egroups_per_channel(u_int is_to_flx) { u_int egroups_per_chan; if( is_to_flx == 0 ) { // tohost if( this->is_full_mode() ) egroups_per_chan = 1; else if( this->is_lpgbt_mode() ) egroups_per_chan = 7; else if( this->get_wide_mode() ) egroups_per_chan = 7; else egroups_per_chan = 5; } else { // toflx if( this->is_full_mode() ) egroups_per_chan = 5; else if( this->is_lpgbt_mode() ) egroups_per_chan = 4; else if( this->get_wide_mode() ) egroups_per_chan = 3; else egroups_per_chan = 5; } return egroups_per_chan; } u_int Device::get_epaths_per_egroup(u_int is_to_flx) { int epaths_per_egroup; if( is_to_flx == 0 ) { // tohost if( this->is_full_mode() ) epaths_per_egroup = 1; else if( this->is_lpgbt_mode() ) epaths_per_egroup = 4; else if( this->get_wide_mode()) epaths_per_egroup = 8; else epaths_per_egroup = 8; } else { // toflx if( this->is_full_mode() ) epaths_per_egroup = 8; else if( this->is_lpgbt_mode() and this->get_firmware_type() != FIRMW_STRIP ) epaths_per_egroup = 4; else if( this->is_lpgbt_mode() and this->get_firmware_type() == FIRMW_STRIP ) epaths_per_egroup = 5; else if( this->get_wide_mode() ) epaths_per_egroup = 8; else epaths_per_egroup = 8; } return epaths_per_egroup; } u_int Device::get_ctrl_elinks_per_channel() { if( m_firmware_type == FIRMW_LTDB ) return 3; // IC, EC, AUX else return 2; // IC, EC } const std::string Device::get_elink_type_str(elink_type_t encoding) { switch(encoding) { case NONE_ELINK_TYPE: return "NONE_ELINK_TYPE"; case DAQ: return "DAQ"; case TTC: return "TTC"; case DCS: return "DCS"; case IC: return "IC"; default: return "UNKNOWN"; } } std::vector Device::get_enabled_elinks_of_type(int dmaid, elink_type_t t) { auto all_elinks = read_enabled_elinks(dmaid); std::vector ret; std::copy_if(all_elinks.begin(), all_elinks.end(), std::back_inserter(ret), [t](Elink e) { return e.type == t; }); // for (auto& e : all_elinks){ // if ( e.type == t ){ // ret.emplace_back(e); // } // } return ret; } unsigned int Device::make_dma_lock_mask(const std::vector& dmaids) { unsigned int lock_mask(LOCK_NONE); for(int id : dmaids){ lock_mask |= LOCK_DMA(id); } return lock_mask; } int64_t Device::broadcast_for(uint64_t elink) { if ((elink & 0x7ff) == 0x7ff) return -1; if ((elink & 0x3f) == 0x3f) return (elink >> 6) & 0x1f; if ((elink & (0x1f << 6)) == (0x1f << 6)) return elink & 0x3f; return elink; } int Device::broadcast_type(uint64_t elink) { if ((elink & 0x7ff) == 0x7ff) return BROADCAST_ALL; if ((elink & 0x3f) == 0x3f) return BROADCAST_CHANNEL; if ((elink & (0x1f << 6)) == (0x1f << 6)) return BROADCAST_ELINK; return BROADCAST_NONE; } const std::string Device::broadcast_type_str(uint64_t elink) { switch(Device::broadcast_type(elink)) { case BROADCAST_NONE: return "None"; case BROADCAST_ALL: return "All"; case BROADCAST_CHANNEL: return "Channel"; case BROADCAST_ELINK: return "E-Link"; default: return "Unknown"; } } // Note allow an array of MAX_BROADCAST_ELINKS for bc_elinks. unsigned Device::broadcast_elinks(uint64_t broadcast_elinks[], const uint64_t broadcast_enable_registers[], uint32_t num_of_channels) { unsigned no_of_broadcast_elinks = 0; int broadcast_to_all = 0; int broadcast_to_elink[64] = {0}; for (uint32_t channel = 0; channel < num_of_channels; channel++) { if (broadcast_enable_registers[channel] > 0) { // Save Broadcast to All broadcast_to_all = 1; // Add Broadcast to all e-links of one link broadcast_elinks[no_of_broadcast_elinks] = ((channel << 6) | 0x03F); // LOG_INFO("Broadcast for link %d to 0x%x", link, broadcast_elinks[no_of_broadcast_elinks]); no_of_broadcast_elinks++; // Save Broadcast to 1 e-link of all links for (uint32_t elink = 0; elink < 64; elink++) { if (broadcast_enable_registers[channel] & (1UL << elink)) { // LOG_INFO("Adding for link %d, elink %d, based on 0x%x and mask 0x%x", link, elink, broadcast_enable_registers[link], (1 << elink)); broadcast_to_elink[elink] = 1; } } } } // Add Broadcast to 1 e-link of all links for (uint32_t elink = 0; elink < 64; elink++) { if (broadcast_to_elink[elink]) { broadcast_elinks[no_of_broadcast_elinks] = ((0x1F << 6) | elink); //LOG_INFO("Broadcast for elink 0x%x to 0x%x", elink, broadcast_elinks[no_of_broadcast_elinks]); no_of_broadcast_elinks++; } } // Add Broadcast to All if needed if (broadcast_to_all) { broadcast_elinks[no_of_broadcast_elinks] = 0x7ff; //LOG_INFO("Broadcast all for links to 0x%x", broadcast_elinks[no_of_broadcast_elinks]); no_of_broadcast_elinks++; } return no_of_broadcast_elinks; } u_int Device::get_broadcast_elinks(uint64_t broadcast_elinks[], uint32_t num_of_channels) { uint64_t broadcast_enable_registers[MAX_BROADCAST_CHANNELS]; for( unsigned channel=0; channel < num_of_channels; ++channel ) { broadcast_enable_registers[channel] = get_broadcast_enable_gen(channel); } unsigned no_of_broadcast_elinks = Device::broadcast_elinks(broadcast_elinks, broadcast_enable_registers, num_of_channels); LOG_INFO("Deduced %d broadcast elinks", no_of_broadcast_elinks); return no_of_broadcast_elinks; }