Skip to content

Commit 4d43638

Browse files
committed
Optimize hall handling with etl::vector
1 parent 7ba963d commit 4d43638

File tree

3 files changed

+32
-39
lines changed

3 files changed

+32
-39
lines changed

Firmware/LowLevel/platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ lib_deps =
2828
bakercp/PacketSerial@^1.4.0
2929
powerbroker2/FireTimer@^1.0.5
3030
https://github.com/ClemensElflein/NeoPixelConnect.git
31-
31+
etlcpp/Embedded Template Library @ ^20.39.4
3232

3333
debug_tool = custom
3434
debug_init_break =

Firmware/LowLevel/src/datatypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ struct HallConfig {
157157
} __attribute__((packed));
158158
#pragma pack(pop)
159159

160+
// For each active hall, we've a handle of it for quick and direct access
161+
struct HallHandle {
162+
HallConfig config;
163+
std::function<bool()> get_value;
164+
};
165+
160166
#define MAX_HALL_INPUTS 10 // How much Hall-inputs we support. 4 * OM + 6 * Stock-CoverUI + 0 spare (because not yet required to make it fixed)
161167

162168
// LL/HL config packet, bi-directional, flexible-length, with defaults for YF-C500.

Firmware/LowLevel/src/main.cpp

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <NeoPixelConnect.h>
2121
#include <PacketSerial.h>
2222
#include <functional>
23+
#include <etl/vector.h>
2324

2425
#include "datatypes.h"
2526
#include "imu.h"
@@ -123,8 +124,8 @@ uint16_t ui_interval = 1000; // UI send msg (LED/State) interval (
123124
uint16_t config_crc_in_flash = 0;
124125
struct ll_high_level_config llhl_config; // LL/HL configuration (is initialized with YF-C500 defaults)
125126

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] = {
128129
[]() { return gpio_get(PIN_EMERGENCY_1); }, // OM-Hall-1 (default Lift1)
129130
[]() { return gpio_get(PIN_EMERGENCY_2); }, // OM-Hall-2 (default Lift2)
130131
[]() { return gpio_get(PIN_EMERGENCY_3); }, // OM-Hall-3 (default Stop1)
@@ -136,9 +137,8 @@ const std::function<bool()> halls[MAX_HALL_INPUTS] = {
136137
[]() { return stock_ui_emergency_state & LL_EMERGENCY_BIT_CU_STOP1; }, // CoverUI-Stop1
137138
[]() { return stock_ui_emergency_state & LL_EMERGENCY_BIT_CU_STOP2; }, // CoverUI-Stop2
138139
};
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;
142142

143143
void sendMessage(void *message, size_t size);
144144
void sendUIMessage(void *message, size_t size);
@@ -161,33 +161,32 @@ void updateEmergency() {
161161
uint8_t last_emergency = status_message.emergency_bitmask & LL_EMERGENCY_BIT_LATCH;
162162
uint8_t emergency_state = 0;
163163

164-
// Check all "stop" mode emergency inputs (halls)
164+
// Check all emergency inputs (halls)
165165
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;
171178
}
172179

173180
// Handle emergency "Stop" buttons
174181
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+
}
176187
} else {
177188
button_emergency_started = 0; // Not pressed, reset the time
178189
}
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-
}
191190

192191
// Handle lifted (>=2 wheels are lifted)
193192
if (num_lifted >= 2) {
@@ -616,22 +615,10 @@ void applyConfig(const uint8_t *buffer, const size_t size) {
616615
new_config.hall_configs[i] = rcv_config.hall_configs[i];
617616
}
618617

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()
621619
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]});
632621
}
633-
lift_halls[lift_hall_idx] = 0xff; // End of lift halls marker
634-
stop_halls[stop_hall_idx] = 0xff; // End of stop halls marker
635622

636623
llhl_config = new_config; // Make new config live
637624
}

0 commit comments

Comments
 (0)