summaryrefslogtreecommitdiff
path: root/robot
diff options
context:
space:
mode:
Diffstat (limited to 'robot')
-rw-r--r--robot/errcatch.c2
-rw-r--r--robot/modes.c30
-rw-r--r--robot/modes.h11
-rw-r--r--robot/sercomm.c2
-rw-r--r--robot/setup.c3
5 files changed, 36 insertions, 12 deletions
diff --git a/robot/errcatch.c b/robot/errcatch.c
index e44acfd..8df90b8 100644
--- a/robot/errcatch.c
+++ b/robot/errcatch.c
@@ -51,7 +51,7 @@ void w2_errcatch_handle_error(w2_s_error *error) {
uint8_t severity = error->code & W2_E_TYPE_MASK;
// trigger emergency mode for critical errors
- if ((severity ^ W2_E_TYPE_CRIT) == 0) w2_modes_switch(W2_M_HALT);
+ if ((severity ^ W2_E_TYPE_CRIT) == 0) w2_modes_call(W2_M_HALT);
// TODO: handle more error types
switch (error->code) {
diff --git a/robot/modes.c b/robot/modes.c
index 1f36703..8d3a099 100644
--- a/robot/modes.c
+++ b/robot/modes.c
@@ -1,15 +1,31 @@
+#include <stdbool.h>
+
+#include "../shared/util.h"
+#include "errcatch.h"
#include "modes.h"
#include "sercomm.h"
-void (*g_w2_current_mode)() = &w2_mode_halt;
+/** function pointer to current mode */
+// static void (*g_w2_current_mode)() = &w2_mode_halt;
+
+static void (*g_w2_mode_history[W2_MODE_HISTORY_BUFFER_SIZE])();
+static uint8_t g_w2_mode_history_index = 0;
+
+void w2_modes_main() { (*g_w2_mode_history[g_w2_mode_history_index])(); }
-void w2_modes_main() { (*g_w2_current_mode)(); }
+void w2_modes_switch(w2_e_mode new_mode, bool replace) {
+ int16_t next_history_index =
+ g_w2_mode_history_index + (new_mode == W2_M_PREV ? -1 : 1) * (replace - 1);
+ if (next_history_index == -1 || next_history_index == W2_MODE_HISTORY_BUFFER_SIZE - 1) {
+ next_history_index = W2_RANGE(0, next_history_index, W2_MODE_HISTORY_BUFFER_SIZE);
+ w2_errcatch_throw(W2_E_WARN_MODE_HISTORY_BUFFER_IOB);
+ }
-void w2_modes_switch(w2_e_mode new_mode) {
if (new_mode == W2_M_PREV) {
- // TODO implement previous mode buffer
+ g_w2_mode_history_index = next_history_index;
} else {
- g_w2_current_mode = W2_MODES[new_mode];
+ g_w2_mode_history_index = next_history_index;
+ g_w2_mode_history[g_w2_mode_history_index] = W2_MODES[new_mode];
}
// forward mode change to sercomm
@@ -22,3 +38,7 @@ void w2_modes_switch(w2_e_mode new_mode) {
free(msg);
free(msg_bin);
}
+
+void w2_modes_call(w2_e_mode mode) { w2_modes_switch(mode, false); }
+
+void w2_modes_swap(w2_e_mode mode) { w2_modes_switch(mode, true); }
diff --git a/robot/modes.h b/robot/modes.h
index a9d96d8..3423a0f 100644
--- a/robot/modes.h
+++ b/robot/modes.h
@@ -1,5 +1,7 @@
#pragma once
+#include "../shared/consts.h"
+
#include "mode_chrg.h"
#include "mode_dirc.h"
#include "mode_grid.h"
@@ -9,9 +11,6 @@
#include "mode_scal.h"
#include "mode_spin.h"
-/** function pointer to current mode */
-extern void (*g_w2_current_mode)();
-
/**
* mode logic
*
@@ -38,5 +37,7 @@ static const void(*const W2_MODES[]) = {
&w2_mode_chrg, &w2_mode_dirc, &w2_mode_spin, &w2_mode_scal,
};
-/** switch the current mode */
-void w2_modes_switch(w2_e_mode new_mode);
+/** switch current mode (allow switching back to previous mode) */
+void w2_modes_call(w2_e_mode mode);
+/** switch current mode (replace current mode keeping history index) */
+void w2_modes_swap(w2_e_mode mode);
diff --git a/robot/sercomm.c b/robot/sercomm.c
index e972f28..c9c6194 100644
--- a/robot/sercomm.c
+++ b/robot/sercomm.c
@@ -71,7 +71,7 @@ void w2_cmd_mode_rx(w2_s_bin *data) {
w2_s_cmd_mode_rx *message = malloc(w2_cmd_sizeof(data->data, data->bytes));
memcpy(message, data->data, data->bytes);
- w2_modes_switch(message->mode);
+ w2_modes_swap(message->mode);
}
void w2_cmd_sped_rx(w2_s_bin *data) { return; }
diff --git a/robot/setup.c b/robot/setup.c
index 1ecda43..06c8fa4 100644
--- a/robot/setup.c
+++ b/robot/setup.c
@@ -31,6 +31,9 @@ void w2_setup_main() {
// reset timer
time_reset();
+ // set default mode
+ w2_modes_swap(W2_M_HALT);
+
// indicate startup done
play("L50 c>c");
}