trigger_state.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include <stdio.h>
  2. #define SCPI_ARGS_N_Q 0
  3. #define SCPI_ARGS_N_C 1
  4. #include "app/scpi/scpi_handler.h"
  5. #include "app/control_table/control_table.h"
  6. const uint8_t fsqvbl_CommandHandlerTriggerPolarity = 1; // TRIGger:POLARity
  7. const uint8_t fsqvbl_CommandHandlerTriggerCounter = 2; // TRIGger:COUNTer
  8. // -----
  9. // @argTokens, @argTypes
  10. // Declare argument parser entities
  11. // Supported arguments: 1=CHARACTER
  12. DECLARE_SCPI_ARGS_C( eScpiArg_Character );
  13. // Argument 1 Character Values allowed list / ACM Switch State
  14. DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST_EXPORT( MemTable_AllowedValues_TriggerState,
  15. "POSitive",
  16. "NEGative"
  17. );
  18. #include "app/nfm/nfm_base.h"
  19. // Refer to:
  20. // [1] SCPI Specification, revision 1999.0
  21. // "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
  22. // [2] Gpib Programming Tutorial, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf)
  23. // Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group
  24. // [3] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
  25. // "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
  26. // =================================================================================
  27. // @fsqvbl_CommandHandlerSwitchState
  28. // State's virtual table
  29. static void fsqe_CommandHandlerTriggerState( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  30. static void fsql_CommandHandlerTriggerState( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx );
  31. static const struct fFSeqEntry_t * fsqf_CommandHandlerTriggerState( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx, const struct fFSeqEntry_t * * pDeferredNext );
  32. const fFSeqVTable_t fsqvbl_CommandHandlerTRIGgerSTATe_group =
  33. {
  34. .f = fsqf_CommandHandlerTriggerState,
  35. .enter = fsqe_CommandHandlerTriggerState,
  36. .leave = fsql_CommandHandlerTriggerState
  37. };
  38. static void fsqe_CommandHandlerTriggerState( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  39. {
  40. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  41. SCPI_PARSE_ARGUMENTS( common_ctx ); (void)common_ctx->argsParserStatus; // status is modified
  42. common_ctx->SwitchState.idx = 0;
  43. common_ctx->SwitchState.state = 0;
  44. }
  45. static void fsql_CommandHandlerTriggerState( const struct fFSeqEntry_t * this, tFSeqCtx_t ctx )
  46. {
  47. }
  48. static const struct fFSeqEntry_t * fsqf_CommandHandlerTriggerState( const struct fFSeqEntry_t * this,
  49. tFSeqCtx_t ctx,
  50. const struct fFSeqEntry_t * * pDeferredNext )
  51. {
  52. const fFSeqEntry_t * nextstate = NULL;
  53. sProcessProgramDataCommonContext_t * common_ctx = ctx;
  54. sScpiParserContext_t * global_ctx = common_ctx->global_ctx;
  55. switch( common_ctx->event )
  56. {
  57. case eProgramData_Event_Write:
  58. {
  59. if( eScpiStatus_success != common_ctx->argsParserStatus ) // check argument parser status
  60. {
  61. common_ctx->status = eProgramDataArgumentSyntax; // parameter syntax error, caller should generate error message
  62. }
  63. else if( ! common_ctx->isQuery )
  64. {
  65. common_ctx->status = eProgramDataIllegalArgument; // forward set, illegal parameter value, caller should generate error message
  66. if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerTriggerPolarity )
  67. {
  68. // process first argument (switch state)
  69. common_ctx->SwitchState.state = SCPI_PROCESS_ARGUMENT_CHARACTER( common_ctx, MemTable_AllowedValues_TriggerState, 0);
  70. }
  71. // check result
  72. if( SCPI_ARGUMENT_CHARACTER_INVALID_ID == common_ctx->SwitchState.state )
  73. {
  74. (void)common_ctx->status; // eProgramDataIllegalArgument
  75. }
  76. else
  77. {
  78. size_t error = 0;
  79. if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerTriggerPolarity )
  80. {
  81. if( common_ctx->SwitchState.state == eTrigState_Rising || common_ctx->SwitchState.state == eTrigState_Falling )
  82. {
  83. ControlHandle.TriggerPolaritySet(common_ctx->SwitchState.state);
  84. }
  85. else
  86. {
  87. error = 1; // Trigger state Syntax Error
  88. }
  89. }
  90. switch( error )
  91. {
  92. case 1: // Trigger state Syntax Error
  93. {
  94. (void)common_ctx->status; // eProgramDataIllegalArgument
  95. }
  96. break;
  97. // case 2: // Trigger State unavailable in this device
  98. // {
  99. // (void)common_ctx->status; // eProgramDataIllegalArgument
  100. // }
  101. // break;
  102. }
  103. if( 0 != error ) break;
  104. common_ctx->status = eProgramDataDone; // request processed, wait for reading...
  105. }
  106. }
  107. else
  108. {
  109. common_ctx->status = eProgramDataNeedRead; // request processed, wait for reading...
  110. }
  111. }
  112. break;
  113. case eProgramData_Event_Read:
  114. {
  115. // @idx - current position of the source data to be outputed
  116. if( common_ctx->SwitchState.idx == 0 ) // first reading
  117. {
  118. size_t length = 0;
  119. if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerTriggerPolarity )
  120. {
  121. uint8_t triggerPolarity = ControlHandle.TriggerPolarityGet();
  122. length = _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "%s", triggerPolarity ? "NEGative\n" : "POSitive\n");
  123. }
  124. else if( common_ctx->handler_ctx == &fsqvbl_CommandHandlerTriggerCounter )
  125. {
  126. uint8_t triggerCount = ControlHandle.TriggerCounterGet();
  127. length = _snprintf( common_ctx->tempBuffer, sizeof(common_ctx->tempBuffer), "%d", triggerCount);
  128. }
  129. if( length == 0 )
  130. {
  131. fsq_RaiseError( SCPI_ERROR_INTERNAL_DEVICE,
  132. SCPI_ERROR_INTERNAL_DEVICE_MSG,
  133. global_ctx->sParser.xHandlerToken.shead,
  134. global_ctx->sParser.xHandlerToken.stail );
  135. common_ctx->status = eProgramData_SpecificError; // specific error already generated
  136. break;
  137. }
  138. else
  139. {
  140. // place null-terminator in the end of line
  141. common_ctx->tempBuffer[length] = '\0';
  142. }
  143. }
  144. // Since @done flag is set, this dispatcher shall not be called anymore.
  145. // Since this handler is implemented as a single-state automat, there no
  146. // ... other states to go to:
  147. (void)nextstate;
  148. // modify current postion index:
  149. SCPI_RESPONSE_HELPER( common_ctx, common_ctx->SwitchState.idx );
  150. }
  151. break;
  152. }
  153. return nextstate;
  154. }