| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include <stdio.h>
- #include <stdint.h>
- const uint8_t fsqvbl_CommandHandlerESR_context = 1;
- const uint8_t fsqvbl_CommandHandlerSTB_context = 2;
- #define SCPI_ARGS_N 0
- #include "app/scpi/scpi_handler.h"
- #include "app/scpi/commandHandlers/esr.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
- // =================================================================================
- // @fsqvbl_CommandHandlerESRSTB
- // State's virtual table
- static void fsqe_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static void fsql_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
- static const struct fFSeqEntry_t * fsqf_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext );
- const fFSeqVTable_t fsqvbl_CommandHandlerESRSTB =
- {
- .f = fsqf_CommandHandlerESRSTB,
- .enter = fsqe_CommandHandlerESRSTB,
- .leave = fsql_CommandHandlerESRSTB
- };
- static void fsqe_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- sProcessProgramDataCommonContext_t * common_ctx = ctx;
- common_ctx->ESRSTB.idx = 0; // reset position
-
- SCPI_PARSE_ARGUMENTS( common_ctx ); (void)common_ctx->argsParserStatus; // status is modified
- }
- static void fsql_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
- {
- }
- static const struct fFSeqEntry_t * fsqf_CommandHandlerESRSTB( 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 (only query)
- }
- else if( eScpiStatus_success != common_ctx->argsParserStatus ) // check argument parser status
- {
- common_ctx->status = eProgramDataArgumentSyntax; // parameter syntax error, caller should generate error message
- }
- 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( 0 == common_ctx->ESRSTB.idx )
- {
- memset( common_ctx->tempBuffer, 0, sizeof(common_ctx->tempBuffer) );
- uint8_t esrstb = 0;
-
- if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerESR_context )
- {
- // 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_register( &global_ctx->sGPIB.registers, &esrstb );
- }
- if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerSTB_context )
- {
- // It is required to call 'scpi_UpdateMessageAvailable' here due to the following reason:
- // The MAV bit is set automatically by SCPI core after this handler returns 'eProgramDataNeedRead'
- // above on 'Write' event in advance even there no data in the output buffer. So after the handler is
- // called the SCPI core updates this bit again, and if the EOM is set, the MAV bit will be reset.
- // But here, during the handler call, this bit is set ever for this command handler, so, it is required
- // to update the MAV bit value: only set if any data is already pushed into the output buffer by the
- // previous handler, and reset otherwise. If it is not done, the *STB? command will return this
- // bit as 1 each call whenever is there data in the buffer or not.
- scpi_UpdateMessageAvailable();
- // Read STB
- // "11.2.2.1 Reading with a Serial Poll", [3]
- // "11.2.2.2 Reading With the *STB? Query", [3]
- GPIBMachine.fGPIB_get_status_byte_normal_poll( &global_ctx->sGPIB.registers, &esrstb );
- }
- int iesrstb = (int)esrstb;
- // first call: prepare buffer
- _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "%d", iesrstb );
- }
- // 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( common_ctx, common_ctx->ESRSTB.idx );
- }
- break;
- }
- return nextstate;
- }
|