aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/adccmds.c6
-rw-r--r--src/endstop.c6
-rw-r--r--src/sched.c70
-rw-r--r--src/sched.h8
4 files changed, 53 insertions, 37 deletions
diff --git a/src/adccmds.c b/src/adccmds.c
index 526325ad..55900ab1 100644
--- a/src/adccmds.c
+++ b/src/adccmds.c
@@ -18,6 +18,8 @@ struct analog_in {
uint8_t state, sample_count;
};
+static struct task_wake analog_wake;
+
static uint_fast8_t
analog_in_event(struct timer *timer)
{
@@ -42,6 +44,7 @@ analog_in_event(struct timer *timer)
}
if (a->value < a->min_value || a->value > a->max_value)
shutdown("adc out of range");
+ sched_wake_task(&analog_wake);
a->next_begin_time += a->rest_time;
a->timer.waketime = a->next_begin_time;
return SF_RESCHEDULE;
@@ -83,8 +86,7 @@ DECL_COMMAND(command_query_analog_in,
void
analog_in_task(void)
{
- static uint16_t next;
- if (!sched_check_periodic(3, &next))
+ if (!sched_check_wake(&analog_wake))
return;
uint8_t oid;
struct analog_in *a;
diff --git a/src/endstop.c b/src/endstop.c
index aaaf1baa..5bd863ea 100644
--- a/src/endstop.c
+++ b/src/endstop.c
@@ -21,6 +21,8 @@ struct end_stop {
enum { ESF_PIN_HIGH=1<<0, ESF_HOMING=1<<1, ESF_REPORT=1<<2 };
+static struct task_wake endstop_wake;
+
static void
stop_steppers(struct end_stop *e)
{
@@ -29,6 +31,7 @@ stop_steppers(struct end_stop *e)
while (count--)
if (e->steppers[count])
stepper_stop(e->steppers[count]);
+ sched_wake_task(&endstop_wake);
}
// Timer callback for an end stop
@@ -115,8 +118,7 @@ DECL_COMMAND(command_end_stop_query, "end_stop_query oid=%c");
void
end_stop_task(void)
{
- static uint16_t next;
- if (!sched_check_periodic(50, &next))
+ if (!sched_check_wake(&endstop_wake))
return;
uint8_t oid;
struct end_stop *e;
diff --git a/src/sched.c b/src/sched.c
index 8fee61f2..758fa71c 100644
--- a/src/sched.c
+++ b/src/sched.c
@@ -6,6 +6,7 @@
#include <setjmp.h> // setjmp
#include "autoconf.h" // CONFIG_*
+#include "board/io.h" // readb
#include "board/irq.h" // irq_save
#include "board/misc.h" // timer_from_us
#include "board/pgm.h" // READP
@@ -18,48 +19,31 @@
* Timers
****************************************************************/
-static uint16_t millis;
+static struct timer periodic_timer, *timer_list = &periodic_timer;
+static struct timer sentinel_timer;
-// Check if ready for a recurring periodic event
-uint8_t
-sched_check_periodic(uint16_t time, uint16_t *pnext)
-{
- uint16_t next = *pnext, cur;
- irqstatus_t flag = irq_save();
- cur = millis;
- irq_restore(flag);
- if ((int16_t)(cur - next) < 0)
- return 0;
- *pnext = cur + time;
- return 1;
-}
-
-static struct timer ms_timer, sentinel_timer, *timer_list = &ms_timer;
-
-// Default millisecond timer. This timer counts milliseconds. It
-// also simplifies the timer code by ensuring there is always a timer
-// on the timer list and that there is always a timer not more than
-// 1ms in the future.
+// The periodic_timer simplifies the timer code by ensuring there is
+// always a timer on the timer list and that there is always a timer
+// not more than 1ms in the future.
static uint_fast8_t
-ms_event(struct timer *t)
+periodic_event(struct timer *t)
{
- millis++;
timer_periodic();
- ms_timer.waketime += timer_from_us(1000);
- sentinel_timer.waketime = ms_timer.waketime + 0x80000000;
+ periodic_timer.waketime += timer_from_us(1000);
+ sentinel_timer.waketime = periodic_timer.waketime + 0x80000000;
return SF_RESCHEDULE;
}
-static struct timer ms_timer = {
- .func = ms_event,
+static struct timer periodic_timer = {
+ .func = periodic_event,
.next = &sentinel_timer,
};
// The sentinel timer is always the last timer on timer_list - its
// presence allows the code to avoid checking for NULL while
// traversing timer_list. Since sentinel_timer.waketime is always
-// equal to (ms_timer.waketime + 0x80000000) any added timer must
-// always have a waketime less than one of these two timers.
+// equal to (periodic_timer.waketime + 0x80000000) any added timer
+// must always have a waketime less than one of these two timers.
static uint_fast8_t
sentinel_event(struct timer *t)
{
@@ -171,14 +155,36 @@ void
sched_timer_shutdown(void)
{
timer_list = &deleted_timer;
- deleted_timer.waketime = ms_timer.waketime;
- deleted_timer.next = &ms_timer;
- ms_timer.next = &sentinel_timer;
+ deleted_timer.waketime = periodic_timer.waketime;
+ deleted_timer.next = &periodic_timer;
+ periodic_timer.next = &sentinel_timer;
}
DECL_SHUTDOWN(sched_timer_shutdown);
/****************************************************************
+ * Task waking
+ ****************************************************************/
+
+// Note that a task is ready to run
+void
+sched_wake_task(struct task_wake *w)
+{
+ writeb(&w->wake, 1);
+}
+
+// Check if a task is ready to run (as indicated by sched_wake_task)
+uint8_t
+sched_check_wake(struct task_wake *w)
+{
+ if (!readb(&w->wake))
+ return 0;
+ writeb(&w->wake, 0);
+ return 1;
+}
+
+
+/****************************************************************
* Shutdown processing
****************************************************************/
diff --git a/src/sched.h b/src/sched.h
index ad5c2c08..bb6bb975 100644
--- a/src/sched.h
+++ b/src/sched.h
@@ -20,11 +20,17 @@ struct timer {
enum { SF_DONE=0, SF_RESCHEDULE=1 };
+// Task waking struct
+struct task_wake {
+ uint8_t wake;
+};
+
// sched.c
-uint8_t sched_check_periodic(uint16_t time, uint16_t *pnext);
void sched_add_timer(struct timer*);
void sched_del_timer(struct timer *del);
unsigned int sched_timer_dispatch(void);
+void sched_wake_task(struct task_wake *w);
+uint8_t sched_check_wake(struct task_wake *w);
uint8_t sched_is_shutdown(void);
void sched_clear_shutdown(void);
void sched_try_shutdown(uint_fast8_t reason);