diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_codes.h b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_codes.h new file mode 100644 index 0000000000000000000000000000000000000000..196f5ba4628e9f695e6b4909772e446072e5a855 --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_codes.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _SM_IO_TRIGGER_IFACE_CODES_H_ +#define _SM_IO_TRIGGER_IFACE_CODES_H_ + +/* Messaging OPCODES */ +#define TRIGGER_IFACE_OPCODE_TYPE uint32_t +#define TRIGGER_IFACE_OPCODE_SIZE (sizeof (TRIGGER_IFACE_OPCODE_TYPE)) + +#define TRIGGER_IFACE_OPCODE_DIR 0 +#define TRIGGER_IFACE_NAME_DIR "trigger_iface_dir" +#define TRIGGER_IFACE_OPCODE_RCV_COUNT_RST 1 +#define TRIGGER_IFACE_NAME_RCV_COUNT_RST "trigger_iface_rcv_count_rst" +#define TRIGGER_IFACE_OPCODE_TRANSM_COUNT_RST 2 +#define TRIGGER_IFACE_NAME_TRANSM_COUNT_RST "trigger_iface_transm_count_rst" +#define TRIGGER_IFACE_OPCODE_RCV_LEN 3 +#define TRIGGER_IFACE_NAME_RCV_LEN "trigger_iface_rcv_len" +#define TRIGGER_IFACE_OPCODE_TRANSM_LEN 4 +#define TRIGGER_IFACE_NAME_TRANSM_LEN "trigger_iface_transm_len" +#define TRIGGER_IFACE_OPCODE_COUNT_RCV 5 +#define TRIGGER_IFACE_NAME_COUNT_RCV "trigger_iface_count_rcv" +#define TRIGGER_IFACE_OPCODE_COUNT_TRANSM 6 +#define TRIGGER_IFACE_NAME_COUNT_TRANSM "trigger_iface_count_transm" +#define TRIGGER_IFACE_OPCODE_END 7 + +/* Messaging Reply OPCODES */ +#define TRIGGER_IFACE_REPLY_TYPE uint32_t +#define TRIGGER_IFACE_REPLY_SIZE (sizeof (TRIGGER_IFACE_REPLY_TYPE)) + +#define TRIGGER_IFACE_OK 0 /* Operation was successful */ +#define TRIGGER_IFACE_ERR 1 /* Could not set/get value */ +#define TRIGGER_IFACE_UNINPL 2 /* Unimplemented function or operation */ +#define TRIGGER_IFACE_REPLY_END 3 /* End marker */ + +#endif diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.c b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.c new file mode 100644 index 0000000000000000000000000000000000000000..0f39a6178a5ce25aad24f00a7fbea9a96aaf185d --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "bpm_server.h" +/* Private headers */ +#include "sm_io_trigger_iface_defaults.h" +#include "sm_io_trigger_iface_core.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io_trigger_iface_core]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io_trigger_iface_core]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io_trigger_iface_core]", \ + smio_err_str (err_type)) + +/* Creates a new instance of Device Information */ +smio_trigger_iface_t * smio_trigger_iface_new (smio_t *parent) +{ + (void) parent; + + smio_trigger_iface_t *self = (smio_trigger_iface_t *) zmalloc (sizeof *self); + ASSERT_ALLOC(self, err_self_alloc); + + return self; + +err_self_alloc: + return NULL; +} + +/* Destroy an instance of the Device Information */ +smio_err_e smio_trigger_iface_destroy (smio_trigger_iface_t **self_p) +{ + assert (self_p); + + if (*self_p) { + smio_trigger_iface_t *self = *self_p; + + free (self); + *self_p = NULL; + } + + return SMIO_SUCCESS; +} + diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.h b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.h new file mode 100644 index 0000000000000000000000000000000000000000..13c57845731b1dcd5b58d5629d16ebb82f81e42f --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_core.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. +*/ + +#ifndef _SM_IO_TRIGGER_IFACE_CORE_H_ +#define _SM_IO_TRIGGER_IFACE_CORE_H_ + +typedef struct { + const uint32_t example; +} smio_trigger_iface_t; + +/***************** Our methods *****************/ + +/* Creates a new instance of the smio realization */ +smio_trigger_iface_t * smio_trigger_iface_new (smio_t *parent); +/* Destroys the smio realizationn */ +smio_err_e smio_trigger_iface_destroy (smio_trigger_iface_t **self_p); + +#endif diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.c b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.c new file mode 100644 index 0000000000000000000000000000000000000000..7bc4bd749912980557d49ba993b7f5276534373b --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "bpm_server.h" +/* Private headers */ +#include "sm_io_trigger_iface_defaults.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io:trigger_iface_defaults]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io:trigger_iface_defaults]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io:trigger_iface_defaults]", \ + smio_err_str (err_type)) + +#define SMIO_TRIGGER_IFACE_LIBBPMCLIENT_LOG_MODE "a" +#define SMIO_TRIGGER_IFACE_MAX_CHAN 24 + +/* We use the actual libclient to send and configure our default values, + * maintaining internal consistency. So, in fact, we are sending ourselves + * a message containing the default values. Because of this approach, we + * only get to default our values when the functions are already exported + * to the broker, which happens on a late stage. This could cause a fast + * client to get an inconsistent state from our server */ +/* TODO: Avoid exporting the functions before we have initialized + * our server with the default values */ +smio_err_e trigger_iface_config_defaults (char *broker_endp, char *service, + const char *log_file_name) +{ + (void) log_file_name; + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io:trigger_iface_defaults] Configuring SMIO " + "TRIGGER_IFACE with default values ...\n"); + bpm_client_err_e client_err = BPM_CLIENT_SUCCESS; + smio_err_e err = SMIO_SUCCESS; + + bpm_client_t *config_client = bpm_client_new_log_mode (broker_endp, 0, + log_file_name, SMIO_TRIGGER_IFACE_LIBBPMCLIENT_LOG_MODE); + ASSERT_ALLOC(config_client, err_alloc_client); + + uint32_t chan; + for (chan = 0; chan < SMIO_TRIGGER_IFACE_MAX_CHAN; ++chan) { + client_err = bpm_set_trigger_dir (config_client, service, chan, TRIGGER_IFACE_DFLT_DIR); + client_err |= bpm_set_trigger_rcv_count_rst (config_client, service, chan, TRIGGER_IFACE_DFLT_RCV_RST); + client_err |= bpm_set_trigger_transm_count_rst (config_client, service, chan, TRIGGER_IFACE_DFLT_TRANSM_RST); + client_err |= bpm_set_trigger_rcv_len (config_client, service, chan, TRIGGER_IFACE_DFLT_RCV_LEN); + client_err |= bpm_set_trigger_transm_len (config_client, service, chan, TRIGGER_IFACE_DFLT_TRANSM_LEN); + } + + ASSERT_TEST(client_err == BPM_CLIENT_SUCCESS, "Could set trigger defaults", + err_param_set, SMIO_ERR_CONFIG_DFLT); + +err_param_set: + bpm_client_destroy (&config_client); +err_alloc_client: + DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io:trigger_iface_defaults] Exiting Config thread %s\n", + service); + return err; +} diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.h b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.h new file mode 100644 index 0000000000000000000000000000000000000000..f2ef719f3f4953ddd133f693410504a5902a227d --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_defaults.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _TRIGGER_IFACE_DEFAULTS_H_ +#define _TRIGGER_IFACE_DEFAULTS_H_ + +#include "sm_io_err.h" + +#define TRIGGER_IFACE_DFLT_DIR 1 /* Input */ +#define TRIGGER_IFACE_DFLT_RCV_RST 1 /* Pulse Reset */ +#define TRIGGER_IFACE_DFLT_TRANSM_RST 1 /* Pulse Reset */ +#define TRIGGER_IFACE_DFLT_RCV_LEN 1 /* Debounce Length */ +#define TRIGGER_IFACE_DFLT_TRANSM_LEN 1 /* Pulse Extension Length */ + +smio_err_e trigger_iface_config_defaults (char *broker_endp, char *service, + const char *log_file_name); + +#endif + diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.c b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.c new file mode 100644 index 0000000000000000000000000000000000000000..0545f2e291e4fc590530c68bacb518ae44f29c5d --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "bpm_server.h" +/* Private headers */ +#include "sm_io_trigger_iface_codes.h" +#include "sm_io_trigger_iface_defaults.h" +#include "sm_io_trigger_iface_exports.h" +#include "sm_io_trigger_iface_core.h" +#include "sm_io_trigger_iface_exp.h" +#include "hw/wb_trigger_iface_regs.h" + +/* Undef ASSERT_ALLOC to avoid conflicting with other ASSERT_ALLOC */ +#ifdef ASSERT_TEST +#undef ASSERT_TEST +#endif +#define ASSERT_TEST(test_boolean, err_str, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_TEST(test_boolean, SM_IO, "[sm_io:trigger_iface_exp]", \ + err_str, err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef ASSERT_ALLOC +#undef ASSERT_ALLOC +#endif +#define ASSERT_ALLOC(ptr, err_goto_label, /* err_core */ ...) \ + ASSERT_HAL_ALLOC(ptr, SM_IO, "[sm_io:trigger_iface_exp]", \ + smio_err_str(SMIO_ERR_ALLOC), \ + err_goto_label, /* err_core */ __VA_ARGS__) + +#ifdef CHECK_ERR +#undef CHECK_ERR +#endif +#define CHECK_ERR(err, err_type) \ + CHECK_HAL_ERR(err, SM_IO, "[sm_io:trigger_iface_exp]", \ + smio_err_str (err_type)) + +/* This must match the FPGA maximum number of channels */ +#define TRIGGER_IFACE_NUM_CHAN 24 +#define TRIGGER_IFACE_CHAN_OFFSET 0x00c /* 3 32-bit registers */ + +/*****************************************************************/ +/************ Specific TRIGGER INTERFACE Operations **************/ +/*****************************************************************/ + +#define BPM_TRIGGER_IFACE_DIR_MIN 0 /* Bidirection Buffer set to Output */ +#define BPM_TRIGGER_IFACE_DIR_MAX 1 /* Bidirection Buffer set to Input */ +RW_PARAM_FUNC(trigger_iface, dir) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_CTL, DIR, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, SINGLE_BIT_PARAM, + BPM_TRIGGER_IFACE_DIR_MIN, BPM_TRIGGER_IFACE_DIR_MAX, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +#define BPM_TRIGGER_IFACE_RCV_COUNT_RST_MIN 0 /* Receive Counter Reset */ +#define BPM_TRIGGER_IFACE_RCV_COUNT_RST_MAX 1 /* Receive Counter Reset */ +RW_PARAM_FUNC(trigger_iface, rcv_count_rst) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_CTL, RCV_COUNT_RST, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, SINGLE_BIT_PARAM, + BPM_TRIGGER_IFACE_RCV_COUNT_RST_MIN, BPM_TRIGGER_IFACE_RCV_COUNT_RST_MAX, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +#define BPM_TRIGGER_IFACE_TRANSM_COUNT_RST_MIN 0 /* Transmit Counter Reset */ +#define BPM_TRIGGER_IFACE_TRANSM_COUNT_RST_MAX 1 /* Transmit Counter Reset */ +RW_PARAM_FUNC(trigger_iface, transm_count_rst) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_CTL, TRANSM_COUNT_RST, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, SINGLE_BIT_PARAM, + BPM_TRIGGER_IFACE_TRANSM_COUNT_RST_MIN, BPM_TRIGGER_IFACE_TRANSM_COUNT_RST_MAX, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +#define BPM_TRIGGER_IFACE_RCV_LEN_MIN ((1 << 8) -1) /* Receiver Debounce Length */ +#define BPM_TRIGGER_IFACE_RCV_LEN_MAX ((1 << 8) -1) /* Receiver Debounce Length */ +RW_PARAM_FUNC(trigger_iface, rcv_len) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_CFG, RCV_LEN, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, MULT_BIT_PARAM, + BPM_TRIGGER_IFACE_RCV_LEN_MIN, BPM_TRIGGER_IFACE_RCV_LEN_MAX, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +#define BPM_TRIGGER_IFACE_TRANSM_LEN_MIN ((1 << 8) -1) /* Receiver Debounce Length */ +#define BPM_TRIGGER_IFACE_TRANSM_LEN_MAX ((1 << 8) -1) /* Receiver Debounce Length */ +RW_PARAM_FUNC(trigger_iface, transm_len) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_CFG, TRANSM_LEN, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, MULT_BIT_PARAM, + /* no minimum value */, /* no maximum value */, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +RW_PARAM_FUNC(trigger_iface, count_rcv) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_COUNT, RCV, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, MULT_BIT_PARAM, + /* no minimum value */, /* no maximum value */, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +RW_PARAM_FUNC(trigger_iface, count_transm) { + SET_GET_PARAM_CHANNEL(trigger_iface, WB_TRIGGER_IFACE_RAW_REG_OFFS, WB_TRIG_IFACE, + CH0_COUNT, TRANSM, TRIGGER_IFACE_CHAN_OFFSET, TRIGGER_IFACE_NUM_CHAN, MULT_BIT_PARAM, + /* no minimum value */, /* no maximum value */, NO_CHK_FUNC, + NO_FMT_FUNC, SET_FIELD); +} + +/* Exported function pointers */ +const disp_table_func_fp trigger_iface_exp_fp [] = { + RW_PARAM_FUNC_NAME(trigger_iface, dir), + RW_PARAM_FUNC_NAME(trigger_iface, rcv_count_rst), + RW_PARAM_FUNC_NAME(trigger_iface, transm_count_rst), + RW_PARAM_FUNC_NAME(trigger_iface, rcv_len), + RW_PARAM_FUNC_NAME(trigger_iface, transm_len), + RW_PARAM_FUNC_NAME(trigger_iface, count_rcv), + RW_PARAM_FUNC_NAME(trigger_iface, count_transm), + NULL +}; + +/************************************************************/ +/***************** Export methods functions *****************/ +/************************************************************/ + +static smio_err_e _trigger_iface_do_op (void *owner, void *msg); + +/* Attach an instance of sm_io to dev_io function pointer */ +smio_err_e trigger_iface_attach (smio_t *self, devio_t *parent) +{ + (void) self; + (void) parent; + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Deattach an instance of sm_io to dev_io function pointer */ +smio_err_e trigger_iface_deattach (smio_t *self) +{ + (void) self; + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Export (register) sm_io to handle operations function pointer */ +smio_err_e trigger_iface_export_ops (smio_t *self, + const disp_op_t** smio_exp_ops) +{ + (void) self; + (void) smio_exp_ops; + return SMIO_ERR_FUNC_NOT_IMPL; +} + +/* Unexport (unregister) sm_io to handle operations function pointer */ +smio_err_e trigger_iface_unexport_ops (smio_t *self) +{ + (void) self; + return SMIO_ERR_FUNC_NOT_IMPL; +} + + +/* Generic wrapper for receiving opcodes and arguments to specific funtions function pointer */ +/* FIXME: Code repetition! _devio_do_smio_op () function does almost the same!!! */ +smio_err_e _trigger_iface_do_op (void *owner, void *msg) +{ + (void) owner; + (void) msg; + return SMIO_ERR_FUNC_NOT_IMPL; +} + +smio_err_e trigger_iface_do_op (void *self, void *msg) +{ + return _trigger_iface_do_op (self, msg); +} + +const smio_ops_t trigger_iface_ops = { + .attach = trigger_iface_attach, /* Attach sm_io instance to dev_io */ + .deattach = trigger_iface_deattach, /* Deattach sm_io instance to dev_io */ + .export_ops = trigger_iface_export_ops, /* Export sm_io operations to dev_io */ + .unexport_ops = trigger_iface_unexport_ops, /* Unexport sm_io operations to dev_io */ + .do_op = trigger_iface_do_op /* Generic wrapper for handling specific operations */ +}; + +/************************************************************/ +/****************** Bootstrap Operations ********************/ +/************************************************************/ + +smio_err_e trigger_iface_init (smio_t * self) +{ + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:trigger_iface_exp] Initializing trigger_iface\n"); + + smio_err_e err = SMIO_SUCCESS; + + err = smio_set_id (self, TRIGGER_IFACE_SDB_DEVID); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO id", err_set_id); + err = smio_set_name (self, TRIGGER_IFACE_SDB_NAME); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO name", err_set_name); + + /* Set SMIO ops pointers */ + err = smio_set_ops (self, &trigger_iface_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO operations", + err_smio_set_ops); + err = smio_set_thsafe_client_ops (self, &smio_thsafe_client_zmq_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO thsafe operations", + err_smio_set_thsafe_ops); + + /* Fill the disp_op_t description structure with the callbacks. */ + + /* disp_op_t structure is const and all of the functions performing on it + * obviously receives a const argument, but here (and only on the SMIO + * initialization) we need to make an exception if we want to keep the + * functions' description and the function pointers separate */ + err = smio_init_exp_ops (self, (disp_op_t **) trigger_iface_exp_ops, + trigger_iface_exp_fp); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not fill SMIO " + "function descriptors with the callbacks", err_fill_desc); + + err = smio_set_exp_ops (self, trigger_iface_exp_ops); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO exported operations", + err_smio_set_exp_ops); + + /* Initialize specific structure */ + smio_trigger_iface_t *smio_handler = smio_trigger_iface_new (self); + ASSERT_ALLOC(smio_handler, err_smio_handler_alloc, SMIO_ERR_ALLOC); + err = smio_set_handler (self, smio_handler); + ASSERT_TEST(err == SMIO_SUCCESS, "Could not set SMIO handler", + err_smio_set_handler); + + return err; + +err_smio_set_handler: + smio_trigger_iface_destroy (&smio_handler); +err_smio_handler_alloc: + smio_set_exp_ops (self, NULL); +err_smio_set_exp_ops: +err_fill_desc: + smio_set_thsafe_client_ops (self, NULL); +err_smio_set_thsafe_ops: + smio_set_ops (self, NULL); +err_smio_set_ops: +err_set_name: +err_set_id: + return err; +} + +/* Destroy sm_io instance of trigger_iface */ +smio_err_e trigger_iface_shutdown (smio_t *self) +{ + DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:trigger_iface_exp] Shutting down trigger_iface\n"); + + smio_err_e err = SMIO_SUCCESS; + smio_trigger_iface_t *trig_iface = smio_get_handler (self); + ASSERT_TEST(trig_iface != NULL, "Could not get trig_iface handler", + err_trig_iface_handler, SMIO_ERR_ALLOC /* FIXME: improve return code */); + + /* Destroy SMIO instance */ + smio_trigger_iface_destroy (&trig_iface); + /* Nullify operation pointers */ + smio_set_exp_ops (self, NULL); + smio_set_thsafe_client_ops (self, NULL); + smio_set_ops (self, NULL); + +err_trig_iface_handler: + return err; +} + +const smio_bootstrap_ops_t trigger_iface_bootstrap_ops = { + .init = trigger_iface_init, + .shutdown = trigger_iface_shutdown, + .config_defaults = trigger_iface_config_defaults +}; + +SMIO_MOD_DECLARE(TRIGGER_IFACE_SDB_DEVID, TRIGGER_IFACE_SDB_NAME, trigger_iface_bootstrap_ops) diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.h b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.h new file mode 100644 index 0000000000000000000000000000000000000000..12f381da86dd1025cdfbd2aef56233b29bd57e7b --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exp.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _TRIGGER_IFACE_H_ +#define _TRIGGER_IFACE_H_ + +/* Known modules IDs (from SDB records defined in FPGA) */ +#define TRIGGER_IFACE_SDB_DEVID 0xbcbb78d2 +#define TRIGGER_IFACE_SDB_NAME "TRIGGER_IFACE" + +extern const smio_bootstrap_ops_t trigger_iface_bootstrap_ops; + +#endif + diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.c b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.c new file mode 100644 index 0000000000000000000000000000000000000000..c9cbf69444a1b945c93a99b6ac8d0ac8c911d71b --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#include "sm_io_exports_helper.h" +#include "sm_io_codes.h" + +/* Description SMIO TRIGGER_IFACE functions */ + +disp_op_t trigger_iface_dir_exp = { + .name = TRIGGER_IFACE_NAME_DIR, + .opcode = TRIGGER_IFACE_OPCODE_DIR, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_rcv_count_rst_exp = { + .name = TRIGGER_IFACE_NAME_RCV_COUNT_RST, + .opcode = TRIGGER_IFACE_OPCODE_RCV_COUNT_RST, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_transm_count_rst_exp = { + .name = TRIGGER_IFACE_NAME_TRANSM_COUNT_RST, + .opcode = TRIGGER_IFACE_OPCODE_TRANSM_COUNT_RST, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_rcv_len_exp = { + .name = TRIGGER_IFACE_NAME_RCV_LEN, + .opcode = TRIGGER_IFACE_OPCODE_RCV_LEN, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_transm_len_exp = { + .name = TRIGGER_IFACE_NAME_TRANSM_LEN, + .opcode = TRIGGER_IFACE_OPCODE_TRANSM_LEN, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_count_rcv_exp = { + .name = TRIGGER_IFACE_NAME_COUNT_RCV, + .opcode = TRIGGER_IFACE_OPCODE_COUNT_RCV, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +disp_op_t trigger_iface_count_transm_exp = { + .name = TRIGGER_IFACE_NAME_COUNT_TRANSM, + .opcode = TRIGGER_IFACE_OPCODE_COUNT_TRANSM, + .retval = DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + .retval_owner = DISP_OWNER_OTHER, + .args = { + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_ENCODE(DISP_ATYPE_UINT32, uint32_t), + DISP_ARG_END + } +}; + +/* Exported function description */ +const disp_op_t *trigger_iface_exp_ops [] = { + &trigger_iface_dir_exp, + &trigger_iface_rcv_count_rst_exp, + &trigger_iface_transm_count_rst_exp, + &trigger_iface_rcv_len_exp, + &trigger_iface_transm_len_exp, + &trigger_iface_count_rcv_exp, + &trigger_iface_count_transm_exp, + NULL +}; + diff --git a/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.h b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.h new file mode 100644 index 0000000000000000000000000000000000000000..96f6b4cb971c4299e2de75ffe13b504a77b1bf07 --- /dev/null +++ b/src/sm_io/modules/trigger_iface/sm_io_trigger_iface_exports.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 LNLS (www.lnls.br) + * Author: Lucas Russo <lucas.russo@lnls.br> + * + * Released according to the GNU GPL, version 3 or any later version. + */ + +#ifndef _SM_IO_TRIGGER_IFACE_EXPORTS_H_ +#define _SM_IO_TRIGGER_IFACE_EXPORTS_H_ + +#include "disptable.h" + +extern disp_op_t trigger_iface_dir_exp; +extern disp_op_t trigger_iface_rcv_count_rst_exp; +extern disp_op_t trigger_iface_transm_count_rst_exp; +extern disp_op_t trigger_iface_rcv_len_exp; +extern disp_op_t trigger_iface_transm_len_exp; +extern disp_op_t trigger_iface_count_rcv_exp; +extern disp_op_t trigger_iface_count_transm_exp; + +extern const disp_op_t *trigger_iface_exp_ops []; + +#endif + diff --git a/src/sm_io/modules/trigger_iface/trigger_iface.mk b/src/sm_io/modules/trigger_iface/trigger_iface.mk new file mode 100644 index 0000000000000000000000000000000000000000..1f3140fb6a96a169e4699fdb7419a9f1bb620548 --- /dev/null +++ b/src/sm_io/modules/trigger_iface/trigger_iface.mk @@ -0,0 +1,6 @@ +sm_io_trigger_iface_DIR = $(SRC_DIR)/sm_io/modules/trigger_iface + +sm_io_trigger_iface_OBJS = $(sm_io_trigger_iface_DIR)/sm_io_trigger_iface_core.o \ + $(sm_io_trigger_iface_DIR)/sm_io_trigger_iface_exp.o \ + $(sm_io_trigger_iface_DIR)/sm_io_trigger_iface_exports.o \ + $(sm_io_trigger_iface_DIR)/sm_io_trigger_iface_defaults.o