20
20
#include < NeoPixelConnect.h>
21
21
#include < PacketSerial.h>
22
22
#include < functional>
23
+ #include < etl/vector.h>
23
24
24
25
#include " datatypes.h"
25
26
#include " imu.h"
@@ -123,8 +124,8 @@ uint16_t ui_interval = 1000; // UI send msg (LED/State) interval (
123
124
uint16_t config_crc_in_flash = 0 ;
124
125
struct ll_high_level_config llhl_config; // LL/HL configuration (is initialized with YF-C500 defaults)
125
126
126
- // Hall input sources, same order as in ll_high_level_config.hall_configs
127
- const std::function<bool ()> halls [MAX_HALL_INPUTS] = {
127
+ // Available hall input sources, same order as in ll_high_level_config.hall_configs
128
+ const std::function<bool ()> available_halls [MAX_HALL_INPUTS] = {
128
129
[]() { return gpio_get (PIN_EMERGENCY_1); }, // OM-Hall-1 (default Lift1)
129
130
[]() { return gpio_get (PIN_EMERGENCY_2); }, // OM-Hall-2 (default Lift2)
130
131
[]() { return gpio_get (PIN_EMERGENCY_3); }, // OM-Hall-3 (default Stop1)
@@ -136,9 +137,8 @@ const std::function<bool()> halls[MAX_HALL_INPUTS] = {
136
137
[]() { return stock_ui_emergency_state & LL_EMERGENCY_BIT_CU_STOP1; }, // CoverUI-Stop1
137
138
[]() { return stock_ui_emergency_state & LL_EMERGENCY_BIT_CU_STOP2; }, // CoverUI-Stop2
138
139
};
139
- // Instead of iterating constantly over all halls, we use these compacted ones, whose contain the halls index of the used ones
140
- uint8_t stop_halls[MAX_HALL_INPUTS] = {};
141
- uint8_t lift_halls[MAX_HALL_INPUTS] = {};
140
+ // Instead of iterating constantly over all available_halls, we use this compacted vector (which only contain the used halls)
141
+ etl::vector<HallHandle, MAX_HALL_INPUTS> halls;
142
142
143
143
void sendMessage (void *message, size_t size);
144
144
void sendUIMessage (void *message, size_t size);
@@ -161,33 +161,32 @@ void updateEmergency() {
161
161
uint8_t last_emergency = status_message.emergency_bitmask & LL_EMERGENCY_BIT_LATCH;
162
162
uint8_t emergency_state = 0 ;
163
163
164
- // Check all "stop" mode emergency inputs (halls)
164
+ // Check all emergency inputs (halls)
165
165
bool stop_pressed = false ;
166
- size_t i;
167
- for (i = 0 ; i < MAX_HALL_INPUTS; i++) {
168
- if (stop_halls[i] == 0xff ) break ; // End marker reached
169
- stop_pressed = halls[stop_halls[i]]() ^ llhl_config.hall_configs [stop_halls[i]].active_low ; // Get hall value and apply active_low level (invert)
170
- if (stop_pressed) break ; // Break at first detected stop
166
+ int num_lifted = 0 ;
167
+ for (const auto &hall : halls) {
168
+ if (!(hall.get_value () ^ hall.config .active_low )) continue ; // Hall isn't triggered
169
+ if (hall.config .mode == HallMode::STOP) {
170
+ stop_pressed = true ;
171
+ } else if (hall.config .mode == HallMode::LIFT_TILT) {
172
+ num_lifted++;
173
+ }
174
+ // From logic point of view, it save to escape here if stop_pressed == true AND num_lifted >= 2, but this is very unlikely to happen ever!
175
+ // Instead of, we should exit iterating over the remaining halls, if an important emergency case happen, which is STOP got pressed OR >=2 wheels got lifted.
176
+ if (stop_pressed || num_lifted >= 2 )
177
+ break ;
171
178
}
172
179
173
180
// Handle emergency "Stop" buttons
174
181
if (stop_pressed) {
175
- if (button_emergency_started == 0 ) button_emergency_started = millis (); // If we just pressed, store the timestamp
182
+ if (button_emergency_started == 0 ) {
183
+ button_emergency_started = millis (); // Just pressed, store the timestamp for debouncing
184
+ } else if (button_emergency_started > 0 && (millis () - button_emergency_started) >= BUTTON_EMERGENCY_MILLIS) {
185
+ emergency_state |= LL_EMERGENCY_BIT_STOP; // Debounced
186
+ }
176
187
} else {
177
188
button_emergency_started = 0 ; // Not pressed, reset the time
178
189
}
179
- if (button_emergency_started > 0 && (millis () - button_emergency_started) >= BUTTON_EMERGENCY_MILLIS) {
180
- emergency_state |= LL_EMERGENCY_BIT_STOP;
181
- }
182
-
183
- // Check all "lifted" mode emergency inputs (halls)
184
- int num_lifted = 0 ;
185
- for (i = 0 ; i < MAX_HALL_INPUTS; i++) {
186
- if (lift_halls[i] == 0xff ) break ; // End marker reached
187
- if (halls[lift_halls[i]]() ^ llhl_config.hall_configs [lift_halls[i]].active_low ) // Get hall value and apply active_low level (invert)
188
- num_lifted++;
189
- if (num_lifted >= 2 ) break ; // Break once two wheels are lifted
190
- }
191
190
192
191
// Handle lifted (>=2 wheels are lifted)
193
192
if (num_lifted >= 2 ) {
@@ -616,22 +615,10 @@ void applyConfig(const uint8_t *buffer, const size_t size) {
616
615
new_config.hall_configs [i] = rcv_config.hall_configs [i];
617
616
}
618
617
619
- // Apply active Emergency/Hall configurations to our compacted stop/lift-hall arrays which get used by updateEmergency()
620
- uint8_t stop_hall_idx = 0 , lift_hall_idx = 0 ;
618
+ // Apply the new emergency/hall configuration to our compacted stop/lift-hall vector which get used by updateEmergency()
621
619
for (size_t i = 0 ; i < MAX_HALL_INPUTS; i++) {
622
- switch (new_config.hall_configs [i].mode ) {
623
- case HallMode::LIFT_TILT:
624
- lift_halls[lift_hall_idx] = i;
625
- lift_hall_idx++;
626
- break ;
627
- case HallMode::STOP:
628
- stop_halls[stop_hall_idx] = i;
629
- stop_hall_idx++;
630
- break ;
631
- }
620
+ halls.push_back ({new_config.hall_configs [i], available_halls[i]});
632
621
}
633
- lift_halls[lift_hall_idx] = 0xff ; // End of lift halls marker
634
- stop_halls[stop_hall_idx] = 0xff ; // End of stop halls marker
635
622
636
623
llhl_config = new_config; // Make new config live
637
624
}
0 commit comments