summaryrefslogtreecommitdiff
path: root/src/hal/components/gearchange.comp
blob: 9a523684b57464e24a6650c4fe4c738eefd1e9fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
component gearchange """Select from one two speed ranges
The output will be a value scaled for the selected gear, and clamped to
the min/max values for that gear.
The scale of gear 1 is assumed to be 1, so the output device scale
should be chosen accordingly.
The scale of gear 2 is relative to gear 1, so if gear 2 runs the spindle
2.5 times as fast as gear 1, scale2 should be set to 2.5.""";
pin in bit sel "Gear selection input";
pin in float speed_in "Speed command input";
pin out float speed_out "Speed command to DAC/PWM";
pin in bit dir_in "Direction command input";
pin out bit dir_out "Direction output - possibly inverted for second gear";
param rw float min1 = 0 "Minimum allowed speed in gear range 1";
param rw float max1 = 100000 "Maximum allowed speed in gear range 1";
param rw float min2 = 0 "Minimum allowed speed in gear range 2";
param rw float max2 = 100000 "Maximum allowed speed in gear range 2";
param rw float scale2 = 1.0 """Relative scale of gear 2 vs. gear 1
Since it is assumed that gear 2 is "high gear", \\fBscale2\\fR must be
greater than 1, and will be reset to 1 if set lower.""";
param rw bit reverse = 0 "Set to 1 to reverse the spindle in second gear";

function _;
license "GPL";
;;
FUNCTION(_) {
    hal_float_t temp_in = speed_in;
    hal_float_t sign=1;
    /* Assume that the output device is scaled so that gear 1 is "Pass-through" */
    /* the other gear(s) need to be scaled by the relative scale for that gear */
    if (scale2 < 1) scale2 = 1;
    if (temp_in < 0) {
	sign = -1;
	temp_in = -temp_in;
    }
    if(sel) {		/* gear 2 */
    	if (temp_in < min2) temp_in = min2;
    	else if (temp_in > max2) temp_in = max2;
    	temp_in /= scale2;		/* scale up to second gear output range */
	dir_out = dir_in ^ reverse;
    } else {
    	if (temp_in < min1) temp_in = min1;
    	else if (temp_in > max1) temp_in = max1;
	dir_out = dir_in;
    }
    speed_out = sign*temp_in;
}