From 37a293243932cb3b2021ef91377c70e610dd5fc5 Mon Sep 17 00:00:00 2001 From: Howard Li <bighorn@pursuitofchallenge.com> Date: 周日, 19 4月 2020 12:09:28 +0800 Subject: [PATCH] Refactor SCPI_RegSet and SCPI_CoreCls --- libscpi/src/ieee488.c | 186 ++++++++++++++++++++-------------------------- 1 files changed, 81 insertions(+), 105 deletions(-) diff --git a/libscpi/src/ieee488.c b/libscpi/src/ieee488.c index d55a8f8..6323454 100644 --- a/libscpi/src/ieee488.c +++ b/libscpi/src/ieee488.c @@ -97,41 +97,6 @@ }; /** - * Update register value - * @param context - * @param name - register name - */ -static void regUpdate(scpi_t * context, scpi_reg_name_t name) { - SCPI_RegSet(context, name, SCPI_RegGet(context, name)); -} - -/** - * Update latching event register value based on bit transitions from 0 -> 1 - * in the condition register - * @param context - * @param condReg - condition register name - * @param eventReg - event register name - */ -static void regUpdateEvent(scpi_t * context, scpi_reg_val_t oldCondVal, scpi_reg_val_t newCondVal, scpi_reg_name_t eventReg) { - SCPI_RegSet(context, eventReg, ((oldCondVal ^ newCondVal) & newCondVal) | SCPI_RegGet(context, eventReg)); -} - -/** - * Update STB register according to value and its mask register - * @param context - * @param val value of register - * @param mask name of mask register (enable register) - * @param stbBits bits to clear or set in STB - */ -static void regUpdateSTB(scpi_t * context, scpi_reg_val_t val, scpi_reg_name_t mask, scpi_reg_val_t stbBits) { - if (val & SCPI_RegGet(context, mask)) { - SCPI_RegSetBits(context, SCPI_REG_STB, stbBits); - } else { - SCPI_RegClearBits(context, SCPI_REG_STB, stbBits); - } -} - -/** * Get register value * @param name - register name * @return register value @@ -164,75 +129,94 @@ * @param val - new value */ void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val) { - scpi_bool_t srq = FALSE; - scpi_reg_val_t mask; - scpi_reg_val_t old_val; - if ((name >= SCPI_REG_COUNT) || (context == NULL)) { return; } - /* store old register value */ - old_val = context->registers[name]; + scpi_reg_group_info_t register_group; - /* set register value */ - context->registers[name] = val; + do { + scpi_reg_class_t register_type = scpi_reg_details[name].type; + register_group = scpi_reg_group_details[scpi_reg_details[name].group]; - /** @TODO: remove recutsion */ - switch (name) { - case SCPI_REG_STB: - mask = SCPI_RegGet(context, SCPI_REG_SRE); - mask &= ~STB_SRQ; - if (val & mask) { - val |= STB_SRQ; - /* avoid sending SRQ if nothing has changed */ - if (old_val != val) { - srq = TRUE; + scpi_reg_val_t ptrans; + + /* store old register value */ + scpi_reg_val_t old_val = context->registers[name]; + + if (old_val == val) { + return; + } else { + context->registers[name] = val; + } + + switch (register_type) { + case SCPI_REG_CLASS_STB: + case SCPI_REG_CLASS_SRE: + ; + scpi_reg_val_t stb = context->registers[SCPI_REG_STB] & ~STB_SRQ; + scpi_reg_val_t sre = context->registers[SCPI_REG_SRE] & ~STB_SRQ; + + if (stb & sre) { + ptrans = ((old_val ^ val) & val); + context->registers[SCPI_REG_STB] |= STB_SRQ; + if (ptrans & val) { + writeControl(context, SCPI_CTRL_SRQ, context->registers[SCPI_REG_STB]); + } + } else { + context->registers[SCPI_REG_STB] &= ~STB_SRQ; } - } else { - val &= ~STB_SRQ; - } - break; - case SCPI_REG_SRE: - regUpdate(context, SCPI_REG_STB); - break; - case SCPI_REG_ESR: - regUpdateSTB(context, val, SCPI_REG_ESE, STB_ESR); - break; - case SCPI_REG_ESE: - regUpdate(context, SCPI_REG_ESR); - break; - case SCPI_REG_QUES: - regUpdateSTB(context, val, SCPI_REG_QUESE, STB_QES); - break; - case SCPI_REG_QUESE: - regUpdate(context, SCPI_REG_QUES); - break; - case SCPI_REG_QUESC: - regUpdateEvent(context, old_val, val, SCPI_REG_QUES); - break; - case SCPI_REG_OPER: - regUpdateSTB(context, val, SCPI_REG_OPERE, STB_OPS); - break; - case SCPI_REG_OPERE: - regUpdate(context, SCPI_REG_OPER); - break; - case SCPI_REG_OPERC: - regUpdateEvent(context, old_val, val, SCPI_REG_OPER); - break; + break; + case SCPI_REG_CLASS_EVEN: + ; + scpi_reg_val_t enable; + if(register_group.enable != SCPI_REG_NONE) { + enable = SCPI_RegGet(context, register_group.enable); + } else { + enable = 0xFFFF; + } + scpi_bool_t summary = val & enable; - case SCPI_REG_COUNT: - /* nothing to do */ - break; - } + name = register_group.parent_reg; + val = SCPI_RegGet(context, register_group.parent_reg); + if (summary) { + val |= register_group.parent_bit; + } else { + val &= ~(register_group.parent_bit); + } + break; + case SCPI_REG_CLASS_COND: + name = register_group.event; - /* set updated register value */ - context->registers[name] = val; + if(register_group.ptfilt == SCPI_REG_NONE && register_group.ntfilt == SCPI_REG_NONE) { + val = ((old_val ^ val) & val) | SCPI_RegGet(context, register_group.event); + } else { + scpi_reg_val_t ptfilt = 0, ntfilt = 0; + scpi_reg_val_t transitions; + scpi_reg_val_t ntrans; - if (srq) { - writeControl(context, SCPI_CTRL_SRQ, SCPI_RegGet(context, SCPI_REG_STB)); - } + if(register_group.ptfilt != SCPI_REG_NONE) { + ptfilt = SCPI_RegGet(context, register_group.ptfilt); + } + + if(register_group.ntfilt != SCPI_REG_NONE) { + ntfilt = SCPI_RegGet(context, register_group.ntfilt); + } + + transitions = old_val ^ val; + ptrans = transitions & val; + ntrans = transitions & ~ptrans; + + val = ((ptrans & ptfilt) | (ntrans & ntfilt)) | SCPI_RegGet(context, register_group.event); + } + break; + case SCPI_REG_CLASS_ENAB: + case SCPI_REG_CLASS_NTR: + case SCPI_REG_CLASS_PTR: + return; + } + } while(register_group.parent_reg != SCPI_REG_NONE); } /** @@ -254,25 +238,17 @@ } /** - * Clear event register - * @param context - */ -void SCPI_EventClear(scpi_t * context) { - /* TODO */ - SCPI_RegSet(context, SCPI_REG_ESR, 0); -} - -/** * *CLS - This command clears all status data structures in a device. * For a device which minimally complies with SCPI. (SCPI std 4.1.3.2) * @param context * @return */ scpi_result_t SCPI_CoreCls(scpi_t * context) { - SCPI_EventClear(context); SCPI_ErrorClear(context); - SCPI_RegSet(context, SCPI_REG_OPER, 0); - SCPI_RegSet(context, SCPI_REG_QUES, 0); + for (int i = 0; i < SCPI_REG_GROUP_COUNT; ++i) { + scpi_reg_name_t event_reg = scpi_reg_group_details[i].event; + SCPI_RegSet(context, event_reg, 0); + } return SCPI_RES_OK; } -- Gitblit v1.9.1