opc.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <stdio.h>
  2. #define SCPI_ARGS_N 0
  3. #include "app/scpi/scpi_handler.h"
  4. #include "app/scpi/commandHandlers/opc.h"
  5. #include "app/nfm/nfm_base.h"
  6. // Refer to:
  7. // [1] SCPI Specification, revision 1999.0
  8. // "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
  9. // [2] Gpib Programming Tutorial, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf)
  10. // Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group
  11. // [3] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
  12. // "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
  13. // Standard Digital Interface for Programmable Instrumentation"
  14. // =================================================================================
  15. // @fsqvbl_CommandHandlerOPC
  16. // State's virtual table
  17. static void fsqe_CommandHandlerOPC( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  18. static void fsql_CommandHandlerOPC( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  19. static const struct fFSeqEntry_t * fsqf_CommandHandlerOPC( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext );
  20. const fFSeqVTable_t fsqvbl_CommandHandlerOPC =
  21. {
  22. .f = fsqf_CommandHandlerOPC,
  23. .enter = fsqe_CommandHandlerOPC,
  24. .leave = fsql_CommandHandlerOPC
  25. };
  26. static void fsqe_CommandHandlerOPC( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  27. {
  28. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  29. SCPI_PARSE_ARGUMENTS( common_ctx ); (void)common_ctx->argsParserStatus; // status is modified
  30. common_ctx->OPC.idx = 0; // reset position
  31. }
  32. static void fsql_CommandHandlerOPC( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  33. {
  34. }
  35. static const struct fFSeqEntry_t * fsqf_CommandHandlerOPC( 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( eScpiStatus_success != common_ctx->argsParserStatus ) // check argument parser status
  47. {
  48. common_ctx->status = eProgramDataArgumentSyntax; // parameter syntax error, caller should generate error message
  49. }
  50. else
  51. if( common_ctx->isQuery )
  52. {
  53. common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading...
  54. (void)nextstate; // stay in this state
  55. }
  56. else
  57. {
  58. // "11.2 Status Byte Register", [1]
  59. // "12.5.2.1.2 Operation Complete Command Active State (OCAS)", [3]
  60. // "4.1.3.3 *OPC and *WAI", [1]
  61. // Implementation of the *OPC and *WAI commands is straightforward in devices which
  62. // implement only sequential commands. When executing *OPC the device simply sets the OPC bit of SESR.
  63. GPIBMachine.fGPIB_set_event_status_register_operation_complete_state( &global_ctx->sGPIB.registers, true );
  64. common_ctx->status = eProgramDataDone; // request processed
  65. }
  66. // Since @done flag is set, this dispatcher shall not be called anymore.
  67. // Since this handler is implemented as a single-state automat, there no
  68. // ... other states to go to:
  69. (void)nextstate;
  70. }
  71. break;
  72. case eProgramData_Event_Read:
  73. {
  74. // first call: prepare buffer
  75. if( 0 == common_ctx->OPC.idx )
  76. {
  77. memset( common_ctx->tempBuffer, 0, sizeof(common_ctx->tempBuffer) );
  78. // "4.1.3.4 *OPC?" [1]
  79. // Implementation of the *OPC? query is straightforward in devices which implement only
  80. // sequential commands. When executing *OPC? the device simply places a “1" in the Output Queue.
  81. // "12.5.3 The *OPC? Common Query", [3]
  82. // The *OPC? query allows synchronization between a controller and a device using the MAV bit in the Status Byte or
  83. // a read of the Output Queue. Detailed illustrations of the use of this function appear in Appendix B. Note that,
  84. // unlike the *OPC command described in 12.5.2, the *OPC? query does not in any way affect the OPC Event bit in the
  85. // Standard Event Status Register (ESR).
  86. // Since there no asyncronious operations are supported, this command immediately generate the response "1"
  87. _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "1" );
  88. }
  89. SCPI_RESPONSE_HELPER( common_ctx, common_ctx->OPC.idx );
  90. (void)nextstate; // stay in this state
  91. }
  92. break;
  93. }
  94. return nextstate;
  95. }