summaryrefslogtreecommitdiffstats
path: root/pressure_control/firmware
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2009-05-03 12:35:53 +0200
committerMichael Buesch <mb@bu3sch.de>2009-05-03 12:35:53 +0200
commitaa5604d118bc89e85c8230562080c034bfc9df17 (patch)
treeea99685ddc38ed4badad8fe6e17db162ffad6e01 /pressure_control/firmware
parent44b0b0d80254064868c905b88826fda14010860c (diff)
downloadcnc-aa5604d118bc89e85c8230562080c034bfc9df17.tar.xz
cnc-aa5604d118bc89e85c8230562080c034bfc9df17.zip
pressure-control: Implement idle-release of valves through timer.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Diffstat (limited to 'pressure_control/firmware')
-rw-r--r--pressure_control/firmware/Makefile2
-rw-r--r--pressure_control/firmware/main.c56
-rw-r--r--pressure_control/firmware/main.h21
-rw-r--r--pressure_control/firmware/remote.c13
-rw-r--r--pressure_control/firmware/remote.h1
-rw-r--r--pressure_control/firmware/valves.c25
-rw-r--r--pressure_control/firmware/valves.h5
7 files changed, 90 insertions, 33 deletions
diff --git a/pressure_control/firmware/Makefile b/pressure_control/firmware/Makefile
index a4d380e..1e965be 100644
--- a/pressure_control/firmware/Makefile
+++ b/pressure_control/firmware/Makefile
@@ -27,7 +27,7 @@ main.o: util.h calibration.h valves.h sensor.h remote.h main.h
util.o: util.h calibration.h
-valves.o: util.h valves.h
+valves.o: util.h valves.h main.h
sensor.o: util.h sensor.h
diff --git a/pressure_control/firmware/main.c b/pressure_control/firmware/main.c
index a82a503..af779a7 100644
--- a/pressure_control/firmware/main.c
+++ b/pressure_control/firmware/main.c
@@ -40,6 +40,9 @@ struct eeprom_data {
struct pressure_config cfg;
/* The pressure state data. */
struct pressure_state state;
+/* The 1000Hz jiffies counter */
+static jiffies_t jiffies_counter;
+
/* EEPROM contents */
static struct eeprom_data EEMEM eeprom = {
@@ -106,12 +109,22 @@ void sensor_result(uint16_t mbar)
state.needs_checking = 1;
}
+jiffies_t get_jiffies(void)
+{
+ uint16_t sreg;
+ jiffies_t j;
+
+ sreg = irq_disable_save();
+ j = jiffies_counter;
+ irq_restore(sreg);
+
+ return j;
+}
+
/* 1kHz system timer. */
ISR(TIMER1_COMPA_vect)
{
- if (state.sensor_trigger_cnt > 0)
- state.sensor_trigger_cnt--;
- remote_1khz_work();
+ jiffies_counter++;
}
void system_timer_init(void)
@@ -225,28 +238,33 @@ int main(void)
print("Monitoring...\n");
remote_work();
remote_notify_restart();
+ sensor_trigger_read();
while (1) {
+ static jiffies_t next_sensor_trigger;
+ static bool need_sensor_trigger;
+ jiffies_t now;
+
mb();
- if (state.device_enabled) {
- if (state.sensor_trigger_cnt == 0) {
- /* It's time for triggering another
- * sensor measurement. */
- state.sensor_trigger_cnt = -1;
- mb();
- sensor_trigger_read();
- }
- if (state.needs_checking) {
+ now = get_jiffies();
+ if (state.needs_checking) {
+ if (state.device_enabled)
check_pressure();
- /* Trigger another measurement in
- * a few milliseconds. */
- state.sensor_trigger_cnt = 35;
- state.needs_checking = 0;
- mb();
- }
- } else {
+ /* Trigger another measurement in
+ * a few milliseconds. */
state.needs_checking = 0;
+ next_sensor_trigger = now + msec_to_jiffies(35);
+ mb();
+ need_sensor_trigger = 1;
+ }
+ if (need_sensor_trigger &&
+ time_after(now, next_sensor_trigger)) {
+ /* It's time for triggering another
+ * sensor measurement. */
+ need_sensor_trigger = 0;
+ sensor_trigger_read();
}
remote_work();
+ valves_work();
wdt_reset();
}
}
diff --git a/pressure_control/firmware/main.h b/pressure_control/firmware/main.h
index edb8694..d8cb6aa 100644
--- a/pressure_control/firmware/main.h
+++ b/pressure_control/firmware/main.h
@@ -6,6 +6,27 @@
#include <stdint.h>
+typedef uint16_t jiffies_t;
+typedef int16_t s_jiffies_t;
+
+/* Jiffies timing helpers derived from the Linux Kernel sources.
+ * These inlines deal with timer wrapping correctly.
+ *
+ * time_after(a, b) returns true if the time a is after time b.
+ *
+ * Do this with "<0" and ">=0" to only test the sign of the result. A
+ * good compiler would generate better code (and a really good compiler
+ * wouldn't care). Gcc is currently neither.
+ */
+#define time_after(a, b) ((s_jiffies_t)(b) - (s_jiffies_t)(a) < 0)
+#define time_before(a, b) time_after(b, a)
+
+#define JIFFIES_PER_SECOND 1000
+#define msec_to_jiffies(msec) ((jiffies_t)((uint32_t)JIFFIES_PER_SECOND * (uint32_t)(msec) / (uint32_t)1000))
+
+jiffies_t get_jiffies(void);
+
+
struct pressure_config {
/* Desired pressure in mBar */
uint16_t desired;
diff --git a/pressure_control/firmware/remote.c b/pressure_control/firmware/remote.c
index f41c9ed..6383339 100644
--- a/pressure_control/firmware/remote.c
+++ b/pressure_control/firmware/remote.c
@@ -362,6 +362,9 @@ void print_hex(uint8_t number)
/* Maintanance work. Called with IRQs enabled. */
void remote_work(void)
{
+ static jiffies_t last_timeout_check;
+ jiffies_t now = get_jiffies();
+
if (rx_msg_valid) {
handle_received_message();
mb();
@@ -372,15 +375,13 @@ void remote_work(void)
rx_softirq = 0;
usart_handle_rx_irq();
}
+ if (last_timeout_check != now) {
+ last_timeout_check = now;
+ usart_rx_timeout_check();
+ }
sei();
}
-/* Maintanance work. Called at a frequency of 1KHz with IRQs disabled. */
-void remote_1khz_work(void)
-{
- usart_rx_timeout_check();
-}
-
void remote_pressure_change_notification(uint16_t mbar)
{
struct remote_message msg;
diff --git a/pressure_control/firmware/remote.h b/pressure_control/firmware/remote.h
index 85afd92..709a1f0 100644
--- a/pressure_control/firmware/remote.h
+++ b/pressure_control/firmware/remote.h
@@ -85,7 +85,6 @@ void remote_pressure_change_notification(uint16_t mbar);
void remote_notify_restart(void);
void remote_work(void);
-void remote_1khz_work(void);
void remote_init(void);
#endif /* REMOTE_H_ */
diff --git a/pressure_control/firmware/valves.c b/pressure_control/firmware/valves.c
index 75d4606..86ea85b 100644
--- a/pressure_control/firmware/valves.c
+++ b/pressure_control/firmware/valves.c
@@ -20,6 +20,7 @@
#include "valves.h"
#include "util.h"
+#include "main.h"
#include <avr/io.h>
@@ -34,6 +35,8 @@
static uint8_t current_global_state = 0xFF;
+static bool need_switch_to_idle;
+static jiffies_t switch_to_idle_time;
void valve0_switch(uint8_t state)
@@ -56,7 +59,6 @@ void valve1_switch(uint8_t state)
void valves_global_switch(uint8_t state)
{
-
if (state == current_global_state)
return;
current_global_state = state;
@@ -65,9 +67,6 @@ void valves_global_switch(uint8_t state)
case VALVES_IDLE:
valve0_switch(VALVE_STATE_12);
valve1_switch(VALVE_STATE_12);
- valve_wait_toggle();
- valve0_switch(VALVE_STATE_IDLE);
- valve1_switch(VALVE_STATE_IDLE);
break;
case VALVES_FLOW_IN:
valve1_switch(VALVE_STATE_12);
@@ -78,6 +77,18 @@ void valves_global_switch(uint8_t state)
valve1_switch(VALVE_STATE_14);
break;
}
+ switch_to_idle_time = get_jiffies() + msec_to_jiffies(VALVE_TOGGLE_MSEC);
+ need_switch_to_idle = 1;
+}
+
+void valves_work(void)
+{
+ if (need_switch_to_idle &&
+ time_after(get_jiffies(), switch_to_idle_time)) {
+ need_switch_to_idle = 0;
+ valve0_switch(VALVE_STATE_IDLE);
+ valve1_switch(VALVE_STATE_IDLE);
+ }
}
uint8_t valves_get_global_state(void)
@@ -101,7 +112,11 @@ void valves_shutdown(void)
void valves_emergency_state(void)
{
- valves_init();
+ valves_ddr_setup();
+ valves_global_switch(VALVES_IDLE);
+ valve_wait_toggle();
+ valve0_switch(VALVE_STATE_IDLE);
+ valve1_switch(VALVE_STATE_IDLE);
}
void valves_init(void)
diff --git a/pressure_control/firmware/valves.h b/pressure_control/firmware/valves.h
index 0929682..1b50b3a 100644
--- a/pressure_control/firmware/valves.h
+++ b/pressure_control/firmware/valves.h
@@ -20,13 +20,16 @@ enum valve_state {
VALVE_STATE_14,
};
+#define VALVE_TOGGLE_MSEC 10
+
/* Wait for the valve to toggle from one position to another. */
static inline void valve_wait_toggle(void)
{
- mdelay(10);
+ mdelay(VALVE_TOGGLE_MSEC);
}
void valves_init(void);
+void valves_work(void);
void valves_emergency_state(void);
void valves_shutdown(void);
void valves_global_switch(uint8_t global_state);
bues.ch cgit interface