#error Deprecated. 'ese_sre' is used instead #include #define SCPI_ARGS_N_C 1 #define SCPI_ARGS_N_Q 0 #include "app/scpi/scpi_handler.h" // ----- // @argTypesCommand // Declare argument parser entities for command form // Supported arguments: 1=NUMERIC DECLARE_SCPI_ARGS_C( eScpiArg_Numeric ); // ----- // @argTypesQuery // Declare argument parser entities for query form // Supported arguments: 0 DECLARE_SCPI_ARGS_Q(); DECLARE_ARGUMENT_NUMERIC_VALUES_I8(AllowedValues_Argument1, 0, 255); #include "app/scpi/commandHandlers/ese.h" #include "app/acm/acm_base.h" // Refer to: // [1] SCPI Specification, revision 1999.0 // "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999" // [2] Gpib Programming Tutorial, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf) // Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group // [3] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992) // "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE // ================================================================================= // @fsqvbl_CommandHandlerESE // State's virtual table static void fsqe_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ); static void fsql_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ); static const struct fFSeqEntry_t * fsqf_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext ); const fFSeqVTable_t fsqvbl_CommandHandlerESE = { .f = fsqf_CommandHandlerESE, .enter = fsqe_CommandHandlerESE, .leave = fsql_CommandHandlerESE }; static void fsqe_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ) { sProcessProgramDataCommonContext_t * common_ctx = ctx; sScpiParserContext_t * global_ctx = common_ctx->global_ctx; common_ctx->ESE.idx = 0; // reset position SCPI_PARSE_ARGUMENTS( common_ctx ); (void)common_ctx->argsParserStatus; // status is modified (void)global_ctx; } static void fsql_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ) { sProcessProgramDataCommonContext_t * common_ctx = ctx; sScpiParserContext_t * global_ctx = common_ctx->global_ctx; (void)common_ctx; (void)global_ctx; } static const struct fFSeqEntry_t * fsqf_CommandHandlerESE( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext ) { const fFSeqEntry_t * nextstate = NULL; sProcessProgramDataCommonContext_t * common_ctx = ctx; sScpiParserContext_t * global_ctx = common_ctx->global_ctx; (void)common_ctx; (void)global_ctx; switch( common_ctx->event ) { case eProgramData_Event_Write: { if( eScpiStatus_success != common_ctx->argsParserStatus ) // check argument parser status { common_ctx->status = eProgramDataArgumentSyntax; // parameter syntax error, caller should generate error message } else if( ! common_ctx->isQuery ) { common_ctx->status = eProgramDataSyntaxError; // forward set const sNumericEntry_t * ne = SCPI_PROCESS_ARGUMENT_NUMERIC(common_ctx, &AllowedValues_Argument1, 0); assert( ne ); switch( ne->error ) { case ScpiNumericSuccess: { GPIBMachine.fGPIB_set_event_status_enable_register( &global_ctx->sGPIB.registers, (uint8_t)ne->Value.i ); common_ctx->status = eProgramDataDone; } break; // -------- processed by SCPI_PROCESS_ARGUMENT_NUMERIC ---- // "11.5.1.1.5", [3] // "10.10.6 Error Handling", [3] // "<...> An out-of-range integer shall cause an Execution Error, see 11.5.1.1.5. <...>" case ScpiNumericError_DEVICE_RANGE: // the value is out of range supported by device case ScpiNumericError_USER_RANGE: // the value is out of user specified range: // the value is out of range supported by device case ScpiNumericError_USER_TYPE: // the value does not match to the user expectation case ScpiNumericInvalidArg: // forbidden case: design bug case ScpiNumericError: // generic numeric conversion error break; // -------------------------------------------------------- } } else { common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading... (void)nextstate; // stay in this state } } break; case eProgramData_Event_Read: { // Take the input buffer by @pBuffer and @nBufferLength // @dst = @pBuffer, output response buffer // @bsize = @nBufferLength, output buffer size uint8_t * dst = (uint8_t*)global_ctx->sRead.pBufferIdx; size_t bsize = global_ctx->sRead.nBufferSize; // @idx - current position of the source data to be outputed size_t idx = common_ctx->ESE.idx; if( 0 == idx ) { memset( common_ctx->tempBuffer, 0, sizeof(common_ctx->tempBuffer) ); uint8_t ESE = 0; // Read ESB: // "11.5.1.2 Standard Event Status Register Operation", [3] // "<...> The Standard Event Status Register is destructively read (that is, read and cleared) <...>", [3] // retrieve ESB and clear it GPIBMachine.fGPIB_get_event_status_enable_register( &global_ctx->sGPIB.registers, &ESE ); int iESE = (int)ESE; // first call: prepare buffer _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "%d", iESE ); } // @ESE_str - response string const char * ESE_str = common_ctx->tempBuffer; // Copy response string char by char to the output buffer // ... until the null-character is reached or the output // ... buffer free space is ran out: while( ('\0' != ESE_str[idx]) && ( 0sRead.nDataLength += global_ctx->sRead.nBufferSize - bsize; // Check for end-condition: if( '\0' == ESE_str[idx] ) { common_ctx->status = eProgramDataDone; } // Since @done flag is set, this dispatcher shall not be called anymore. // Since this handler is implemented as a single-state automat, there no // ... other states to go to: (void)nextstate; // modify current postion index: common_ctx->ESE.idx = idx; } break; } return nextstate; }