Add wasm tacle-bench targets

This commit is contained in:
2026-06-12 20:06:22 +02:00
parent 30daa8a00c
commit 08c2e9c13d
1122 changed files with 520422 additions and 0 deletions

View File

@ -0,0 +1,130 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: lift
Author: Martin Schoeberl, Benedikt Huber
Function: Lift Controler
Source: C-Port from http://www.jopdesign.com/doc/jembench.pdf
Original name: run_lift.c
Changes: no major functional changes
License: GPL version 3 or later
*/
/*
Include section
*/
#include "liftlibcontrol.h"
#include "liftlibio.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void lift_controller();
void lift_init();
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
lift_main();
int lift_return();
/*
Declaration of global variables
*/
int lift_checksum; /* Checksum */
/*
Initialization- and return-value-related functions
*/
void
lift_init() {
unsigned int i;
unsigned char *p;
volatile char bitmask = 0;
/*
Apply volatile XOR-bitmask to entire input array.
*/
p = (unsigned char *) &lift_ctrl_io_in[0];
__pragma_loopbound(40, 40);
for (i = 0; i < sizeof(lift_ctrl_io_in); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_out[0];
__pragma_loopbound(16, 16);
for (i = 0; i < sizeof(lift_ctrl_io_out); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_analog[0];
__pragma_loopbound(16, 16);
for (i = 0; i < sizeof(lift_ctrl_io_analog); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_led[0];
__pragma_loopbound(64, 64);
for (i = 0; i < sizeof(lift_ctrl_io_led); ++i, ++p)
*p ^= bitmask;
lift_checksum = 0;
lift_ctrl_init();
}
int
lift_return() {
return (lift_checksum - 4005888 != 0);
}
/*
Algorithm core functions
*/
void
lift_controller() {
lift_ctrl_get_vals();
lift_ctrl_loop();
lift_ctrl_set_vals();
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
lift_main() {
int i = 0;
__pragma_loopbound(1001, 1001);
while (1) {
/* zero input stimulus */
lift_simio_in = 0;
lift_simio_adc1 = 0;
lift_simio_adc2 = 0;
lift_simio_adc3 = 0;
/* run lift_controller */
lift_controller();
if (i++ >= 1000)
break;
}
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
lift_init();
lift_main();
return (lift_return());
}

View File

@ -0,0 +1,267 @@
#include "liftlibcontrol.h"
#include "liftlibio.h"
/* Global variables */
int lift_levelPos[16];
int lift_one_level;
/**
Is the counter valid for level positioning?
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
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(14, 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(14, 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;
}

View File

@ -0,0 +1,62 @@
#ifndef LIFTLIBCONTROL_H
#define LIFTLIBCONTROL_H
enum lift_Direction {
lift_GO_LOAD = 8,
lift_GO_TOP = 6,
lift_GO_BOTTOM = 7,
lift_GO_UP = 4,
lift_GO_DOWN = 5
};
enum lift_Sensor {
lift_SENS_IMPULS = 0,
lift_SENS_TOP = 1,
lift_SENS_BOTTOM = 2,
lift_SENS_LOAD = 3
};
enum lift_Motor { lift_MOTOR_ON = 0, lift_MOTOR_UP = 1 };
enum lift_Command {
lift_CMD_NONE = 0,
lift_CMD_TOP = 1,
lift_CMD_BOTTOM = 2,
lift_CMD_UP = 3,
lift_CMD_DOWN = 4
};
/* Global variables */
extern int lift_levelPos[16];
extern int lift_one_level;
extern int lift_cntValid;
extern int lift_cnt;
extern int lift_level;
extern int lift_loadLevel;
extern int lift_loadPending;
extern int lift_loadSensor;
extern int lift_cmd;
extern int lift_timMotor;
extern int lift_timImp;
extern int lift_directionUp;
extern int lift_lastImp;
extern int lift_dbgCnt;
extern int lift_endCnt;
/* Checksum */
extern int lift_checksum;
/* prototypes */
void lift_ctrl_init();
void lift_ctrl_loop();
/* internal prototypes */
int lift_check_run();
void lift_wait_for_motor_start();
void lift_do_cmd();
void lift_do_impulse(int val, int motor, int reset);
void lift_check_cmd();
void lift_check_level();
#endif

View File

@ -0,0 +1,69 @@
#include "liftlibio.h"
/* Global variables */
int lift_ctrl_io_in[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int lift_ctrl_io_out[4] = {0, 0, 0, 0};
int lift_ctrl_io_analog[4] = {0, 0, 0, 0};
int lift_ctrl_io_led[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int lift_ctrl_dly1;
int lift_ctrl_dly2;
/* Simulated hardware */
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
volatile int lift_simio_in;
volatile int lift_simio_out;
volatile int lift_simio_led;
volatile int lift_simio_adc1;
volatile int lift_simio_adc2;
volatile int lift_simio_adc3;
void
lift_io_init() {
lift_ctrl_dly1 = 0;
lift_ctrl_dly2 = 0;
}
void
lift_ctrl_set_vals() {
int val = 0, i;
__pragma_loopbound(4, 4);
for (i = 4 - 1; i >= 0; --i) {
val <<= 1;
val |= lift_ctrl_io_out[i] ? 1 : 0;
}
lift_simio_out = val;
__pragma_loopbound(14, 14);
for (i = 14 - 1; i >= 0; --i) {
val <<= 1;
val |= lift_ctrl_io_led[i] ? 1 : 0;
}
lift_simio_led = val;
lift_checksum += val;
}
void
lift_ctrl_get_vals() {
int i;
unsigned short int in0 = lift_simio_in;
unsigned short int in1 = lift_ctrl_dly1;
unsigned short int in2 = lift_ctrl_dly2;
lift_ctrl_dly2 = lift_ctrl_dly1;
lift_ctrl_dly1 = in0;
/* majority voting for input values
delays input value change by one period */
__pragma_loopbound(10, 10);
for (i = 0; i < 10; ++i) {
lift_ctrl_io_in[i] = ((in0 & 1) + (in1 & 1) + (in2 & 1)) > 1;
in0 >>= 1;
in1 >>= 1;
in2 >>= 1;
}
lift_ctrl_io_analog[0] = lift_simio_adc1;
lift_ctrl_io_analog[1] = lift_simio_adc2;
lift_ctrl_io_analog[2] = lift_simio_adc3;
}

View File

@ -0,0 +1,28 @@
#ifndef LIFTLIBIO_H
#define LIFTLIBIO_H
/* Global variables */
extern int lift_ctrl_io_in[10];
extern int lift_ctrl_io_out[4];
extern int lift_ctrl_io_analog[4];
extern int lift_ctrl_io_led[16];
extern int lift_ctrl_dly1, lift_ctrl_dly2;
/* Simulated hardware */
extern volatile int lift_simio_in;
extern volatile int lift_simio_out;
extern volatile int lift_simio_led;
extern volatile int lift_simio_adc1;
extern volatile int lift_simio_adc2;
extern volatile int lift_simio_adc3;
/* Checksum */
extern int lift_checksum;
/* prototypes */
void lift_io_init(void);
void lift_ctrl_get_vals(void);
void lift_ctrl_set_vals(void);
#endif

View File

@ -0,0 +1,138 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: lift
Author: Martin Schoeberl, Benedikt Huber
Function: Lift Controler
Source: C-Port from http://www.jopdesign.com/doc/jembench.pdf
Original name: run_lift.c
Changes: no major functional changes
License: GPL version 3 or later
*/
/*
Include section
*/
#include "liftlibcontrol.h"
#include "liftlibio.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
#include "liftlibcontrol.c"
#include "liftlibio.c"
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void lift_controller();
__attribute__((always_inline)) static inline void lift_init();
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
lift_main();
__attribute__((always_inline)) static inline int lift_return();
/*
Declaration of global variables
*/
int lift_checksum; /* Checksum */
/*
Initialization- and return-value-related functions
*/
__attribute__((always_inline)) static inline void
lift_init() {
unsigned int i;
unsigned char *p;
volatile char bitmask = 0;
/*
Apply volatile XOR-bitmask to entire input array.
*/
p = (unsigned char *) &lift_ctrl_io_in[0];
__pragma_loopbound(40, 40);
for (i = 0; i < sizeof(lift_ctrl_io_in); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_out[0];
__pragma_loopbound(16, 16);
for (i = 0; i < sizeof(lift_ctrl_io_out); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_analog[0];
__pragma_loopbound(16, 16);
for (i = 0; i < sizeof(lift_ctrl_io_analog); ++i, ++p)
*p ^= bitmask;
p = (unsigned char *) &lift_ctrl_io_led[0];
__pragma_loopbound(64, 64);
for (i = 0; i < sizeof(lift_ctrl_io_led); ++i, ++p)
*p ^= bitmask;
lift_checksum = 0;
lift_ctrl_init();
}
__attribute__((always_inline)) static inline int
lift_return() {
return (lift_checksum - 4005888 != 0);
}
/*
Algorithm core functions
*/
__attribute__((always_inline)) static inline void
lift_controller() {
lift_ctrl_get_vals();
lift_ctrl_loop();
lift_ctrl_set_vals();
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
lift_main() {
int i = 0;
__pragma_loopbound(1001, 1001);
while (1) {
/* zero input stimulus */
lift_simio_in = 0;
lift_simio_adc1 = 0;
lift_simio_adc2 = 0;
lift_simio_adc3 = 0;
/* run lift_controller */
lift_controller();
if (i++ >= 1000)
break;
}
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
lift_init();
lift_main();
return (lift_return());
}

View File

@ -0,0 +1,267 @@
#include "liftlibcontrol.h"
#include "liftlibio.h"
/* Global variables */
int lift_levelPos[16];
int lift_one_level;
/**
Is the counter valid for level positioning?
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
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;
__attribute__((always_inline)) static inline 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];
}
__attribute__((always_inline)) static inline 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;
}
__attribute__((always_inline)) static inline void
lift_check_level() {
int i;
int middle = lift_one_level >> 2;
if (lift_cntValid) {
__pragma_loopbound(14, 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(14, 14);
for (i = 0; i < 14; ++i)
lift_ctrl_io_led[i] = (i == lift_level - 1);
}
__attribute__((always_inline)) static inline 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;
}
__attribute__((always_inline)) static inline 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;
}
}
__attribute__((always_inline)) static inline 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;
}
}
__attribute__((always_inline)) static inline 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];
}
}
__attribute__((always_inline)) static inline 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;
}

View File

@ -0,0 +1,63 @@
#ifndef LIFTLIBCONTROL_H
#define LIFTLIBCONTROL_H
enum lift_Direction {
lift_GO_LOAD = 8,
lift_GO_TOP = 6,
lift_GO_BOTTOM = 7,
lift_GO_UP = 4,
lift_GO_DOWN = 5
};
enum lift_Sensor {
lift_SENS_IMPULS = 0,
lift_SENS_TOP = 1,
lift_SENS_BOTTOM = 2,
lift_SENS_LOAD = 3
};
enum lift_Motor { lift_MOTOR_ON = 0, lift_MOTOR_UP = 1 };
enum lift_Command {
lift_CMD_NONE = 0,
lift_CMD_TOP = 1,
lift_CMD_BOTTOM = 2,
lift_CMD_UP = 3,
lift_CMD_DOWN = 4
};
/* Global variables */
extern int lift_levelPos[16];
extern int lift_one_level;
extern int lift_cntValid;
extern int lift_cnt;
extern int lift_level;
extern int lift_loadLevel;
extern int lift_loadPending;
extern int lift_loadSensor;
extern int lift_cmd;
extern int lift_timMotor;
extern int lift_timImp;
extern int lift_directionUp;
extern int lift_lastImp;
extern int lift_dbgCnt;
extern int lift_endCnt;
/* Checksum */
extern int lift_checksum;
/* prototypes */
__attribute__((always_inline)) static inline void lift_ctrl_init();
__attribute__((always_inline)) static inline void lift_ctrl_loop();
/* internal prototypes */
__attribute__((always_inline)) static inline int lift_check_run();
__attribute__((always_inline)) static inline void lift_wait_for_motor_start();
__attribute__((always_inline)) static inline void lift_do_cmd();
__attribute__((always_inline)) static inline void
lift_do_impulse(int val, int motor, int reset);
__attribute__((always_inline)) static inline void lift_check_cmd();
__attribute__((always_inline)) static inline void lift_check_level();
#endif

View File

@ -0,0 +1,69 @@
#include "liftlibio.h"
/* Global variables */
int lift_ctrl_io_in[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int lift_ctrl_io_out[4] = {0, 0, 0, 0};
int lift_ctrl_io_analog[4] = {0, 0, 0, 0};
int lift_ctrl_io_led[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int lift_ctrl_dly1;
int lift_ctrl_dly2;
/* Simulated hardware */
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
volatile int lift_simio_in;
volatile int lift_simio_out;
volatile int lift_simio_led;
volatile int lift_simio_adc1;
volatile int lift_simio_adc2;
volatile int lift_simio_adc3;
__attribute__((always_inline)) static inline void
lift_io_init() {
lift_ctrl_dly1 = 0;
lift_ctrl_dly2 = 0;
}
__attribute__((always_inline)) static inline void
lift_ctrl_set_vals() {
int val = 0, i;
__pragma_loopbound(4, 4);
for (i = 4 - 1; i >= 0; --i) {
val <<= 1;
val |= lift_ctrl_io_out[i] ? 1 : 0;
}
lift_simio_out = val;
__pragma_loopbound(14, 14);
for (i = 14 - 1; i >= 0; --i) {
val <<= 1;
val |= lift_ctrl_io_led[i] ? 1 : 0;
}
lift_simio_led = val;
lift_checksum += val;
}
__attribute__((always_inline)) static inline void
lift_ctrl_get_vals() {
int i;
unsigned short int in0 = lift_simio_in;
unsigned short int in1 = lift_ctrl_dly1;
unsigned short int in2 = lift_ctrl_dly2;
lift_ctrl_dly2 = lift_ctrl_dly1;
lift_ctrl_dly1 = in0;
/* majority voting for input values
delays input value change by one period */
__pragma_loopbound(10, 10);
for (i = 0; i < 10; ++i) {
lift_ctrl_io_in[i] = ((in0 & 1) + (in1 & 1) + (in2 & 1)) > 1;
in0 >>= 1;
in1 >>= 1;
in2 >>= 1;
}
lift_ctrl_io_analog[0] = lift_simio_adc1;
lift_ctrl_io_analog[1] = lift_simio_adc2;
lift_ctrl_io_analog[2] = lift_simio_adc3;
}

View File

@ -0,0 +1,28 @@
#ifndef LIFTLIBIO_H
#define LIFTLIBIO_H
/* Global variables */
extern int lift_ctrl_io_in[10];
extern int lift_ctrl_io_out[4];
extern int lift_ctrl_io_analog[4];
extern int lift_ctrl_io_led[16];
extern int lift_ctrl_dly1, lift_ctrl_dly2;
/* Simulated hardware */
extern volatile int lift_simio_in;
extern volatile int lift_simio_out;
extern volatile int lift_simio_led;
extern volatile int lift_simio_adc1;
extern volatile int lift_simio_adc2;
extern volatile int lift_simio_adc3;
/* Checksum */
extern int lift_checksum;
/* prototypes */
__attribute__((always_inline)) static inline void lift_io_init(void);
__attribute__((always_inline)) static inline void lift_ctrl_get_vals(void);
__attribute__((always_inline)) static inline void lift_ctrl_set_vals(void);
#endif