From 11f2f2e329ef404d0e9c022cb2f9fbbb45bae285 Mon Sep 17 00:00:00 2001 From: nancy.liao <huihui.liao@greentest.com.cn> Date: 周日, 27 4月 2025 17:33:31 +0800 Subject: [PATCH] 完成了SCPI命令语法分析器的完整规则 --- libscpi/src/ieee488.c | 248 ++++++++++++++++++++++++++----------------------- 1 files changed, 130 insertions(+), 118 deletions(-) diff --git a/libscpi/src/ieee488.c b/libscpi/src/ieee488.c index d55a8f8..09279ba 100644 --- a/libscpi/src/ieee488.c +++ b/libscpi/src/ieee488.c @@ -38,8 +38,6 @@ #include "scpi/parser.h" #include "scpi/ieee488.h" #include "scpi/error.h" -#include "scpi/constants.h" - #include <stdio.h> static const scpi_reg_info_t scpi_reg_details[SCPI_REG_COUNT] = { @@ -53,7 +51,15 @@ { SCPI_REG_CLASS_EVEN, SCPI_REG_GROUP_QUES }, { SCPI_REG_CLASS_ENAB, SCPI_REG_GROUP_QUES }, { SCPI_REG_CLASS_COND, SCPI_REG_GROUP_QUES }, - /* Add device specific register details here*/ + +#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] = { @@ -65,7 +71,7 @@ SCPI_REG_NONE, SCPI_REG_NONE, 0 - }, //SCPI_REG_GROUP_STB + }, /* SCPI_REG_GROUP_STB */ { SCPI_REG_ESR, SCPI_REG_ESE, @@ -74,7 +80,7 @@ SCPI_REG_NONE, SCPI_REG_STB, STB_ESR - }, //SCPI_REG_GROUP_ESR + }, /* SCPI_REG_GROUP_ESR */ { SCPI_REG_OPER, SCPI_REG_OPERE, @@ -83,7 +89,7 @@ SCPI_REG_NONE, SCPI_REG_STB, STB_OPS - }, //SCPI_REG_GROUP_OPER + }, /* SCPI_REG_GROUP_OPER */ { SCPI_REG_QUES, SCPI_REG_QUESE, @@ -92,44 +98,17 @@ SCPI_REG_NONE, SCPI_REG_STB, STB_QES - }, //SCPI_REG_GROUP_QUES - /* Add device specific register group details here*/ + }, /* 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 + }; - -/** - * 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 @@ -164,75 +143,100 @@ * @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; } - 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; + 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 +258,20 @@ } /** - * 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); + 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; } @@ -281,7 +280,8 @@ * @param context * @return */ -scpi_result_t SCPI_CoreEse(scpi_t * context) { +scpi_result_t SCPI_CoreEse(scpi_t * context) +{ int32_t new_ESE; if (SCPI_ParamInt32(context, &new_ESE, TRUE)) { SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t) new_ESE); @@ -324,8 +324,12 @@ */ scpi_result_t SCPI_CoreIdnQ(scpi_t * context) { int i; - for (i = 0; i < 4; i++) { - if (context->idn[i]) { + for (i = 0; i < 4; i++) + { + if (context->idn[i]) + { + char* outPut = "IDNS鍝嶅簲"; + // context->interface->write(context,context->idn[i],0); SCPI_ResultMnemonic(context, context->idn[i]); } else { SCPI_ResultMnemonic(context, "0"); @@ -339,7 +343,8 @@ * @param context * @return */ -scpi_result_t SCPI_CoreOpc(scpi_t * context) { +scpi_result_t SCPI_CoreOpc(scpi_t * context) +{ SCPI_RegSetBits(context, SCPI_REG_ESR, ESR_OPC); return SCPI_RES_OK; } @@ -386,8 +391,14 @@ * @param context * @return */ -scpi_result_t SCPI_CoreSreQ(scpi_t * context) { - SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_SRE)); +scpi_result_t SCPI_CoreSreQ(scpi_t * context) +{ + context->interface->write(context,"Registers request start",0); + for(int i =0;i<SCPI_REG_COUNT;i++) + { + context->interface->write(context,(char*)context->registers[i],0); + } + context->interface->write(context,"Registers request end",0); return SCPI_RES_OK; } @@ -423,3 +434,4 @@ return SCPI_RES_OK; } + -- Gitblit v1.9.1