diff --git a/main.cpp b/main.cpp
index d0b0ca7..e9107a9 100644
--- a/main.cpp
+++ b/main.cpp
@@ -30,6 +30,7 @@ along with this program. If not, see .
#include "user_io.h"
#include "input.h"
#include "fpga_io.h"
+#include "scheduler.h"
const char *version = "$VER:HPS" VDATE;
@@ -75,26 +76,8 @@ int main(int argc, char *argv[])
FindStorage();
user_io_init((argc > 1) ? argv[1] : "");
- while(1)
- {
- if(!is_fpga_ready(1))
- {
- printf("FPGA is not ready. JTAG uploading?\n");
- printf("Waiting for FPGA to be ready...\n");
+ scheduler_init();
+ scheduler_run();
- //enable reset in advance
- fpga_core_reset(1);
-
- while (!is_fpga_ready(0))
- {
- sleep(1);
- }
- reboot(0);
- }
-
- user_io_poll();
- input_poll(0);
- HandleUI();
- }
return 0;
}
diff --git a/menu.h b/menu.h
index 3705abe..bebf1f0 100644
--- a/menu.h
+++ b/menu.h
@@ -1,6 +1,8 @@
#ifndef MENU_H
#define MENU_H
+#include
+
// UI strings, used by boot messages
extern const char *config_memory_chip_msg[];
extern const char *config_memory_slow_msg[];
diff --git a/scheduler.cpp b/scheduler.cpp
new file mode 100644
index 0000000..e504126
--- /dev/null
+++ b/scheduler.cpp
@@ -0,0 +1,94 @@
+#include "scheduler.h"
+#include
+#include "libco.h"
+#include "menu.h"
+#include "user_io.h"
+#include "input.h"
+#include "fpga_io.h"
+
+static cothread_t co_scheduler = nullptr;
+static cothread_t co_poll = nullptr;
+static cothread_t co_ui = nullptr;
+static cothread_t co_last = nullptr;
+
+static void scheduler_wait_fpga_ready(void)
+{
+ while (!is_fpga_ready(1))
+ {
+ printf("FPGA is not ready. JTAG uploading?\n");
+ printf("Waiting for FPGA to be ready...\n");
+
+ //enable reset in advance
+ fpga_core_reset(1);
+
+ while (!is_fpga_ready(0))
+ {
+ sleep(1);
+ }
+ reboot(0);
+ }
+}
+
+static void scheduler_co_poll(void)
+{
+ for (;;)
+ {
+ scheduler_wait_fpga_ready();
+
+ user_io_poll();
+ input_poll(0);
+
+ scheduler_yield();
+ }
+}
+
+static void scheduler_co_ui(void)
+{
+ for (;;)
+ {
+ HandleUI();
+
+ scheduler_yield();
+ }
+}
+
+static void scheduler_schedule(void)
+{
+ if (co_last == co_poll)
+ {
+ co_last = co_ui;
+ co_switch(co_ui);
+ }
+ else
+ {
+ co_last = co_poll;
+ co_switch(co_poll);
+ }
+}
+
+void scheduler_init(void)
+{
+ const unsigned int co_stack_size = 262144 * sizeof(void*);
+
+ co_poll = co_create(co_stack_size, scheduler_co_poll);
+ co_ui = co_create(co_stack_size, scheduler_co_ui);
+}
+
+void scheduler_run(void)
+{
+ co_scheduler = co_active();
+
+ for (;;)
+ {
+ scheduler_schedule();
+ }
+
+ co_delete(co_ui);
+ co_delete(co_poll);
+ co_delete(co_scheduler);
+}
+
+void scheduler_yield(void)
+{
+ co_switch(co_scheduler);
+}
diff --git a/scheduler.h b/scheduler.h
new file mode 100644
index 0000000..15207fb
--- /dev/null
+++ b/scheduler.h
@@ -0,0 +1,8 @@
+#ifndef SCHEDULER_H
+#define SCHEDULER_H
+
+void scheduler_init(void);
+void scheduler_run(void);
+void scheduler_yield(void);
+
+#endif