| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #define SCPI_CORE_STATE__HANDLEERROR_GUARD
- #include "app/scpi/CommandParserStates/handle_error.h"
- #define SCPI_CORE_PRIVATE // access to 'scpi_core_private.h'
- #define SCPI_HANDLE_ERROR_C // access to some const variables in 'scpi_core_private.h'
- #include "app/scpi/scpi_core_private.h"
- #include "app/scpi/scpi_errq.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
- //----------------------------------------------------------------
- // Refer "21.8.1 The Error/Event Queue", [1]
- // Refer "8.2.2 System sub-system", [2]
- // =================================================================================
- // @sHandleErrorContext_t
- // State's private context typedef
- typedef struct
- {
- uint8_t lastEventCode;
- }
- sHandleErrorContext_t;
- // =================================================================================
- // @ctx_HandleError
- // State's private context
- sHandleErrorContext_t ctx_HandleError;
- // =================================================================================
- // @fsqvbl_HandleError
- // State's virtual table
- static void fsqe_HandleError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static void fsql_HandleError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static const struct fFSeqEntry_t * fsqf_HandleError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pnext );
- const fFSeqVTable_t fsqvbl_HandleError =
- {
- .f = fsqf_HandleError,
- .enter = fsqe_HandleError,
- .leave = fsql_HandleError
- };
- // =================================================================================
- // @fsqe_HandleError
- // State's enter routine
- static void fsqe_HandleError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- sScpiParserContext_t * global_ctx = ctx;
- sHandleErrorContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- (void)global_ctx, (void)private_ctx;
- private_ctx->lastEventCode = global_ctx->sEvent.eCode;
- if( SCPI_ERROR_STATE != global_ctx->sExecution.runtimeError )
- {
- if( ! errq_push( &global_ctx->sExecution.xScpiErrorQueue,
- global_ctx->sExecution.runtimeError,
- global_ctx->sExecution.xScpiErrorMessage ) )
- {
- // Error Queue Overflow
- global_ctx->sExecution.errorQueueOverflow = true;
- // "21.8.1 The Error/Event Queue", [1]
- // "21.8.11 Device-Specific Error", [1]
- // "11.5.1.1.6 Bit 3 N Device-Specific ERROR (DDE)", [3]
- GPIBMachine.fGPIB_set_event_status_register_device_specific_error_state(
- &global_ctx->sGPIB.registers, true );
- global_ctx->sExecution.runtimeError = SCPI_ERROR_SUCCESS; // clear error code
- global_ctx->sEvent.eStatus = eScpiStatus_success; // clear error status
- }
- else
- {
- // Notify GPIB: error available in the queue
- // "4 Instrument status", [2]
- // "4.1 Status Byte registers (STB and SRE)", [2]
- // "11.2.2.3 Master Summary Status", [4]
- // "11.3.2.4 Clearing the Service Request Enable Register", [3]
- GPIBMachine.fGPIB_set_error_available_bit( &global_ctx->sGPIB.registers, true );
- switch( SCPI_ERROR_CLASS(global_ctx->sExecution.runtimeError) )
- {
- // ------------ Reasons: --------------
- // "6.1.6.1.1 Parser Errors", [3]
- // "6.5.4 Command Error", [3]
- case SCPI_ERROR_CLASS_COMMAND:
- GPIBMachine.fGPIB_set_event_status_register_command_error_state(
- &global_ctx->sGPIB.registers, true );
- break;
- // ------------ Reasons: --------------
- // "6.5.5 Execution Error", [3]
- // "11.5.1.1.5 Bit 4 N Execution ERROR (E)", [3]
- // "<...> the device shall continue parsing the input stream. <...>", [3]
- case SCPI_ERROR_CLASS_EXECUTION:
- GPIBMachine.fGPIB_set_event_status_register_execution_error_state(
- &global_ctx->sGPIB.registers, true );
- // "11.5.1.1.5 Bit 4 N Execution ERROR (E)", [3]
- // "<...> the device shall continue parsing the input stream. <...>", [3]
- global_ctx->sEvent.eCode = eScpiEventContinue; // change event code to continue parsing
- break;
- // "11.5.1.1.6 Bit 3 N Device-Specific ERROR (DDE)", [3]
- case SCPI_ERROR_CLASS_DEVICE:
- GPIBMachine.fGPIB_set_event_status_register_device_specific_error_state(
- &global_ctx->sGPIB.registers, true );
- break;
- // ------------ Reasons: --------------
- // "6.3.1.3 QUERY State", [3]
- // "6.3.1.7 DEADLOCK State", [3]
- // "6.3.2.2 UNTERMINATED Action", [3]
- // "6.3.2.3 INTERRUPTED Action", [3]
- // "6.5.7 Query Error", [3]
- case SCPI_ERROR_CLASS_QUERY:
- GPIBMachine.fGPIB_set_event_status_register_query_error_state(
- &global_ctx->sGPIB.registers, true );
- break;
- }
- global_ctx->sExecution.runtimeError = SCPI_ERROR_SUCCESS; // clear error code
- global_ctx->sEvent.eStatus = eScpiStatus_success; // clear error status
- }
- }
- }
- // =================================================================================
- // @fsql_HandleError
- // State's leave routine
- static void fsql_HandleError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- sScpiParserContext_t * global_ctx = ctx;
- sHandleErrorContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- (void)ctx, (void)private_ctx, (void)global_ctx;
- }
- // =================================================================================
- // @fsqf_HandleError
- // State's body routine
- static const struct fFSeqEntry_t * fsqf_HandleError( const struct fFSeqEntry_t * this,
- tFSeqCtx_t ctx,
- const struct fFSeqEntry_t * * pDeferredNext )
- {
- // --------------------------------------------------------------------------
- const struct fFSeqEntry_t * nextstate = NULL; // do not change state, do not call next state
- sScpiParserContext_t * global_ctx = ctx;
- sHandleErrorContext_t * private_ctx = fsq_GetPrivateCtxRef(this);
- uint8_t nextEvent = eScpiEventEmpty;
- // --------------------------------------------------------------------------
- switch( global_ctx->sEvent.eCode )
- {
- case eScpiEventRestart:
- {
- // go to reset state
- nextstate = fsq_GetStateById(this,eParserResetState);
- }
- break;
- case eScpiEventContinue:
- {
- // Search for the following message unit separator
- // goto next state: eProcessEndOfProgramData
- nextstate = fsq_GetStateById(this,eProcessEndOfProgramData);
- nextEvent = private_ctx->lastEventCode;
- (void)global_ctx->sEvent.eStatus;; // already cleared
- }
- break;
- case eScpiEventError: // transport error
- {
- global_ctx->sEvent.eStatus = eScpiStatus_success;
- (void)nextstate; // keep this state
- }
- break;
- case eScpiEventRead: // read event during Error condition:
- case eScpiEventWrite: // command parse error -> error state
- {
- // Respond with empty string:
- if( global_ctx->sRead.nDataLength == 0 ) // no response in output buffer
- if( global_ctx->sRead.nBufferSize >= 1 ) // there is vacant room in output buffer
- {
- scpi_WriteCharOutput( ' ' );
- // "Query error", "11.5.1.1.7 Bit 2", [3]
- // "An attempt is being made to read data from the Output Queue when no output is either present or pending"
- GPIBMachine.fGPIB_set_event_status_register_query_error_state( &global_ctx->sGPIB.registers, true );
- }
- global_ctx->sEvent.eStatus = eScpiStatus_success;
- global_ctx->sMessage.r_bEndOfMessage = true;
- scpi_UpdateMessageAvailable();
- (void)nextstate; // keep this state
- }
- break;
- }
-
- global_ctx->sEvent.eCode = nextEvent;
- return nextstate;
- }
|