aboutsummaryrefslogtreecommitdiffstats
path: root/test/monniaux/tacle-bench-lift/liftlibcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/monniaux/tacle-bench-lift/liftlibcontrol.c')
-rw-r--r--test/monniaux/tacle-bench-lift/liftlibcontrol.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/test/monniaux/tacle-bench-lift/liftlibcontrol.c b/test/monniaux/tacle-bench-lift/liftlibcontrol.c
new file mode 100644
index 00000000..5e491276
--- /dev/null
+++ b/test/monniaux/tacle-bench-lift/liftlibcontrol.c
@@ -0,0 +1,277 @@
+#include "liftlibio.h"
+#include "liftlibcontrol.h"
+
+/* Global variables */
+int lift_levelPos[16];
+int lift_one_level;
+
+/**
+ Is the counter valid for level positioning?
+*/
+int lift_cntValid;
+
+/**
+ Position absolute or relative<.
+*/
+int lift_cnt;
+
+/**
+ Last stoped level (1..13) if position is absolute else 0.
+*/
+int lift_level;
+
+/**
+ load position in level, 0 means we don't know
+*/
+int lift_loadLevel;
+
+/**
+ we're going TOP or BOTTOM, but stop at load position.
+*/
+int lift_loadPending;
+
+/**
+ we're waiting for the load sensor to go.
+*/
+int lift_loadSensor;
+
+/**
+ cmd keeps the value of the command until the command is finished.
+ It is only updated by the switches if it's current value is CMD_NONE.
+*/
+int lift_cmd;
+
+int lift_timMotor;
+
+int lift_timImp;
+
+/**
+ Remember last direction for impuls count after motor off;
+*/
+int lift_directionUp;
+
+/**
+ Last value of impuls sensor.
+*/
+int lift_lastImp;
+
+int lift_dbgCnt;
+
+/**
+ stop value for the counter.
+*/
+int lift_endCnt;
+
+
+void lift_ctrl_init()
+{
+ int i;
+ lift_checksum = 0;
+
+ lift_io_init();
+ lift_cntValid = 0;
+ lift_cnt = 0;
+ lift_cmd = lift_CMD_NONE;
+ lift_timMotor = 0;
+ lift_timImp = 0;
+ lift_directionUp = 1;
+ lift_lastImp = 0;
+ lift_loadLevel = 0;
+ lift_loadPending = 0;
+ lift_loadSensor = 0;
+ i = 0;
+ lift_levelPos[i++] = 0;
+ lift_levelPos[i++] = 58;
+ lift_levelPos[i++] = 115;
+ lift_levelPos[i++] = 173;
+ lift_levelPos[i++] = 230;
+ lift_levelPos[i++] = 288;
+ lift_levelPos[i++] = 346;
+ lift_levelPos[i++] = 403;
+ lift_levelPos[i++] = 461;
+ lift_levelPos[i++] = 518;
+ lift_levelPos[i++] = 576;
+ lift_levelPos[i++] = 634;
+ lift_levelPos[i++] = 691;
+ lift_levelPos[i++] = 749;
+ lift_levelPos[i++] = 806;
+ lift_levelPos[i++] = 864;
+ lift_one_level = lift_levelPos[1];
+}
+
+void lift_ctrl_loop()
+{
+ if ( lift_cmd == lift_CMD_NONE )
+ lift_check_cmd();
+ else {
+ lift_do_impulse( lift_ctrl_io_in[lift_SENS_IMPULS],
+ lift_ctrl_io_out[lift_MOTOR_ON],
+ lift_ctrl_io_in[lift_SENS_BOTTOM] );
+ lift_do_cmd();
+ }
+ lift_check_level();
+ lift_ctrl_io_led[13] = ( lift_dbgCnt & 0x80 ) != 0;
+ ++lift_dbgCnt;
+}
+
+
+void lift_check_level()
+{
+ int i;
+ int middle = lift_one_level >> 2;
+ if ( lift_cntValid ) {
+ _Pragma( "loopbound min 14 max 14" )
+ for ( lift_level = 1; lift_level < 14; ++lift_level ) {
+ if ( lift_cnt < lift_levelPos[lift_level] - middle )
+ break;
+ }
+ } else
+ lift_level = 0;
+ _Pragma( "loopbound min 14 max 14" )
+ for ( i = 0; i < 14; ++i )
+ lift_ctrl_io_led[i] = ( i == lift_level - 1 );
+}
+
+
+void lift_check_cmd()
+{
+ if ( lift_loadPending ) {
+ if ( lift_ctrl_io_in[lift_SENS_BOTTOM] )
+ lift_cmd = lift_CMD_TOP;
+ } else
+ if ( lift_ctrl_io_in[lift_GO_UP] ) {
+ if ( !lift_ctrl_io_in[lift_SENS_TOP] && lift_level != 14 )
+ lift_cmd = lift_CMD_UP;
+ } else
+ if ( lift_ctrl_io_in[lift_GO_DOWN] ) {
+ if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] && lift_level != 1 )
+ lift_cmd = lift_CMD_DOWN;
+ } else
+ if ( lift_ctrl_io_in[lift_GO_LOAD] ) {
+ if ( lift_loadLevel != 0 && lift_level < lift_loadLevel )
+ lift_cmd = lift_CMD_TOP;
+ else
+ lift_cmd = lift_CMD_BOTTOM;
+ lift_loadPending = 1;
+ lift_loadSensor = 0;
+ } else
+ if ( lift_ctrl_io_in[lift_GO_TOP] ) {
+ if ( !lift_ctrl_io_in[lift_SENS_TOP] )
+ lift_cmd = lift_CMD_TOP;
+ } else
+ if ( lift_ctrl_io_in[lift_GO_BOTTOM] ) {
+ if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] )
+ lift_cmd = lift_CMD_BOTTOM;
+ }
+ if ( lift_cmd != lift_CMD_NONE )
+ lift_timMotor = 50;
+}
+
+
+void lift_do_impulse( int val, int motor, int reset )
+{
+ if ( val && !lift_lastImp ) {
+ if ( motor || lift_timImp > 0 ) {
+ if ( lift_directionUp )
+ ++lift_cnt;
+ else
+ --lift_cnt;
+ }
+ }
+ if ( reset ) {
+ lift_cnt = 0;
+ lift_cntValid = 1;
+ }
+ lift_lastImp = val;
+ if ( lift_timImp > 0 ) {
+ --lift_timImp;
+ if ( lift_timImp == 0 && lift_cmd != lift_CMD_NONE )
+ lift_cmd = lift_CMD_NONE;
+ }
+}
+
+
+void lift_do_cmd()
+{
+ int run = 0;
+ if ( lift_timMotor > 0 )
+ lift_wait_for_motor_start();
+ else {
+ run = lift_check_run();
+ if ( lift_ctrl_io_out[lift_MOTOR_ON] && !run ) {
+ /* motor stopped: */
+ lift_cmd = 99;
+ lift_timImp = 50;
+ }
+ lift_ctrl_io_out[lift_MOTOR_ON] = run;
+ }
+}
+
+
+void lift_wait_for_motor_start()
+{
+ int newLevel = 0;
+ --lift_timMotor;
+ lift_directionUp = ( lift_cmd == lift_CMD_UP || lift_cmd == lift_CMD_TOP );
+ lift_ctrl_io_out[lift_MOTOR_UP] = lift_directionUp;
+ if ( !lift_cntValid ) {
+ lift_cnt = 0; /* use relative counter */
+ if ( lift_cmd == lift_CMD_UP )
+ lift_endCnt = lift_one_level;
+ else
+ lift_endCnt = -lift_one_level;
+ } else {
+ lift_endCnt = lift_cnt;
+ newLevel = -99;
+ if ( lift_cmd == lift_CMD_UP )
+ newLevel = lift_level + 1;
+ else
+ if ( lift_cmd == lift_CMD_DOWN )
+ newLevel = lift_level - 1;
+ --newLevel; /* lift_level is one based */
+ if ( newLevel >= 0 && newLevel < 14 )
+ lift_endCnt = lift_levelPos[newLevel];
+ }
+}
+
+
+int lift_check_run()
+{
+ if ( lift_cmd == lift_CMD_UP ) {
+ if ( lift_cnt < lift_endCnt - 1 && !lift_ctrl_io_in[lift_SENS_TOP] )
+ return 1;
+ } else
+ if ( lift_cmd == lift_CMD_DOWN ) {
+ if ( lift_cnt > lift_endCnt + 1 && !lift_ctrl_io_in[lift_SENS_BOTTOM] )
+ return 1;
+ } else
+ if ( lift_cmd == lift_CMD_TOP ) {
+ if ( lift_loadPending && lift_ctrl_io_in[lift_SENS_LOAD] ) {
+ /* we are at lift_load position */
+ lift_loadLevel = lift_level;
+ lift_loadPending = 0;
+ return 0;
+ }
+ if ( !lift_ctrl_io_in[lift_SENS_TOP] )
+ return 1;
+ /* safe fallback if lift_load sensor does not work */
+ lift_loadPending = 0;
+ } else
+ if ( lift_cmd == lift_CMD_BOTTOM ) {
+ if ( lift_loadPending ) {
+ if ( lift_loadSensor ) {
+ if ( !lift_ctrl_io_in[lift_SENS_LOAD] ) {
+ lift_loadSensor = 0;
+ /* we are at lift_load position */
+ lift_loadPending = 0;
+ lift_loadLevel = lift_level;
+ return 0;
+ }
+ }
+ lift_loadSensor = lift_ctrl_io_in[lift_SENS_LOAD];
+ }
+ if ( !lift_ctrl_io_in[lift_SENS_BOTTOM] )
+ return 1;
+ }
+ return 0;
+}