From 39fdcb0c57bfeba598f00d77f190e731f26b25a1 Mon Sep 17 00:00:00 2001 From: sola.lu <sola.lu@greentest.com.cn> Date: 周四, 24 4月 2025 18:25:01 +0800 Subject: [PATCH] 1.修改一下,把当前库改为刚从origin仓库拉去下来,然后添加了cmake构建文件的状态。 --- libscpi/src/ieee488.c | 348 +++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 224 insertions(+), 124 deletions(-) diff --git a/libscpi/src/ieee488.c b/libscpi/src/ieee488.c index 4b7cb67..c5f2665 100644 --- a/libscpi/src/ieee488.c +++ b/libscpi/src/ieee488.c @@ -1,28 +1,29 @@ /*- - * Copyright (c) 2012-2013 Jan Breuer, + * BSD 2-Clause License * - * All Rights Reserved - * + * Copyright (c) 2012-2018, Jan Breuer + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -41,13 +42,75 @@ #include <stdio.h> -/** - * Update register value - * @param name - register name - */ -static void SCPI_RegUpdate(scpi_t * context, scpi_reg_name_t name) { - SCPI_RegSet(context, name, SCPI_RegGet(context, name)); -} +static const scpi_reg_info_t scpi_reg_details[SCPI_REG_COUNT] = { + { SCPI_REG_CLASS_STB, SCPI_REG_GROUP_STB }, + { SCPI_REG_CLASS_SRE, SCPI_REG_GROUP_STB }, + { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_ESR }, + { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_ESR }, + { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_OPER }, + { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_OPER }, + { SCPI_REG_CLASS_COND, SCPI_REG_GROUP_OPER }, + { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_QUES }, + { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_QUES }, + { SCPI_REG_CLASS_COND, SCPI_REG_GROUP_QUES }, + +#if USE_CUSTOM_REGISTERS +#ifndef USER_REGISTER_DETAILS +#error "No user register details defined" +#else + USER_REGISTER_DETAILS +#endif +#endif + +}; + +static const scpi_reg_group_info_t scpi_reg_group_details[SCPI_REG_GROUP_COUNT] = { + { + SCPI_REG_STB, + SCPI_REG_SRE, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_NONE, + 0 + }, /* SCPI_REG_GROUP_STB */ + { + SCPI_REG_ESR, + SCPI_REG_ESE, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_STB, + STB_ESR + }, /* SCPI_REG_GROUP_ESR */ + { + SCPI_REG_OPER, + SCPI_REG_OPERE, + SCPI_REG_OPERC, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_STB, + STB_OPS + }, /* SCPI_REG_GROUP_OPER */ + { + SCPI_REG_QUES, + SCPI_REG_QUESE, + SCPI_REG_QUESC, + SCPI_REG_NONE, + SCPI_REG_NONE, + SCPI_REG_STB, + STB_QES + }, /* SCPI_REG_GROUP_QUES */ + +#if USE_CUSTOM_REGISTERS +#ifndef USER_REGISTER_GROUP_DETAILS +#error "No user register group details defined" +#else + USER_REGISTER_GROUP_DETAILS +#endif +#endif + +}; /** * Get register value @@ -55,14 +118,20 @@ * @return register value */ scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name) { - if ((name < SCPI_REG_COUNT) && (context->registers != NULL)) { + if ((name < SCPI_REG_COUNT) && context) { return context->registers[name]; } else { return 0; } } -static size_t writeControl(scpi_t * context, int ctrl, scpi_reg_val_t val) { +/** + * Wrapper function to control interface from context + * @param context + * @param ctrl number of controll message + * @param value value of related register + */ +static size_t writeControl(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { if (context && context->interface && context->interface->control) { return context->interface->control(context, ctrl, val); } else { @@ -76,74 +145,98 @@ * @param val - new value */ void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val) { - bool_t srq = FALSE; - scpi_reg_val_t mask; - - if ((name >= SCPI_REG_COUNT) || (context->registers == NULL)) { + if ((name >= SCPI_REG_COUNT) || (context == NULL)) { return; } - - // set register value - context->registers[name] = val; + scpi_reg_group_info_t register_group; - switch (name) { - case SCPI_REG_STB: - mask = SCPI_RegGet(context, SCPI_REG_SRE); - mask &= ~STB_SRQ; - if (val & mask) { - val |= STB_SRQ; - srq = TRUE; - } else { - val &= ~STB_SRQ; - } - break; - case SCPI_REG_SRE: - SCPI_RegUpdate(context, SCPI_REG_STB); - break; - case SCPI_REG_ESR: - if (val & SCPI_RegGet(context, SCPI_REG_ESE)) { - SCPI_RegSetBits(context, SCPI_REG_STB, STB_ESR); - } else { - SCPI_RegClearBits(context, SCPI_REG_STB, STB_ESR); - } - break; - case SCPI_REG_ESE: - SCPI_RegUpdate(context, SCPI_REG_ESR); - break; - case SCPI_REG_QUES: - if (val & SCPI_RegGet(context, SCPI_REG_QUESE)) { - SCPI_RegSetBits(context, SCPI_REG_STB, STB_QES); - } else { - SCPI_RegClearBits(context, SCPI_REG_STB, STB_QES); - } - break; - case SCPI_REG_QUESE: - SCPI_RegUpdate(context, SCPI_REG_QUES); - break; - case SCPI_REG_OPER: - if (val & SCPI_RegGet(context, SCPI_REG_OPERE)) { - SCPI_RegSetBits(context, SCPI_REG_STB, STB_OPS); - } else { - SCPI_RegClearBits(context, SCPI_REG_STB, STB_OPS); - } - break; - case SCPI_REG_OPERE: - SCPI_RegUpdate(context, SCPI_REG_OPER); - break; - - - case SCPI_REG_COUNT: - // nothing to do - break; - } + do { + scpi_reg_class_t register_type = scpi_reg_details[name].type; + register_group = scpi_reg_group_details[scpi_reg_details[name].group]; - // set updated register value - context->registers[name] = val; + scpi_reg_val_t ptrans; - if (srq) { - writeControl(context, SCPI_CTRL_SRQ, SCPI_RegGet(context, SCPI_REG_STB)); - } + /* 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; + } + 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; + + 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; + + 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(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); } /** @@ -164,13 +257,6 @@ SCPI_RegSet(context, name, SCPI_RegGet(context, name) & ~bits); } -/* ============ */ - -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) @@ -178,10 +264,14 @@ * @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); + int i; + for (i = 0; i < SCPI_REG_GROUP_COUNT; ++i) { + scpi_reg_name_t event_reg = scpi_reg_group_details[i].event; + if (event_reg != SCPI_REG_STB) { + SCPI_RegSet(context, event_reg, 0); + } + } return SCPI_RES_OK; } @@ -192,10 +282,11 @@ */ scpi_result_t SCPI_CoreEse(scpi_t * context) { int32_t new_ESE; - if (SCPI_ParamInt(context, &new_ESE, TRUE)) { - SCPI_RegSet(context, SCPI_REG_ESE, new_ESE); + if (SCPI_ParamInt32(context, &new_ESE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t) new_ESE); + return SCPI_RES_OK; } - return SCPI_RES_OK; + return SCPI_RES_ERR; } /** @@ -204,7 +295,7 @@ * @return */ scpi_result_t SCPI_CoreEseQ(scpi_t * context) { - SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_ESE)); + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESE)); return SCPI_RES_OK; } @@ -214,20 +305,31 @@ * @return */ scpi_result_t SCPI_CoreEsrQ(scpi_t * context) { - SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_ESR)); + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESR)); SCPI_RegSet(context, SCPI_REG_ESR, 0); return SCPI_RES_OK; } /** * *IDN? + * + * field1: MANUFACTURE + * field2: MODEL + * field4: SUBSYSTEMS REVISIONS + * + * example: MANUFACTURE,MODEL,0,01-02-01 * @param context * @return */ scpi_result_t SCPI_CoreIdnQ(scpi_t * context) { - SCPI_ResultString(context, SCPI_MANUFACTURE); - SCPI_ResultString(context, SCPI_DEV_NAME); - SCPI_ResultString(context, SCPI_DEV_VERSION); + int i; + for (i = 0; i < 4; i++) { + if (context->idn[i]) { + SCPI_ResultMnemonic(context, context->idn[i]); + } else { + SCPI_ResultMnemonic(context, "0"); + } + } return SCPI_RES_OK; } @@ -247,8 +349,8 @@ * @return */ scpi_result_t SCPI_CoreOpcQ(scpi_t * context) { - // Operation is always completed - SCPI_ResultInt(context, 1); + /* Operation is always completed */ + SCPI_ResultInt32(context, 1); return SCPI_RES_OK; } @@ -271,10 +373,11 @@ */ scpi_result_t SCPI_CoreSre(scpi_t * context) { int32_t new_SRE; - if (SCPI_ParamInt(context, &new_SRE, TRUE)) { - SCPI_RegSet(context, SCPI_REG_SRE, new_SRE); + if (SCPI_ParamInt32(context, &new_SRE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_SRE, (scpi_reg_val_t) new_SRE); + return SCPI_RES_OK; } - return SCPI_RES_OK; + return SCPI_RES_ERR; } /** @@ -283,7 +386,7 @@ * @return */ scpi_result_t SCPI_CoreSreQ(scpi_t * context) { - SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_SRE)); + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_SRE)); return SCPI_RES_OK; } @@ -293,7 +396,7 @@ * @return */ scpi_result_t SCPI_CoreStbQ(scpi_t * context) { - SCPI_ResultInt(context, SCPI_RegGet(context, SCPI_REG_STB)); + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_STB)); return SCPI_RES_OK; } @@ -303,11 +406,8 @@ * @return */ scpi_result_t SCPI_CoreTstQ(scpi_t * context) { - int result = 0; - if (context && context->interface && context->interface->test) { - result = context->interface->test(context); - } - SCPI_ResultInt(context, result); + (void) context; + SCPI_ResultInt32(context, 0); return SCPI_RES_OK; } @@ -318,7 +418,7 @@ */ scpi_result_t SCPI_CoreWai(scpi_t * context) { (void) context; - // NOP + /* NOP */ return SCPI_RES_OK; } -- Gitblit v1.9.1