Atm_controller.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "Atm_controller.hpp"
  2. const char Atm_controller::relOps[8] = "0=!<>-+";
  3. Atm_controller& Atm_controller::begin( bool initialState /* = false */ ) {
  4. // clang-format off
  5. const static state_t state_table[] PROGMEM = {
  6. /* ON_ENTER ON_LOOP ON_EXIT EVT_ON EVT_OFF EVT_INPUT ELSE */
  7. /* OFF */ ENT_OFF, -1, -1, ON, -1, OFF, -1,
  8. /* ON */ ENT_ON, -1, -1, -1, OFF, ON, -1,
  9. };
  10. // clang-format on
  11. Machine::begin( state_table, ELSE );
  12. last_state = -1;
  13. state( initialState ? ON : OFF );
  14. indicator = -1;
  15. return *this;
  16. }
  17. int Atm_controller::event( int id ) {
  18. switch ( id ) {
  19. case EVT_ON:
  20. return eval_all();
  21. case EVT_OFF:
  22. return !eval_all();
  23. }
  24. return 0;
  25. }
  26. void Atm_controller::action( int id ) {
  27. switch ( id ) {
  28. case ENT_OFF:
  29. connector[last_state == current ? ON_INPUT_FALSE : ON_CHANGE_FALSE].push( state() );
  30. if ( indicator > -1 ) digitalWrite( indicator, !LOW != !indicatorActiveLow );
  31. last_state = current;
  32. return;
  33. case ENT_ON:
  34. if ( last_state != -1 ) connector[( last_state == current ) ? ON_INPUT_TRUE : ON_CHANGE_TRUE].push( state() );
  35. if ( indicator > -1 ) digitalWrite( indicator, !HIGH != !indicatorActiveLow );
  36. last_state = current;
  37. return;
  38. }
  39. }
  40. bool Atm_controller::eval_one( atm_connector& connector ) {
  41. switch ( connector.relOp() ) {
  42. case atm_connector::REL_EQ:
  43. return connector.pull() == connector.event;
  44. case atm_connector::REL_NEQ:
  45. return connector.pull() != connector.event;
  46. case atm_connector::REL_LT:
  47. return connector.pull() < connector.event;
  48. case atm_connector::REL_GT:
  49. return connector.pull() > connector.event;
  50. case atm_connector::REL_LTE:
  51. return connector.pull() <= connector.event;
  52. case atm_connector::REL_GTE:
  53. return connector.pull() >= connector.event;
  54. }
  55. return connector.pull();
  56. }
  57. bool Atm_controller::eval_all() {
  58. bool r = eval_one( operand[0] );
  59. for ( uint8_t i = 1; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
  60. if ( operand[i].mode() ) {
  61. switch ( operand[i].logOp() ) {
  62. case atm_connector::LOG_AND:
  63. r = r && eval_one( operand[i] );
  64. break;
  65. case atm_connector::LOG_OR:
  66. r = r || eval_one( operand[i] );
  67. break;
  68. case atm_connector::LOG_XOR:
  69. r = !r != !eval_one( operand[i] );
  70. break;
  71. }
  72. }
  73. }
  74. return r;
  75. }
  76. Atm_controller& Atm_controller::led( int led, bool activeLow /* = false */ ) {
  77. indicator = led;
  78. indicatorActiveLow = activeLow;
  79. pinMode( indicator, OUTPUT );
  80. return *this;
  81. }
  82. Atm_controller& Atm_controller::onChange( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  83. connector[status ? ON_CHANGE_TRUE : ON_CHANGE_FALSE].set( callback, idx );
  84. return *this;
  85. }
  86. Atm_controller& Atm_controller::onChange( bool status, Machine& machine, int event /* = 0 */ ) {
  87. connector[status ? ON_CHANGE_TRUE : ON_CHANGE_FALSE].set( &machine, event );
  88. return *this;
  89. }
  90. Atm_controller& Atm_controller::onChange( atm_cb_push_t callback, int idx /* = 0 */ ) {
  91. connector[ON_CHANGE_TRUE].set( callback, idx );
  92. connector[ON_CHANGE_FALSE].set( callback, idx );
  93. return *this;
  94. }
  95. Atm_controller& Atm_controller::onChange( Machine& machine, int event /* = 0 */ ) {
  96. connector[ON_CHANGE_TRUE].set( &machine, event );
  97. connector[ON_CHANGE_FALSE].set( &machine, event );
  98. return *this;
  99. }
  100. Atm_controller& Atm_controller::onInput( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  101. connector[status ? ON_INPUT_TRUE : ON_INPUT_FALSE].set( callback, idx );
  102. return *this;
  103. }
  104. Atm_controller& Atm_controller::onInput( bool status, Machine& machine, int event /* = 0 */ ) {
  105. connector[status ? ON_INPUT_TRUE : ON_INPUT_FALSE].set( &machine, event );
  106. return *this;
  107. }
  108. Atm_controller& Atm_controller::IF( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  109. return OP( atm_connector::LOG_AND, machine, relOp, match );
  110. }
  111. Atm_controller& Atm_controller::IF( atm_cb_pull_t callback, int idx /* = 0 */ ) {
  112. return OP( atm_connector::LOG_AND, callback, idx );
  113. }
  114. Atm_controller& Atm_controller::AND( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  115. return OP( atm_connector::LOG_AND, machine, relOp, match );
  116. }
  117. Atm_controller& Atm_controller::AND( atm_cb_pull_t callback, int idx /* = 0 */ ) {
  118. return OP( atm_connector::LOG_AND, callback, idx );
  119. }
  120. Atm_controller& Atm_controller::OR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  121. return OP( atm_connector::LOG_OR, machine, relOp, match );
  122. }
  123. Atm_controller& Atm_controller::OR( atm_cb_pull_t callback, int idx /* = 0 */ ) {
  124. return OP( atm_connector::LOG_OR, callback, idx );
  125. }
  126. Atm_controller& Atm_controller::XOR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  127. return OP( atm_connector::LOG_XOR, machine, relOp, match );
  128. }
  129. Atm_controller& Atm_controller::XOR( atm_cb_pull_t callback, int idx /* = 0 */ ) {
  130. return OP( atm_connector::LOG_XOR, callback, idx );
  131. }
  132. Atm_controller& Atm_controller::OP( char logOp, Machine& machine, char relOp, int match ) {
  133. for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
  134. if ( operand[i].mode() == atm_connector::MODE_NULL ) { // Pick the first free slot
  135. operand[i].set( &machine, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
  136. break;
  137. }
  138. }
  139. return *this;
  140. }
  141. Atm_controller& Atm_controller::OP( char logOp, atm_cb_pull_t callback, int idx ) {
  142. for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
  143. if ( operand[i].mode() == atm_connector::MODE_NULL ) { // Pick the first free slot
  144. operand[i].set( callback, idx );
  145. break;
  146. }
  147. }
  148. return *this;
  149. }
  150. Atm_controller& Atm_controller::trace( Stream& stream ) {
  151. Machine::setTrace( &stream, atm_serial_debug::trace, "CONTROLLER\0EVT_ON\0EVT_OFF\0EVT_INPUT\0ELSE\0OFF\0ON" );
  152. return *this;
  153. }