| | |
| | | /libscpi/obj/ |
| | | /libscpi/dist/ |
| | | |
| | | /nbproject/ |
| | |
| | | #include "scpi-def.h" |
| | | |
| | | scpi_result_t DMM_MeasureVoltageDcQ(scpi_t * context) { |
| | | scpi_parameter_t param1, param2; |
| | | scpi_number_t param1, param2; |
| | | char bf[15]; |
| | | fprintf(stderr, "meas:volt:dc\r\n"); // debug command name |
| | | |
| | | // read first parameter if present |
| | | if (SCPI_Parameter(context, ¶m1, false)) { |
| | | SCPI_ParamTranslateNumberVal(context, ¶m1); |
| | | if (!SCPI_ParamNumber(context, ¶m1, false)) { |
| | | // do something, if parameter not present |
| | | } |
| | | |
| | | // read second paraeter if present |
| | | if (SCPI_Parameter(context, ¶m2, false)) { |
| | | SCPI_ParamTranslateNumberVal(context, ¶m2); |
| | | if (!SCPI_ParamNumber(context, ¶m2, false)) { |
| | | // do something, if parameter not present |
| | | } |
| | | |
| | | |
| | | SCPI_NumberToStr(context, ¶m1.number, bf, 15); |
| | | SCPI_NumberToStr(context, ¶m1, bf, 15); |
| | | fprintf(stderr, "\tP1=%s\r\n", bf); |
| | | |
| | | |
| | | SCPI_NumberToStr(context, ¶m2.number, bf, 15); |
| | | SCPI_NumberToStr(context, ¶m2, bf, 15); |
| | | fprintf(stderr, "\tP2=%s\r\n", bf); |
| | | |
| | | SCPI_ResultDouble(context, 0); |
| | |
| | | } |
| | | |
| | | |
| | | scpi_result_t DMM_MeasureVoltageAcQ(scpi_t * context) { |
| | | scpi_number_t param1, param2; |
| | | char bf[15]; |
| | | fprintf(stderr, "meas:volt:ac\r\n"); // debug command name |
| | | |
| | | // read first parameter if present |
| | | if (!SCPI_ParamNumber(context, ¶m1, false)) { |
| | | // do something, if parameter not present |
| | | } |
| | | |
| | | // read second paraeter if present |
| | | if (!SCPI_ParamNumber(context, ¶m2, false)) { |
| | | // do something, if parameter not present |
| | | } |
| | | |
| | | |
| | | SCPI_NumberToStr(context, ¶m1, bf, 15); |
| | | fprintf(stderr, "\tP1=%s\r\n", bf); |
| | | |
| | | |
| | | SCPI_NumberToStr(context, ¶m2, bf, 15); |
| | | fprintf(stderr, "\tP2=%s\r\n", bf); |
| | | |
| | | SCPI_ResultDouble(context, 0); |
| | | |
| | | return SCPI_RES_OK; |
| | | } |
| | | |
| | | scpi_result_t DMM_ConfigureVoltageDc(scpi_t * context) { |
| | | scpi_parameter_t param1, param2; |
| | | double param1, param2; |
| | | fprintf(stderr, "conf:volt:dc\r\n"); // debug command name |
| | | |
| | | // read first parameter if present |
| | | if (!SCPI_Parameter(context, ¶m1, true)) { |
| | | if (!SCPI_ParamDouble(context, ¶m1, true)) { |
| | | return SCPI_RES_ERR; |
| | | } |
| | | |
| | | // read second paraeter if present |
| | | if (!SCPI_Parameter(context, ¶m2, false)) { |
| | | if (!SCPI_ParamDouble(context, ¶m2, false)) { |
| | | // do something, if parameter not present |
| | | } |
| | | |
| | | fprintf(stderr, "\tP1=%lf\r\n", SCPI_ParamGetDoubleVal(context, ¶m1)); |
| | | fprintf(stderr, "\tP2=%lf\r\n", SCPI_ParamGetDoubleVal(context, ¶m2)); |
| | | fprintf(stderr, "\tP1=%lf\r\n", param1); |
| | | fprintf(stderr, "\tP2=%lf\r\n", param2); |
| | | |
| | | return SCPI_RES_OK; |
| | | } |
| | | |
| | | scpi_result_t TEST_Bool(scpi_t * context) { |
| | | scpi_parameter_t param1; |
| | | scpi_bool_t param1; |
| | | fprintf(stderr, "TEST:BOOL\r\n"); // debug command name |
| | | |
| | | // read first parameter if present |
| | | if (!SCPI_Parameter(context, ¶m1, true)) { |
| | | if (!SCPI_ParamBool(context, ¶m1, true)) { |
| | | return SCPI_RES_ERR; |
| | | } |
| | | |
| | | fprintf(stderr, "\tP1=%d\r\n", SCPI_ParamGetBoolVal(context, ¶m1)); |
| | | fprintf(stderr, "\tP1=%d\r\n", param1); |
| | | |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | |
| | | |
| | | scpi_result_t TEST_ChoiceQ(scpi_t * context) { |
| | | scpi_parameter_t param1; |
| | | int32_t result; |
| | | |
| | | if (!SCPI_Parameter(context, ¶m1, true)) { |
| | | int32_t param; |
| | | |
| | | if (!SCPI_ParamChoice(context, trigger_source, ¶m, true)) { |
| | | return SCPI_RES_ERR; |
| | | } |
| | | |
| | | result = SCPI_ParamGetChoiceVal(context, ¶m1, trigger_source); |
| | | fprintf(stderr, "\tP1=%s (%d)\r\n", trigger_source[param], param); |
| | | |
| | | fprintf(stderr, "\tP1=%s (%d)\r\n", result >= 0 ? trigger_source[result] : "", result); |
| | | |
| | | SCPI_ResultInt(context, result); |
| | | SCPI_ResultInt(context, param); |
| | | |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | {.pattern = "MEASure:VOLTage:DC?", .callback = DMM_MeasureVoltageDcQ,}, |
| | | {.pattern = "CONFigure:VOLTage:DC", .callback = DMM_ConfigureVoltageDc,}, |
| | | {.pattern = "MEASure:VOLTage:DC:RATio?", .callback = SCPI_StubQ,}, |
| | | {.pattern = "MEASure:VOLTage:AC?", .callback = SCPI_StubQ,}, |
| | | {.pattern = "MEASure:VOLTage:AC?", .callback = DMM_MeasureVoltageAcQ,}, |
| | | {.pattern = "MEASure:CURRent:DC?", .callback = SCPI_StubQ,}, |
| | | {.pattern = "MEASure:CURRent:AC?", .callback = SCPI_StubQ,}, |
| | | {.pattern = "MEASure:RESistance?", .callback = SCPI_StubQ,}, |
| | |
| | | size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len); |
| | | size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val); |
| | | |
| | | int32_t SCPI_ParamGetIntVal(scpi_t * context, scpi_parameter_t * parameter); |
| | | double SCPI_ParamGetDoubleVal(scpi_t * context, scpi_parameter_t * parameter); |
| | | void SCPI_ParamGetTextVal(scpi_t * context, scpi_parameter_t * parameter, const char ** data, int32_t * len); |
| | | #define SCPI_ParamGetCharactersVal SCPI_ParamGetTextVal |
| | | #define SCPI_ParamGetArbitraryBlockVal SCPI_ParamGetTextVal |
| | | scpi_bool_t SCPI_ParamGetBoolVal(scpi_t * context, scpi_parameter_t * parameter); |
| | | int32_t SCPI_ParamGetChoiceVal(scpi_t * context, scpi_parameter_t * parameter, const char * options[]); |
| | | |
| | | scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory); |
| | | scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed); |
| | | |
| | | scpi_bool_t SCPI_ParamInt(scpi_t * context, int32_t * value, scpi_bool_t mandatory); |
| | | scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory); |
| | | // scpi_bool_t SCPI_ParamString(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); |
| | | scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); |
| | | #define SCPI_ParamArbitraryBlock SCPI_ParamCharacters |
| | | scpi_bool_t SCPI_ParamText(scpi_t * context, const char ** value, size_t * len, int * type, scpi_bool_t mandatory); |
| | | |
| | | scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory); |
| | | scpi_bool_t SCPI_ParamChoice(scpi_t * context, const char * options[], int32_t * value, scpi_bool_t mandatory); |
| | | |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | int8_t base; |
| | | scpi_special_number_t type; |
| | | }; |
| | | typedef struct _scpi_number_parameter_t scpi_number_parameter_t; |
| | | typedef struct _scpi_number_parameter_t scpi_number_t; |
| | | |
| | | struct _scpi_data_parameter_t { |
| | | const char * ptr; |
| | |
| | | struct _scpi_parameter_t { |
| | | scpi_token_type_t type; |
| | | scpi_data_parameter_t data; |
| | | scpi_number_parameter_t number; |
| | | scpi_number_t number; |
| | | }; |
| | | typedef struct _scpi_parameter_t scpi_parameter_t; |
| | | |
| | |
| | | extern const scpi_unit_def_t scpi_units_def[]; |
| | | extern const scpi_special_number_def_t scpi_special_numbers_def[]; |
| | | |
| | | scpi_bool_t SCPI_ParamNumber(scpi_t * context, scpi_number_t * value, scpi_bool_t mandatory); |
| | | |
| | | scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter); |
| | | size_t SCPI_NumberToStr(scpi_t * context, scpi_number_parameter_t * value, char * str, size_t len); |
| | | size_t SCPI_NumberToStr(scpi_t * context, scpi_number_t * value, char * str, size_t len); |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_CoreEse(scpi_t * context) { |
| | | scpi_parameter_t parameter; |
| | | if (SCPI_Parameter(context, ¶meter, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_ESE, SCPI_ParamGetIntVal(context, ¶meter)); |
| | | int32_t new_ESE; |
| | | if (SCPI_ParamInt(context, &new_ESE, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_ESE, new_ESE); |
| | | } |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_CoreSre(scpi_t * context) { |
| | | scpi_parameter_t parameter; |
| | | if (SCPI_Parameter(context, ¶meter, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_SRE, SCPI_ParamGetIntVal(context, ¶meter)); |
| | | int32_t new_SRE; |
| | | if (SCPI_ParamInt(context, &new_SRE, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_SRE, new_SRE); |
| | | } |
| | | return SCPI_RES_OK; |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context) { |
| | | scpi_parameter_t parameter; |
| | | if (SCPI_Parameter(context, ¶meter, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_QUESE, SCPI_ParamGetIntVal(context, ¶meter)); |
| | | int32_t new_QUESE; |
| | | if (SCPI_ParamInt(context, &new_QUESE, TRUE)) { |
| | | SCPI_RegSet(context, SCPI_REG_QUESE, new_QUESE); |
| | | } |
| | | |
| | | return SCPI_RES_OK; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | int32_t SCPI_ParamGetIntVal(scpi_t * context, scpi_parameter_t * parameter) { |
| | | scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed) { |
| | | switch (parameter->type) { |
| | | case TokHexnum: |
| | | case TokOctnum: |
| | | case TokBinnum: |
| | | case TokDecimalNumericProgramData: |
| | | case TokDecimalNumericProgramDataWithSuffix: |
| | | return parameter->number.value; |
| | | default: |
| | | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | double SCPI_ParamGetDoubleVal(scpi_t * context, scpi_parameter_t * parameter) { |
| | | return parameter->number.value; |
| | | } |
| | | |
| | | void SCPI_ParamGetTextVal(scpi_t * context, scpi_parameter_t * parameter, const char ** data, int32_t * len) { |
| | | *data = parameter->data.ptr; |
| | | *len = parameter->data.len; |
| | | } |
| | | |
| | | /* SCPI-99 7.3 Boolean Program Data */ |
| | | scpi_bool_t SCPI_ParamGetBoolVal(scpi_t * context, scpi_parameter_t * parameter) { |
| | | switch (parameter->type) { |
| | | case TokDecimalNumericProgramData: |
| | | return parameter->number.value ? 1 : 0; |
| | | case TokProgramMnemonic: |
| | | if (compareStr("ON", 2, parameter->data.ptr, parameter->data.len)) { |
| | | return TRUE; |
| | | } else if (compareStr("OFF", 3, parameter->data.ptr, parameter->data.len)) { |
| | | case TokDecimalNumericProgramDataWithSuffix: |
| | | return suffixAllowed; |
| | | default: |
| | | return FALSE; |
| | | } |
| | | } |
| | | |
| | | scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory) |
| | | { |
| | | scpi_bool_t result; |
| | | scpi_parameter_t param; |
| | | |
| | | if (!value) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | result = SCPI_Parameter(context, ¶m, mandatory); |
| | | if (result) { |
| | | if (SCPI_ParamIsNumber(¶m, FALSE)) { |
| | | *value = param.number.value; |
| | | } else if (SCPI_ParamIsNumber(¶m, TRUE)) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); |
| | | result = FALSE; |
| | | } else { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); |
| | | result = FALSE; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | scpi_bool_t SCPI_ParamInt(scpi_t * context, int32_t * value, scpi_bool_t mandatory) |
| | | { |
| | | // TODO: remove dependency on double |
| | | double tmpVal; |
| | | scpi_bool_t result; |
| | | |
| | | if (!value) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | result = SCPI_ParamDouble(context, &tmpVal, mandatory); |
| | | if (result) { |
| | | *value = tmpVal; |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) |
| | | { |
| | | scpi_bool_t result; |
| | | scpi_parameter_t param; |
| | | |
| | | if (!value || !len) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | result = SCPI_Parameter(context, ¶m, mandatory); |
| | | if (result) { |
| | | *value = param.data.ptr; |
| | | *len = param.data.len; |
| | | |
| | | // TODO: return also parameter type (ProgramMnemonic, ArbitraryBlockProgramData, SingleQuoteProgramData, DoubleQuoteProgramData |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory) |
| | | { |
| | | scpi_bool_t result; |
| | | scpi_parameter_t param; |
| | | |
| | | if (!value) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | result = SCPI_Parameter(context, ¶m, mandatory); |
| | | |
| | | if (result) { |
| | | switch (param.type) { |
| | | case TokDecimalNumericProgramData: |
| | | *value = param.number.value ? 1 : 0; |
| | | break; |
| | | case TokProgramMnemonic: |
| | | if (compareStr("ON", 2, param.data.ptr, param.data.len)) { |
| | | *value = TRUE; |
| | | } else if (compareStr("OFF", 3, param.data.ptr, param.data.len)) { |
| | | *value = FALSE; |
| | | } else { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); |
| | | return FALSE; |
| | | result = FALSE; |
| | | } |
| | | break; |
| | | default: |
| | | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); |
| | | return FALSE; |
| | | result = FALSE; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get choice parameter |
| | | */ |
| | | int32_t SCPI_ParamGetChoiceVal(scpi_t * context, scpi_parameter_t * parameter, const char * options[]) { |
| | | return result; |
| | | } |
| | | |
| | | scpi_bool_t SCPI_ParamChoice(scpi_t * context, const char * options[], int32_t * value, scpi_bool_t mandatory) |
| | | { |
| | | size_t res; |
| | | scpi_bool_t result; |
| | | scpi_parameter_t param; |
| | | |
| | | if (!options) { |
| | | if (!options || !value) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); |
| | | return -1; |
| | | return FALSE; |
| | | } |
| | | |
| | | switch(parameter->type) { |
| | | case TokProgramMnemonic: |
| | | result = SCPI_Parameter(context, ¶m, mandatory); |
| | | if (result) { |
| | | if (param.type == TokProgramMnemonic) { |
| | | for (res = 0; options[res]; ++res) { |
| | | if (matchPattern(options[res], strlen(options[res]), parameter->data.ptr, parameter->data.len)) { |
| | | return res; |
| | | if (matchPattern(options[res], strlen(options[res]), param.data.ptr, param.data.len)) { |
| | | *value = res; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!options[res]) { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); |
| | | return -1; |
| | | default: |
| | | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); |
| | | return -1; |
| | | result = FALSE; |
| | | } |
| | | } else { |
| | | SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); |
| | | result = FALSE; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | int parseProgramData(lex_state_t * state, scpi_token_t * token) { |
| | |
| | | * @param value resultin value |
| | | * @return TRUE if str matches one of specs patterns |
| | | */ |
| | | static scpi_bool_t translateSpecialNumber(const scpi_special_number_def_t * specs, const char * str, size_t len, scpi_number_parameter_t * value) { |
| | | static scpi_bool_t translateSpecialNumber(const scpi_special_number_def_t * specs, const char * str, size_t len, scpi_number_t * value) { |
| | | int i; |
| | | |
| | | value->value = 0.0; |
| | |
| | | * @param value preparsed numeric value |
| | | * @return TRUE if value parameter was converted to base units |
| | | */ |
| | | static scpi_bool_t transformNumber(scpi_t * context, const char * unit, size_t len, scpi_number_parameter_t * value) { |
| | | static scpi_bool_t transformNumber(scpi_t * context, const char * unit, size_t len, scpi_number_t * value) { |
| | | size_t s; |
| | | const scpi_unit_def_t * unitDef; |
| | | s = skipWhitespace(unit, len); |
| | |
| | | * @param mandatory if the parameter is mandatory |
| | | * @return |
| | | */ |
| | | scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter) { |
| | | scpi_bool_t SCPI_ParamNumber(scpi_t * context, scpi_number_t * value, scpi_bool_t mandatory) |
| | | { |
| | | scpi_token_t token; |
| | | lex_state_t state; |
| | | scpi_parameter_t param; |
| | | scpi_bool_t result; |
| | | |
| | | state.buffer = parameter->data.ptr; |
| | | result = SCPI_Parameter(context, ¶m, mandatory); |
| | | |
| | | |
| | | state.buffer = param.data.ptr; |
| | | state.pos = state.buffer; |
| | | state.len = parameter->data.len; |
| | | state.len = param.data.len; |
| | | |
| | | switch(parameter->type) { |
| | | switch(param.type) { |
| | | case TokDecimalNumericProgramData: |
| | | case TokHexnum: |
| | | case TokOctnum: |
| | | case TokBinnum: |
| | | result = TRUE; |
| | | break; |
| | | case TokDecimalNumericProgramDataWithSuffix: |
| | | lexDecimalNumericProgramData(&state, &token); |
| | | lexWhiteSpace(&state, &token); |
| | | lexSuffixProgramData(&state, &token); |
| | | |
| | | return transformNumber(context, token.ptr, token.len, ¶meter->number); |
| | | result = transformNumber(context, token.ptr, token.len, ¶m.number); |
| | | break; |
| | | case TokProgramMnemonic: |
| | | lexWhiteSpace(&state, &token); |
| | | lexCharacterProgramData(&state, &token); |
| | | |
| | | /* convert string to special number type */ |
| | | return translateSpecialNumber(context->special_numbers, token.ptr, token.len, ¶meter->number); |
| | | result = translateSpecialNumber(context->special_numbers, token.ptr, token.len, ¶m.number); |
| | | break; |
| | | default: |
| | | return FALSE; |
| | | result = FALSE; |
| | | } |
| | | |
| | | if (result) { |
| | | memcpy(value, ¶m.number, sizeof(scpi_number_t)); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param len max length of string |
| | | * @return number of chars written to string |
| | | */ |
| | | size_t SCPI_NumberToStr(scpi_t * context, scpi_number_parameter_t * value, char * str, size_t len) { |
| | | size_t SCPI_NumberToStr(scpi_t * context, scpi_number_t * value, char * str, size_t len) { |
| | | const char * type; |
| | | const char * unit; |
| | | size_t result; |