#include #define SCPI_ARGS_N 0 #include "app/scpi/scpi_handler.h" #include "app/scpi/commandHandlers/syst_error.h" #include "app/nfm/nfm_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 //---------------------------------------------------------------- // Refer "21.8.1 The Error/Event Queue", [1] // Refer "8.2.2 System sub-system", [2] // ================================================================================= // @fsqvbl_CommandHandlerSystemError // State's virtual table static void fsqe_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ); static void fsql_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ); static const struct fFSeqEntry_t * fsqf_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext ); const fFSeqVTable_t fsqvbl_CommandHandlerSystemError = { .f = fsqf_CommandHandlerSystemError, .enter = fsqe_CommandHandlerSystemError, .leave = fsql_CommandHandlerSystemError }; static void fsqe_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ) { sProcessProgramDataCommonContext_t * common_ctx = ctx; common_ctx->SYSTemERRor.idx = 0; // reset position common_ctx->SYSTemERRor.error = false; } static void fsql_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx ) { } static const struct fFSeqEntry_t * fsqf_CommandHandlerSystemError( 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; switch( common_ctx->event ) { case eProgramData_Event_Write: { if( ! common_ctx->isQuery ) { common_ctx->status = eProgramDataSyntaxError; // invalid command header type: COMMAND not supported } else { common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading... (void)nextstate; // stay in this state } } break; case eProgramData_Event_Read: { // @idx - current position of the source data to be outputed if( common_ctx->SYSTemERRor.idx == 0 ) // first reading { int16_t scpiError; size_t len = sizeof( global_ctx->sExecution.xScpiErrorMessage ); // Check overflow flag ("21.8.1 The Error/Event Queue", [1], "8.2.2 System sub-system", [2]) if( global_ctx->sExecution.errorQueueOverflow ) { // Form 'Overflow' error without placing it into the queue fsq_RaiseError( SCPI_ERROR_QUEUE_OVERFLOW, SCPI_ERROR_QUEUE_OVERFLOW_MSG, NULL, NULL ); (void)global_ctx->sExecution.xScpiErrorMessage; // use formatted message text global_ctx->sExecution.errorQueueOverflow = false; // reset overflow indicator } else // Note: function @fsq_RaiseError uses the same buffer to place the error message to the log // So it guarantees that any message placed into the log can be extracted to the same buffer: // @global_ctx->sExecution.xScpiErrorMessage if( !errq_isempty(&global_ctx->sExecution.xScpiErrorQueue) && errq_peek( &global_ctx->sExecution.xScpiErrorQueue, &scpiError, &global_ctx->sExecution.xScpiErrorMessage[0], &len) ) { errq_removetop( &global_ctx->sExecution.xScpiErrorQueue ); } else { strcpy( global_ctx->sExecution.xScpiErrorMessage, SCPI_ERROR_NO ); } // check if the error queue is empty if( errq_isempty(&global_ctx->sExecution.xScpiErrorQueue) ) { // clear EAV bit in GPIB GPIBMachine.fGPIB_set_error_available_bit( &global_ctx->sGPIB.registers, false ); } } // 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: SCPI_RESPONSE_HELPER_EX( common_ctx, common_ctx->SYSTemERRor.idx, global_ctx->sExecution.xScpiErrorMessage, sizeof(global_ctx->sExecution.xScpiErrorMessage) ); } break; } return nextstate; }