From de33e5309a59555dd45fe8bd4acefe17ccaeadb3 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Wed, 3 Apr 2019 16:03:46 -0300 Subject: [PATCH] sm_io/*/acq: add FC_FULL error status when fifo full This is related to github issue lnls-dig/bpm-epics-ioc#30 --- core/sm_io/include/sm_io_acq_codes.h | 3 ++- .../src/sm_io/c/modules/acq/sm_io_acq_exp.c | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/sm_io/include/sm_io_acq_codes.h b/core/sm_io/include/sm_io_acq_codes.h index 6caf976e..e4d023d1 100644 --- a/core/sm_io/include/sm_io_acq_codes.h +++ b/core/sm_io/include/sm_io_acq_codes.h @@ -67,6 +67,7 @@ struct _smio_acq_data_block_t { #define ACQ_NUM_CHAN_OOR 5 /* Channel number out of range */ #define ACQ_COULD_NOT_READ 6 /* Could not read memory block */ #define ACQ_TRIG_TYPE 7 /* Incompatible trigger type */ -#define ACQ_REPLY_END 8 /* End marker */ +#define ACQ_FC_FULL 8 /* Acquisition overlfow error */ +#define ACQ_REPLY_END 9 /* End marker */ #endif diff --git a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c index 569e17f3..32227c36 100644 --- a/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c +++ b/core/sm_io/src/sm_io/c/modules/acq/sm_io_acq_exp.c @@ -46,6 +46,9 @@ #define ACQ_CORE_IDLE_VALUE ACQ_CORE_STA_FSM_STATE_W(0x1) +#define ACQ_CORE_FC_FULL_MASK ACQ_CORE_STA_FC_FULL +#define ACQ_CORE_FC_FULL_VALUE ACQ_CORE_STA_FC_FULL + /* Acquisition is completed when FSM is in IDLE state, FSM is with DONE * flag asserted, Flow Control FIFO is with DOME flag asserted and DDR3 has * its DONE flag asserted */ @@ -56,7 +59,8 @@ ACQ_CORE_STA_FC_TRANS_DONE | ACQ_CORE_STA_DDR3_TRANS_DONE) static int _acq_check_status (SMIO_OWNER_TYPE *self, uint32_t status_mask, - uint32_t status_value); + uint32_t status_value, uint32_t status_oflow_mask, + uint32_t status_oflow_value); static int _acq_set_trigger_type (SMIO_OWNER_TYPE *self, uint32_t trigger_type); static int _acq_get_trigger_type (SMIO_OWNER_TYPE *self, uint32_t *trigger_type); static uint64_t _acq_get_start_address (uint64_t acq_core_trig_addr, @@ -85,7 +89,8 @@ static int _acq_data_acquire (void *owner, void *args, void *ret) /* First step is to check if the FPGA is already doing an acquisition. If it * is, then return an error. Otherwise proceed normally. */ - err = _acq_check_status (self, ACQ_CORE_IDLE_MASK, ACQ_CORE_IDLE_VALUE); + err = _acq_check_status (self, ACQ_CORE_IDLE_MASK, ACQ_CORE_IDLE_VALUE, + ACQ_CORE_FC_FULL_MASK, ACQ_CORE_FC_FULL_VALUE); ASSERT_TEST(err == -ACQ_OK, "Previous acquisition in progress. " "New acquisition not started", err_acq_not_completed); @@ -254,7 +259,8 @@ static int _acq_check_data_acquire (void *owner, void *args, void *ret) uint32_t chan = acq->curr_chan; - err = _acq_check_status (self, ACQ_CORE_COMPLETE_MASK, ACQ_CORE_COMPLETE_VALUE); + err = _acq_check_status (self, ACQ_CORE_COMPLETE_MASK, ACQ_CORE_COMPLETE_VALUE, + ACQ_CORE_FC_FULL_MASK, ACQ_CORE_FC_FULL_VALUE); if (err != -ACQ_OK) { DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] acq_check_data_acquire: " "Acquisition is not done for channel %u\n", chan); @@ -272,7 +278,8 @@ static int _acq_check_data_acquire (void *owner, void *args, void *ret) } static int _acq_check_status (SMIO_OWNER_TYPE *self, uint32_t status_mask, - uint32_t status_value) + uint32_t status_value, uint32_t status_oflow_mask, + uint32_t status_oflow_value) { int err = -ACQ_OK; uint32_t status_done = 0; @@ -282,6 +289,11 @@ static int _acq_check_status (SMIO_OWNER_TYPE *self, uint32_t status_mask, DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:acq] data_acquire: " "Status done = 0x%08x\n", status_done); + if ((status_done & status_oflow_mask) == status_oflow_value) { + err = -ACQ_FC_FULL; + goto err_fc_full; + } + if ((status_done & status_mask) != status_value) { err = -ACQ_NOT_COMPLETED; goto err_not_completed; @@ -289,6 +301,7 @@ static int _acq_check_status (SMIO_OWNER_TYPE *self, uint32_t status_mask, err = -ACQ_OK; +err_fc_full: err_not_completed: return err; } @@ -574,7 +587,8 @@ static int _acq_cfg_trigger (void *owner, void *args, void *ret) else { /* Only check if the FPGA is already doing an acquisition if we are about * to change it. If it is, then return an error. Otherwise proceed normally. */ - err = _acq_check_status (self, ACQ_CORE_IDLE_MASK, ACQ_CORE_IDLE_VALUE); + err = _acq_check_status (self, ACQ_CORE_IDLE_MASK, ACQ_CORE_IDLE_VALUE, + ACQ_CORE_FC_FULL_MASK, ACQ_CORE_FC_FULL_VALUE); ASSERT_TEST(err == -ACQ_OK, "Previous acquisition in progress. " "Cannot change trigger type", err_acq_not_completed);