-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathramp.c
More file actions
155 lines (117 loc) · 4.05 KB
/
ramp.c
File metadata and controls
155 lines (117 loc) · 4.05 KB
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "ramp.h"
#include "utils/utils.h"
err_t ramp_init(ramp_t* ramp)
{
ramp->current_ref = 0;
ramp->target_ref = 0;
// (0.02 * 0x10000 << 16) / (time / 100).
ramp->reference_step = 0x51E0000 /* 20 ms << 16 */ / (RAMP_REFERENCE_TIME_DEFAULT / 100);
ramp->start_step = 0x51E0000 /* 20 ms << 16 */ / (RAMP_START_TIME_DEFAULT / 100);
ramp->stop_step = 0x51E0000 /* 20 ms << 16 */ / (RAMP_STOP_TIME_DEFAULT / 100);
ramp->fast_stop_step = 0x51E0000 /* 20 ms << 16 */ / (RAMP_FAST_STOP_TIME_DEFAULT / 100);
ramp->stop_mode = RAMP_STOP_MODE_NORMAL;
return E_NO_ERROR;
}
err_t ramp_set_reference_time(ramp_t* ramp, ramp_time_t time, fixed32_t step_dt)
{
if(time < 0) return E_INVALID_VALUE;
if(time > RAMP_TIME_MAX) return E_OUT_OF_RANGE;
fixed32_t step = step_dt * 100;
step = fixed32_div((int64_t)step, time);
ramp->reference_step = step;
return E_NO_ERROR;
}
err_t ramp_set_start_time(ramp_t* ramp, ramp_time_t time, fixed32_t step_dt)
{
if(time < 0) return E_INVALID_VALUE;
if(time > RAMP_TIME_MAX) return E_OUT_OF_RANGE;
fixed32_t step = step_dt * 100;
step = fixed32_div((int64_t)step, time);
ramp->start_step = step;
return E_NO_ERROR;
}
err_t ramp_set_stop_time(ramp_t* ramp, ramp_time_t time, fixed32_t step_dt)
{
if(time < 0) return E_INVALID_VALUE;
if(time > RAMP_TIME_MAX) return E_OUT_OF_RANGE;
fixed32_t step = step_dt * 100;
step = fixed32_div((int64_t)step, time);
ramp->stop_step = step;
return E_NO_ERROR;
}
err_t ramp_set_fast_stop_time(ramp_t* ramp, ramp_time_t time, fixed32_t step_dt)
{
if(time < 0) return E_INVALID_VALUE;
if(time > RAMP_TIME_MAX) return E_OUT_OF_RANGE;
fixed32_t step = step_dt * 100;
step = fixed32_div((int64_t)step, time);
ramp->fast_stop_step = step;
return E_NO_ERROR;
}
static fixed32_t ramp_get_step(ramp_t* ramp)
{
if(ramp->current_ref < ramp->target_ref){
return ramp->start_step;
}else if(ramp->current_ref > ramp->target_ref){
if(ramp->stop_mode == RAMP_STOP_MODE_NORMAL){
return ramp->stop_step;
}else{
return ramp->fast_stop_step;
}
}
return 0;
}
err_t ramp_set_target_reference(ramp_t* ramp, ramp_reference_t reference)
{
if(reference > RAMP_REFERENCE_MAX_F) return E_OUT_OF_RANGE;
if(reference < RAMP_REFERENCE_MIN_F) return E_OUT_OF_RANGE;
ramp->target_ref = reference;
return E_NO_ERROR;
}
bool ramp_inc_reference(ramp_t* ramp)
{
if(ramp->target_ref == RAMP_REFERENCE_MAX_F) return false;
fixed32_t new_ref = ramp->target_ref + ramp->reference_step;
if(new_ref > RAMP_REFERENCE_MAX_F) new_ref = RAMP_REFERENCE_MAX_F;
ramp->target_ref = new_ref;
return true;
}
bool ramp_dec_reference(ramp_t* ramp)
{
if(ramp->target_ref == RAMP_REFERENCE_MIN_F) return false;
fixed32_t new_ref = ramp->target_ref - ramp->reference_step;
if(new_ref < RAMP_REFERENCE_MIN_F) new_ref = RAMP_REFERENCE_MIN_F;
ramp->target_ref = new_ref;
return true;
}
void ramp_adjust_current_reference(ramp_t* ramp, fixed32_t cur_val, fixed32_t max_val)
{
if(cur_val <= RAMP_REFERENCE_MIN_F){
ramp->current_ref = 0;
return;
}
if(cur_val >= max_val){
ramp->current_ref = RAMP_REFERENCE_MAX_F;
return;
}
fixed32_t cur_calc_ref = fixed32_div((int64_t)cur_val, max_val);
cur_calc_ref = cur_calc_ref * 100;
cur_calc_ref = CLAMP(cur_calc_ref, RAMP_REFERENCE_MIN_F, RAMP_REFERENCE_MAX_F);
ramp->current_ref = cur_calc_ref;
}
bool ramp_calc_step(ramp_t* ramp)
{
if(ramp->current_ref == ramp->target_ref) return true;
fixed32_t dr = ramp->current_ref - ramp->target_ref;
fixed32_t abs_dr = fixed_abs(dr);
fixed32_t step = ramp_get_step(ramp);
if(abs_dr < step){
ramp->current_ref = ramp->target_ref;
return true;
}else if(dr < 0){
ramp->current_ref += step;
}else{
ramp->current_ref -= step;
}
return false;
}