/**
 * @file wrtd-rt-adc.c
 *
 * Copyright (c) 2018-2019 CERN (home.cern)
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "fmc_adc_aux_trigout.h"

#define NBR_CPUS 1
#define CPU_IDX 0
#define NBR_RULES 16
#define NBR_DEVICES 2
#define NBR_ALARMS 1
#define DEVICES_NBR_CHS { 5, 1, 0, 0}
#define DEVICES_CHS_DIR { WRTD_CH_DIR_IN, WRTD_CH_DIR_OUT, 0, 0}
#define APP_ID 0x35B0
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-adc"
#define WRTD_NET_TX 1
#define WRTD_NET_RX 1
#define WRTD_LOCAL_TX 1
#define WRTD_LOCAL_RX 1

#include "wrtd-rt-common.h"

#include "wrtd-adcout.c"
#include "wrtd-adcin.c"

static struct wrtd_adcin_dev adcin0 =
{
        .io_addr = 0x0000,
};

static struct wrtd_adcout_dev adcout0 =
{
        .io_addr = 0x1000,
};

static inline int wr_link_up(void)
{
        if (!adcin_wr_link_up(&adcin0))
                return 0;
        if (!adcout_wr_link_up(&adcout0))
                return 0;
        return 1;
}

static inline int wr_time_locked(void)
{
        if (!adcin_wr_time_locked(&adcin0))
                return 0;
        if (!adcout_wr_time_locked(&adcout0))
                return 0;
        return 1;
}

static inline int wr_time_ready(void)
{
        if (!adcin_wr_time_ready(&adcin0))
                return 0;
        if (!adcout_wr_time_ready(&adcout0))
                return 0;
        return 1;
}

static inline void wr_enable_lock(int enable)
{
        adcin_wr_enable_lock(&adcin0, enable);
        adcout_wr_enable_lock(&adcout0, enable);
}

static inline int wr_sync_timeout(void)
{
#ifdef SIMULATION
        return 0;
#else
        int res, val;
        res = 0;

        val = adcin_wr_sync_timeout();
        res = val > res ? val : res;

        val = adcout_wr_sync_timeout();
        res = val > res ? val : res;
        return res;
#endif
}

static int wrtd_local_output(struct wrtd_event *ev, unsigned ch)
{
        return adcout_local_output(&adcout0, ev, ch);
}

static int wrtd_user_init(void)
{
        adcin_init(&adcin0);
        adcout_init(&adcout0);

        wr_enable_lock(0);

        pr_debug("rt-adc firmware initialized.\n\r");

        return 0;
}

static void wrtd_io(void)
{
        adcin_input(&adcin0);
        adcout_output(&adcout0);
}
