esr_stb.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. const uint8_t fsqvbl_CommandHandlerESR_context = 1;
  4. const uint8_t fsqvbl_CommandHandlerSTB_context = 2;
  5. #define SCPI_ARGS_N 0
  6. #include "app/scpi/scpi_handler.h"
  7. #include "app/scpi/commandHandlers/esr.h"
  8. #include "app/nfm/nfm_base.h"
  9. // Refer to:
  10. // [1] SCPI Specification, revision 1999.0
  11. // "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
  12. // [2] Gpib Programming Tutorial, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf)
  13. // Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group
  14. // =================================================================================
  15. // @fsqvbl_CommandHandlerESRSTB
  16. // State's virtual table
  17. static void fsqe_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  18. static void fsql_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  19. static const struct fFSeqEntry_t * fsqf_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext );
  20. const fFSeqVTable_t fsqvbl_CommandHandlerESRSTB =
  21. {
  22. .f = fsqf_CommandHandlerESRSTB,
  23. .enter = fsqe_CommandHandlerESRSTB,
  24. .leave = fsql_CommandHandlerESRSTB
  25. };
  26. static void fsqe_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  27. {
  28. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  29. common_ctx->ESRSTB.idx = 0; // reset position
  30. SCPI_PARSE_ARGUMENTS( common_ctx ); (void)common_ctx->argsParserStatus; // status is modified
  31. }
  32. static void fsql_CommandHandlerESRSTB( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  33. {
  34. }
  35. static const struct fFSeqEntry_t * fsqf_CommandHandlerESRSTB( const struct fFSeqEntry_t * this,
  36. tFSeqCtx_t ctx,
  37. const struct fFSeqEntry_t * * pDeferredNext )
  38. {
  39. const fFSeqEntry_t * nextstate = NULL;
  40. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  41. sScpiParserContext_t * global_ctx = common_ctx->global_ctx;
  42. switch( common_ctx->event )
  43. {
  44. case eProgramData_Event_Write:
  45. {
  46. if( ! common_ctx->isQuery )
  47. {
  48. common_ctx->status = eProgramDataSyntaxError; // invalid command header type: COMMAND not supported (only query)
  49. }
  50. else if( eScpiStatus_success != common_ctx->argsParserStatus ) // check argument parser status
  51. {
  52. common_ctx->status = eProgramDataArgumentSyntax; // parameter syntax error, caller should generate error message
  53. }
  54. else
  55. {
  56. common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading...
  57. (void)nextstate; // stay in this state
  58. }
  59. }
  60. break;
  61. case eProgramData_Event_Read:
  62. {
  63. // @idx - current position of the source data to be outputed
  64. if( 0 == common_ctx->ESRSTB.idx )
  65. {
  66. memset( common_ctx->tempBuffer, 0, sizeof(common_ctx->tempBuffer) );
  67. uint8_t esrstb = 0;
  68. if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerESR_context )
  69. {
  70. // Read ESB:
  71. // "11.5.1.2 Standard Event Status Register Operation", [3]
  72. // "<...> The Standard Event Status Register is destructively read (that is, read and cleared) <...>", [3]
  73. // retrieve ESB and clear it
  74. GPIBMachine.fGPIB_get_event_status_register( &global_ctx->sGPIB.registers, &esrstb );
  75. }
  76. if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerSTB_context )
  77. {
  78. // It is required to call 'scpi_UpdateMessageAvailable' here due to the following reason:
  79. // The MAV bit is set automatically by SCPI core after this handler returns 'eProgramDataNeedRead'
  80. // above on 'Write' event in advance even there no data in the output buffer. So after the handler is
  81. // called the SCPI core updates this bit again, and if the EOM is set, the MAV bit will be reset.
  82. // But here, during the handler call, this bit is set ever for this command handler, so, it is required
  83. // to update the MAV bit value: only set if any data is already pushed into the output buffer by the
  84. // previous handler, and reset otherwise. If it is not done, the *STB? command will return this
  85. // bit as 1 each call whenever is there data in the buffer or not.
  86. scpi_UpdateMessageAvailable();
  87. // Read STB
  88. // "11.2.2.1 Reading with a Serial Poll", [3]
  89. // "11.2.2.2 Reading With the *STB? Query", [3]
  90. GPIBMachine.fGPIB_get_status_byte_normal_poll( &global_ctx->sGPIB.registers, &esrstb );
  91. }
  92. int iesrstb = (int)esrstb;
  93. // first call: prepare buffer
  94. _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "%d", iesrstb );
  95. }
  96. // Since @done flag is set, this dispatcher shall not be called anymore.
  97. // Since this handler is implemented as a single-state automat, there no
  98. // ... other states to go to:
  99. (void)nextstate;
  100. // modify current postion index:
  101. SCPI_RESPONSE_HELPER( common_ctx, common_ctx->ESRSTB.idx );
  102. }
  103. break;
  104. }
  105. return nextstate;
  106. }