#ifndef XLRU_FPGA_H
#define XLRU_FPGA_H


#include <stdint.h>

struct fpga_uc_ctrl_t
{
    uint32_t slot_address;
    uint32_t read_back;

    uint32_t dbg_reg[32];

};

struct fpga_uc_info_t
{
    enum { fpga_offset=0x00780};

    uint32_t sw_id[2];
    uint16_t sw_release[2];
    uint32_t sw_build;

    uint32_t slot_address;
    uint32_t spare[3];

    uint32_t supply_status[3];
    uint32_t temperature_status[1];

    int8_t temperature_value[8];

    enum sensor_status_t
    {
        sensor_status_ok,
        sensor_status_under_range,
        sensor_status_over_range,
        sensor_status_not_valid
    };

    sensor_status_t sensorStatus(unsigned int n) const
    {
        unsigned int w=n>>4;
        unsigned int s=n-(w<<4);
        uint32_t v=supply_status[w];
        v=v>>(2*s);
        v=v & 0x3;
        return static_cast<sensor_status_t>(v);
    }

    sensor_status_t temperatureStatus(unsigned int n) const
    {
        uint32_t v=temperature_status[0];
        v=v>>(n*2);
        v=v & 0x3;
        return static_cast<sensor_status_t>(v);
    }

    int temperature(unsigned int n) const
    {
        return temperature_value[n];
    }
};

struct fpga_fw_info_t
{
    enum {fpga_offset=0x0800};

    uint32_t fw_id[2];
    uint32_t fw_release;
    uint32_t fw_build;

    uint32_t lock_link;
    uint32_t lock_link_latched;

    uint32_t cbit_result;
    uint32_t cbit_result_latched;

    uint32_t detector_status;
    uint32_t detector_presence;


};

struct fpga_info_t
{
    enum {
        fpga_info_address=0x44000780,
        fpga_info_gap=fpga_fw_info_t::fpga_offset-fpga_uc_info_t::fpga_offset
    };

    fpga_uc_info_t uc_info;

    uint8_t spare[fpga_info_gap-(sizeof(fpga_uc_info_t))];

    fpga_fw_info_t fw_info;
};

#endif // XLRU_FPGA_H
