/**
 * @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 { 2*5, 2*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-x2"
#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 adcin[2] =
{
        {.io_addr = 0x1000, .ch = 0},
        {.io_addr = 0x3000, .ch = 5},
};

static struct wrtd_adcout_dev adcout[2] =
{
        {.io_addr = 0x0000},
        {.io_addr = 0x2000},
};

static inline int wr_link_up(void)
{
        /* Same link for everyone.  */
        return adcin_wr_link_up(&adcin[0]);
}

static inline int wr_time_ready(void)
{
        /* Same time for everyone.  */
        return adcin_wr_time_ready(&adcin[0]);
}

static inline void wr_enable_lock(int enable)
{
        /* No lock.  */
}

static inline int wr_aux_locked(void)
{
        /* No aux clock.  */
        return 1;
}

static inline int wr_sync_timeout(void)
{
        /* No timeout.  */
        return 0;
}

static int wrtd_local_output(struct wrtd_event *ev, unsigned ch)
{
        if ((ch & 15) == 0)
                return adcout_local_output(&adcout[0], ev, 0);
        else
                return adcout_local_output(&adcout[1], ev, 0);
}

static int wrtd_user_init(void)
{
        unsigned i;
        for (i = 0; i < 2; i++) {
                adcin_init(&adcin[i]);
                adcout_init(&adcout[i]);
        }

        wr_enable_lock(0);

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

        return 0;
}

static void wrtd_io(void)
{
        unsigned i;
        for (i = 0; i < 2; i++) {
                adcin_input(&adcin[i]);
                adcout_output(&adcout[i]);
        }
}
