Program Listing for File device_file.cpp

Return to documentation for file (device_file.cpp)

#include "device.hpp"
#include "log.hpp"


FileDevice::FileDevice(ConfigFile& cfg, unsigned dev_no)
    : Device(dev_no, cfg.resource.vid, cfg.resource.did, cfg.get_device_cid(dev_no)),
    m_locks(0), m_regmap(cfg.regmap), m_channels(cfg.channels),
    m_block_size(cfg.block_size), m_trailer_size(32), m_wide_mode(0), m_max_tlp_bytes(cfg.max_tlp_bytes),
    m_toflx_dmaid(cfg.toflx_dmaid), m_trickle_dmaid(6), m_status_leds(0), m_busy(0)
{
    m_firmware_type         = cfg.firmware;
    m_fromHostDataFormat    = static_cast<flx_fromhost_format>(cfg.fromHostDataFormat);
    m_toHostDataFormat      = static_cast<flx_tohost_format>(cfg.toHostDataFormat);

    for (auto dma_elinks_pair : cfg.elinks) {
        int dmaid = dma_elinks_pair.first;
        uint8_t is_to_flx = (dmaid == m_toflx_dmaid || dmaid == m_trickle_dmaid);
        for (uint16_t elink : dma_elinks_pair.second) {
            bool is_ttc = (elink == TTC2HOST_LINK(m_channels)) ? true : false;
            felix_id_t fid = get_fid_from_ids(m_did, m_cid, elink, 0, m_vid, is_to_flx, is_ttc);
            elink_type_t type = is_ttc ? elink_type_t::TTC : elink_type_t::DAQ;
            encoding_t enc = is_ttc ? encoding_t::ENC_TTC : encoding_t::ENC_8b10b;
            m_enabled_elinks[dmaid].emplace_back(fid, elink, false, type, enc);
        }
    }

    for (auto dma_elinks_pair : cfg.elinks_with_streams) {
        int dmaid = dma_elinks_pair.first;
        uint8_t is_to_flx = (dmaid == m_toflx_dmaid || dmaid == m_trickle_dmaid);
        for (uint16_t elink : dma_elinks_pair.second) {
            elink_type_t type = elink_type_t::DAQ;
            encoding_t enc = encoding_t::ENC_8b10b;
            felix_id_t fid = get_fid_from_ids(m_did, m_cid, elink, 0, m_vid, is_to_flx, false);
            m_enabled_elinks[dmaid].emplace_back(fid, elink, true, type, enc);
        }
    }

}


FileDevice::FileDevice(unsigned dev_no)
    : Device(dev_no, 0, 0, dev_no),
    m_locks(0), m_regmap(REGMAP_VERSION), m_channels(24),
    m_block_size(1024), m_trailer_size(32), m_wide_mode(0), m_max_tlp_bytes(32),
    m_toflx_dmaid(5), m_trickle_dmaid(6), m_status_leds(0), m_busy(0)
{
    m_toHostDataFormat = TOHOST_SUBCHUNK_TRAILER;
}

int FileDevice::open_device(u_int lock_mask)
{
    if (lock_mask != 0 && lock_mask == m_locks){
        LOG_ERR("Device locked. Current locked mask 0x%x", m_locks);
    }
    m_locks = lock_mask;

    u_long major = (m_regmap & 0xFF00) >> 8;
    u_long minor = (m_regmap & 0x00FF) >> 0;
    LOG_INFO("  regmap version %lu.%lu", major, minor);
    if ( has_wrong_rm()){
        LOG_ERR("felix-star compiled for register map 0x%x, firmware uses 0x%x\n", REGMAP_VERSION, m_regmap);
        return 1;
    }

    // only initialize m_fromHostDataFormat if not already set
    if (m_regmap < 0x500 and m_fromHostDataFormat == UN_INITIALIZED){
        m_fromHostDataFormat = FROMHOST_FORMAT_REGMAP4;
        m_trailer_size = 2;
        m_block_size = 1024;
    } else if (m_fromHostDataFormat == UN_INITIALIZED){
        m_fromHostDataFormat = FROMHOST_FORMAT_HDR32_PACKET32;
        m_trailer_size = 4;
    }
    return 0;
}


void FileDevice::set_register(const char *key, uint64_t value)
{
    if (!strcmp(key, "STATUS_LEDS")) {
        m_status_leds = value;
    } else if (!strcmp(key, "TTC_DEC_CTRL_MASTER_BUSY")) {
        m_busy = value;
    }
}


uint64_t FileDevice::get_register(const char *key)
{
    if (!strcmp(key, "STATUS_LEDS")) {
        return m_status_leds;
    } else if (!strcmp(key, "REG_MAP_VERSION")) {
        return m_regmap;
    } else if (!strcmp(key, "PCIE_ENDPOINT")) {
        return m_device_number;
    } else if (!strcmp(key, "TTC_DEC_CTRL_MASTER_BUSY")) {
        return m_busy;
    } else if (!strcmp(key, "FPGA_DNA")) {
        return 0x012007c004500580;
    } else if (!strcmp(key, "FPGA_CORE_TEMP")) {
        return 2688;
    } else if (!strcmp(key, "TACH_CNT")) {
        return 67285;
    } else if (!strcmp(key, "MMCM_MAIN_MAIN_INPUT")) {
        return 2;
    } else if (!strcmp(key, "MMCM_MAIN_PLL_LOCK")) {
        return 1;
    } else if (!strcmp(key, "FIRMWARE_MODE")) {
        return 0;
    } else if (!strcmp(key, "BOARD_ID_TIMESTAMP")) {
        return 0x2006112009;
    } else if (!strcmp(key, "GIT_HASH")) {
        return 0xd20ac176;
    } else if (!strcmp(key, "GBT_ALIGNMENT_DONE")) {
        return 0x0;
    } else if (!strcmp(key, "GBT_ERROR")) {
        return 0x0;
    } else if (!strcmp(key, "NUM_OF_CHANNELS")) {
        return 12;
    }
    return 0;
}


void FileDevice::add_enabled_elink(Elink e, int dmaid)
{
    std::vector<Elink>& elinks_dmaid = m_enabled_elinks[dmaid];
    LOG_INFO("Enabling elink %u on dmaid %d", e.lid, dmaid);
    elinks_dmaid.push_back(e);
}


std::vector<Elink> FileDevice::read_enabled_elinks(int dmaid)
{
    return m_enabled_elinks.at(dmaid);
}


bool FileDevice::dma_enabled(int dmaid)
{
    return true;
}


void FileDevice::dma_to_host(DmaBuffer* buf, int dmaid)
{
    buf->pend = buf->paddr + buf->size;
    buf->pc_ptr = buf->paddr;
    buf->emu_fw_ptr = buf->paddr;
}


uint64_t FileDevice::get_broadcast_enable_gen(u_int channel)
{
    return 0;
}


bool FileDevice::elink_has_stream_id(u_int channel, u_int egroup, u_int epath)
{
    return true;
}


monitoring_data_t FileDevice::hw_get_monitoring_data(unsigned int mon_mask)
{
    monitoring_data_t mondata;
    //no need of emulating the readout of all parameters.
    if( mon_mask & FPGA_MONITOR )
    {
        mondata.fpga.temperature = 70;
        mondata.fpga.vccint = 10;
        mondata.fpga.vccaux = 1;
        mondata.fpga.vccbram = 1;
        mondata.fpga.fanspeed = 8000;
        mondata.fpga.dna = 0x1000000000000;
    }
    return mondata;
}