syst_error.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include <stdio.h>
  2. #define SCPI_ARGS_N 0
  3. #include "app/scpi/scpi_handler.h"
  4. #include "app/scpi/commandHandlers/syst_error.h"
  5. #include "app/nfm/nfm_base.h"
  6. //----------------------------------------------------------------
  7. // Refer to:
  8. // [1] SCPI Specification, revision 1999.0
  9. // "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
  10. // [2] Gpib Programming Tutorial, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf)
  11. // Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group
  12. //----------------------------------------------------------------
  13. // Refer "21.8.1 The Error/Event Queue", [1]
  14. // Refer "8.2.2 System sub-system", [2]
  15. // =================================================================================
  16. // @fsqvbl_CommandHandlerSystemError
  17. // State's virtual table
  18. static void fsqe_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  19. static void fsql_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  20. static const struct fFSeqEntry_t * fsqf_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext );
  21. const fFSeqVTable_t fsqvbl_CommandHandlerSystemError =
  22. {
  23. .f = fsqf_CommandHandlerSystemError,
  24. .enter = fsqe_CommandHandlerSystemError,
  25. .leave = fsql_CommandHandlerSystemError
  26. };
  27. static void fsqe_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  28. {
  29. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  30. common_ctx->SYSTemERRor.idx = 0; // reset position
  31. common_ctx->SYSTemERRor.error = false;
  32. }
  33. static void fsql_CommandHandlerSystemError( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  34. {
  35. }
  36. static const struct fFSeqEntry_t * fsqf_CommandHandlerSystemError( const struct fFSeqEntry_t * this,
  37. tFSeqCtx_t ctx,
  38. const struct fFSeqEntry_t * * pDeferredNext )
  39. {
  40. const fFSeqEntry_t * nextstate = NULL;
  41. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  42. sScpiParserContext_t * global_ctx = common_ctx->global_ctx;
  43. switch( common_ctx->event )
  44. {
  45. case eProgramData_Event_Write:
  46. {
  47. if( ! common_ctx->isQuery )
  48. {
  49. common_ctx->status = eProgramDataSyntaxError; // invalid command header type: COMMAND not supported
  50. }
  51. else
  52. {
  53. common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading...
  54. (void)nextstate; // stay in this state
  55. }
  56. }
  57. break;
  58. case eProgramData_Event_Read:
  59. {
  60. // @idx - current position of the source data to be outputed
  61. if( common_ctx->SYSTemERRor.idx == 0 ) // first reading
  62. {
  63. int16_t scpiError;
  64. size_t len = sizeof( global_ctx->sExecution.xScpiErrorMessage );
  65. // Check overflow flag ("21.8.1 The Error/Event Queue", [1], "8.2.2 System sub-system", [2])
  66. if( global_ctx->sExecution.errorQueueOverflow )
  67. {
  68. // Form 'Overflow' error without placing it into the queue
  69. fsq_RaiseError( SCPI_ERROR_QUEUE_OVERFLOW,
  70. SCPI_ERROR_QUEUE_OVERFLOW_MSG,
  71. NULL, NULL );
  72. (void)global_ctx->sExecution.xScpiErrorMessage; // use formatted message text
  73. global_ctx->sExecution.errorQueueOverflow = false; // reset overflow indicator
  74. }
  75. else
  76. // Note: function @fsq_RaiseError uses the same buffer to place the error message to the log
  77. // So it guarantees that any message placed into the log can be extracted to the same buffer:
  78. // @global_ctx->sExecution.xScpiErrorMessage
  79. if( !errq_isempty(&global_ctx->sExecution.xScpiErrorQueue)
  80. && errq_peek( &global_ctx->sExecution.xScpiErrorQueue,
  81. &scpiError,
  82. &global_ctx->sExecution.xScpiErrorMessage[0],
  83. &len) )
  84. {
  85. errq_removetop( &global_ctx->sExecution.xScpiErrorQueue );
  86. }
  87. else
  88. {
  89. strcpy( global_ctx->sExecution.xScpiErrorMessage,
  90. SCPI_ERROR_NO );
  91. }
  92. // check if the error queue is empty
  93. if( errq_isempty(&global_ctx->sExecution.xScpiErrorQueue) )
  94. {
  95. // clear EAV bit in GPIB
  96. GPIBMachine.fGPIB_set_error_available_bit( &global_ctx->sGPIB.registers, false );
  97. }
  98. }
  99. // Since @done flag is set, this dispatcher shall not be called anymore.
  100. // Since this handler is implemented as a single-state automat, there no
  101. // ... other states to go to:
  102. (void)nextstate;
  103. // modify current postion index:
  104. SCPI_RESPONSE_HELPER_EX( common_ctx, common_ctx->SYSTemERRor.idx, global_ctx->sExecution.xScpiErrorMessage, sizeof(global_ctx->sExecution.xScpiErrorMessage) );
  105. }
  106. break;
  107. }
  108. return nextstate;
  109. }