-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparameters.c
177 lines (166 loc) · 5.1 KB
/
parameters.c
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "parameters.h"
#include "hardware.h"
#include "stepper.h"
#include "peripheral.h"
#include "protocol/constants.h"
#include "protocol/message_structs.h"
parameters_t parameters;
void reset_parameters(void){
parameters.error_low = 0;
parameters.error_high = 0;
parameters.homing = ENABLE_MIN; // Don't flip, home low, no software max, don't invert
parameters.min_pos = 0;
parameters.max_pos = 0;
parameters.home_pos = 0;
parameters.homing_feedrate = 60000; // Arbitrary, but reasonable
parameters.motor_on = 0;
parameters.motor_timeout = 1<<30; // Big number is big
// Position lives in the stepper state, as it is volatile
parameters.slowdown = 0;
parameters.sync_error = 0;
parameters.last_home = 0;
}
static uint32_t const_to_mask(imc_axis_parameter c){
switch(c){
case IMC_PARAM_FLIP_AXIS:
return FLIP_AXIS;
case IMC_PARAM_HOME_DIR:
return HOME_DIR;
case IMC_PARAM_MIN_SOFTWARE_ENDSTOPS:
return MIN_SOFTWARE;
case IMC_PARAM_MAX_SOFTWARE_ENDSTOPS:
return MAX_SOFTWARE;
case IMC_PARAM_MIN_LIMIT_EN:
return ENABLE_MIN;
case IMC_PARAM_MAX_LIMIT_EN:
return ENABLE_MAX;
case IMC_PARAM_MIN_LIMIT_INV:
return INVERT_MIN;
case IMC_PARAM_MAX_LIMIT_INV:
return INVERT_MAX;
default:
return 0;
}
}
static uint32_t limit_state(uint32_t dir){
uint32_t bit = dir ? MAX_LIMIT_BIT : MIN_LIMIT_BIT;
uint32_t invert = (parameters.homing & (dir ? INVERT_MAX : INVERT_MIN)) ? bit : 0;
return ((CONTROL_PORT(DIR) ^ invert) & bit) ? 1 : 0;
}
void handle_get_parameter(volatile msg_get_param_t* msg,rsp_get_param_t* rsp){
switch(msg->param_id){
case IMC_PARAM_ERROR_INFO1:
rsp->value = parameters.error_low;
break;
case IMC_PARAM_ERROR_INFO2:
rsp->value = parameters.error_high;
break;
case IMC_PARAM_FLIP_AXIS:
case IMC_PARAM_HOME_DIR:
case IMC_PARAM_MIN_SOFTWARE_ENDSTOPS:
case IMC_PARAM_MAX_SOFTWARE_ENDSTOPS:
case IMC_PARAM_MIN_LIMIT_EN:
case IMC_PARAM_MAX_LIMIT_EN:
case IMC_PARAM_MIN_LIMIT_INV:
case IMC_PARAM_MAX_LIMIT_INV:
rsp->value = const_to_mask(msg->param_id) & parameters.homing ? 1 : 0;
break;
case IMC_PARAM_MIN_POS:
rsp->value = parameters.min_pos;
break;
case IMC_PARAM_MAX_POS:
rsp->value = parameters.max_pos;
break;
case IMC_PARAM_HOME_POS:
rsp->value = parameters.home_pos;
break;
case IMC_PARAM_HOMING_FEEDRATE:
rsp->value = parameters.homing_feedrate;
break;
case IMC_PARAM_MOTOR_ON:
rsp->value = parameters.motor_on;
break;
case IMC_PARAM_MOTOR_IDLE_TIMEOUT:
rsp->value = parameters.motor_timeout;
break;
case IMC_PARAM_LOCATION:
rsp->value = get_position();
break;
case IMC_PARAM_SLOWDOWN:
rsp->value = parameters.slowdown;
break;
case IMC_PARAM_SYNC_ERROR:
rsp->value = parameters.sync_error;
break;
case IMC_PARAM_LAST_HOME:
rsp->value = parameters.last_home;
break;
case IMC_PARAM_MIN_LIMIT_STATE:
rsp->value = limit_state(0);
break;
case IMC_PARAM_MAX_LIMIT_STATE:
rsp->value = limit_state(1);
break;
default:
;
}
}
void handle_set_parameter(volatile msg_set_param_t* msg){
// Can't set error info or sync_error
// Pullups and motor on/off are special, as we actually have to do io
uint32_t mask;
uint32_t axis = 0;
switch(msg->param_id){
case IMC_PARAM_MAX_LIMIT_INV:
case IMC_PARAM_MAX_LIMIT_EN:
axis = 1;
case IMC_PARAM_MIN_LIMIT_EN:
case IMC_PARAM_MIN_LIMIT_INV:
case IMC_PARAM_FLIP_AXIS:
case IMC_PARAM_HOME_DIR:
case IMC_PARAM_MIN_SOFTWARE_ENDSTOPS:
case IMC_PARAM_MAX_SOFTWARE_ENDSTOPS:
mask = const_to_mask(msg->param_id);
parameters.homing = ((~mask) & parameters.homing) | (msg->param_value ? mask : 0);
// This is called a few extra times, but should be idempotent
configure_limit_gpio(axis, PRESERVE_PULLUP, parameters.homing);
break;
case IMC_PARAM_MIN_POS: parameters.min_pos = msg->param_value; break;
case IMC_PARAM_MAX_POS: parameters.max_pos = msg->param_value; break;
case IMC_PARAM_HOMING_FEEDRATE:
{
uint32_t minimum = msg->param_value;
minimum = minimum < MINIMUM_STEPS_PER_MINUTE ? MINIMUM_STEPS_PER_MINUTE : minimum;
parameters.homing_feedrate = minimum;
}
break;
case IMC_PARAM_HOME_POS: parameters.home_pos = msg->param_value; break;
case IMC_PARAM_MOTOR_IDLE_TIMEOUT: parameters.motor_timeout = msg->param_value; break;
case IMC_PARAM_SLOWDOWN: parameters.slowdown = msg->param_value; break;
case IMC_PARAM_MIN_LIMIT_PULLUP:
configure_limit_gpio(0, msg->param_value, parameters.homing);
break;
case IMC_PARAM_MAX_LIMIT_PULLUP:
configure_limit_gpio(1, msg->param_value, parameters.homing);
break;
case IMC_PARAM_MOTOR_ON:
// Do some IO to turn the motor on or off
enable_stepper();
parameters.motor_on = msg->param_value;
if(parameters.motor_on){
enable_stepper();
}else{
disable_stepper();
}
break;
case IMC_PARAM_LOCATION:
// This may have a signed/unsigned issue. todo: figure that out
set_position(msg->param_value);
break;
case IMC_PARAM_MICROSTEPPING:
set_microstepping(msg->param_value);
break;
default:
break;
}
}