diff --git a/lambda-test/.cproject b/lambda-test/.cproject
index ef6bacc..b394c0e 100644
--- a/lambda-test/.cproject
+++ b/lambda-test/.cproject
@@ -8,21 +8,20 @@
-
-
-
+
+
-
+
-
+
+
+
+
+
@@ -53,15 +55,22 @@
-
+
-
+
+
+
+
-
+
+
+
+
+
diff --git a/lambda-test/.gitignore b/lambda-test/.gitignore
index 49d3023..93e51f0 100644
--- a/lambda-test/.gitignore
+++ b/lambda-test/.gitignore
@@ -1,3 +1,4 @@
/Release/
/lambda-test.elf
/lambda-test.hex
+/Debug/
diff --git a/lambda-test/.project b/lambda-test/.project
index d072cdc..e68be51 100644
--- a/lambda-test/.project
+++ b/lambda-test/.project
@@ -25,4 +25,11 @@
org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
de.innot.avreclipse.core.avrnature
+
+
+ lambda
+ 2
+ /data/Job/git/lambda-avr/lambda
+
+
diff --git a/lambda-test/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/lambda-test/.settings/org.eclipse.cdt.managedbuilder.core.prefs
new file mode 100644
index 0000000..9234061
--- /dev/null
+++ b/lambda-test/.settings/org.eclipse.cdt.managedbuilder.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/CPATH/delimiter=\:
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/CPATH/operation=remove
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/C_INCLUDE_PATH/delimiter=\:
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/C_INCLUDE_PATH/operation=remove
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/append=true
+environment/buildEnvironmentInclude/de.innot.avreclipse.configuration.app.debug.1035318481/appendContributed=true
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1035318481/LIBRARY_PATH/delimiter=\:
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1035318481/LIBRARY_PATH/operation=remove
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1035318481/append=true
+environment/buildEnvironmentLibrary/de.innot.avreclipse.configuration.app.debug.1035318481/appendContributed=true
diff --git a/lambda-test/display-test.c b/lambda-test/display-test.c
index 172a6f0..f88625a 100644
--- a/lambda-test/display-test.c
+++ b/lambda-test/display-test.c
@@ -40,6 +40,8 @@
assertTrue(beepLength == 1);
cycleDisplay();
+ assertTrue(position == displayPosAirgate);
+ cycleDisplay();
assertTrue(position == displayPosHeater);
cycleDisplay();
assertTrue(position == displayPosLastText);
diff --git a/lambda-test/interrupts-test.c b/lambda-test/interrupts-test.c
index 1ed25af..90512a7 100644
--- a/lambda-test/interrupts-test.c
+++ b/lambda-test/interrupts-test.c
@@ -45,11 +45,14 @@
initInterrupts();
// ADC interrupt enabled
- assertTrue(bit_is_set(ADCSRA, ADIE));
+ // assertTrue(bit_is_set(ADCSRA, ADIE));
// timer0 compare match A interrupt enabled
assertTrue(bit_is_set(TIMSK0, OCIE0A));
+ // timer2 compare match A interrupt enabled
+ assertTrue(bit_is_set(TIMSK2, OCIE2A));
+
// USART RX complete interrupt 0 enabled
assertTrue(bit_is_set(UCSR0B, RXCIE0));
diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c
index 864e5c5..42909bf 100644
--- a/lambda-test/lambda-test.c
+++ b/lambda-test/lambda-test.c
@@ -42,11 +42,12 @@
runClass(commandClass);
runClass(displayClass);
runClass(integersClass);
- runClass(interruptsClass);
runClass(rulesClass);
runClass(sensorsClass);
runClass(stringsClass);
runClass(usartClass);
+ // run this one last since the timers interfere with some tests
+ runClass(interruptsClass);
endSuite();
while (1) {
diff --git a/lambda-test/rules-test.c b/lambda-test/rules-test.c
index 66a26b5..5bf79b6 100644
--- a/lambda-test/rules-test.c
+++ b/lambda-test/rules-test.c
@@ -21,21 +21,31 @@
extern int8_t state;
extern Rule rules[];
+static void stepUntilDone(void) {
+ while (isAirgateBusy()) {
+ makeSteps();
+ }
+ makeSteps();
+}
+
static bool testAirgate50(void) {
Measurement meas = {0, 0, 0, 0};
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = burning_down;
reason(meas);
assertFalse(rules[0].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[0].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
reason(meas);
assertFalse(rules[0].fired);
@@ -44,27 +54,32 @@
meas.lambda = LAMBDA_TOO_LEAN;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = burning_down;
reason(meas);
assertFalse(rules[0].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[0].fired);
resetRules(true);
+ resetAirgate(AIRGATE_50);
state = firing_up;
reason(meas);
- assertTrue(rules[0].fired);
- assertTrue(50 == getAirgate());
-
- // should not fire if airgate == 50
- resetRules(false);
- state = firing_up;
- reason(meas);
+ stepUntilDone();
assertFalse(rules[0].fired);
- assertTrue(50 == getAirgate());
+ assertTrue(AIRGATE_50 == getAirgate());
+
+ resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
+ state = firing_up;
+ reason(meas);
+ stepUntilDone();
+ assertTrue(rules[0].fired);
+ assertTrue(AIRGATE_50 == getAirgate());
cancelAlert();
@@ -76,16 +91,19 @@
Measurement meas = {999, 0, 0, 0};
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
reason(meas);
assertFalse(rules[1].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[1].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = burning_down;
reason(meas);
assertFalse(rules[1].fired);
@@ -94,20 +112,32 @@
meas.lambda = LAMBDA_TOO_LEAN;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
reason(meas);
assertFalse(rules[1].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[1].fired);
resetRules(true);
+ resetAirgate(AIRGATE_25);
state = burning_down;
reason(meas);
+ stepUntilDone();
+ assertFalse(rules[1].fired);
+ assertTrue(AIRGATE_25 == getAirgate());
+
+ resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
+ state = burning_down;
+ reason(meas);
+ stepUntilDone();
assertTrue(rules[1].fired);
- assertTrue(25 == getAirgate());
+ assertTrue(AIRGATE_25 == getAirgate());
cancelAlert();
@@ -119,16 +149,19 @@
Measurement meas = {999, 0, 0, 0};
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
reason(meas);
assertFalse(rules[2].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[2].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = burning_down;
reason(meas);
assertFalse(rules[2].fired);
@@ -137,20 +170,42 @@
meas.lambda = LAMBDA_MAX;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
reason(meas);
assertFalse(rules[2].fired);
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = undefined;
reason(meas);
assertFalse(rules[2].fired);
resetRules(true);
+ resetAirgate(AIRGATE_CLOSE);
state = burning_down;
reason(meas);
+ stepUntilDone();
+ assertFalse(rules[2].fired);
+ assertTrue(AIRGATE_CLOSE == getAirgate());
+
+ // airgate25 kicks in first and prevents airgateClose from running
+ // (airgate busy)
+ resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
+ state = burning_down;
+ reason(meas);
+ stepUntilDone();
+ assertFalse(rules[2].fired);
+ assertFalse(AIRGATE_CLOSE == getAirgate());
+
+ // now airgateClose kicks in
+ resetRules(true);
+ state = burning_down;
+ reason(meas);
+ stepUntilDone();
assertTrue(rules[2].fired);
- assertTrue(0 == getAirgate());
+ assertTrue(AIRGATE_CLOSE == getAirgate());
cancelAlert();
@@ -166,36 +221,41 @@
meas.tempI = TEMP_FIRE_OUT;
meas.lambda = LAMBDA_MAX;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
assertFalse(rules[3].fired);
meas.tempI = TEMP_FIRE_OUT + 1;
meas.lambda = LAMBDA_MAX;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
assertFalse(rules[3].fired);
meas.tempI = TEMP_FIRE_OUT;
meas.lambda = LAMBDA_TOO_RICH - 1;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
assertFalse(rules[3].fired);
meas.tempI = TEMP_FIRE_OUT + 1;
meas.lambda = LAMBDA_TOO_RICH - 1;
resetRules(true);
- setAirgate(50);
+ resetAirgate(AIRGATE_50);
reason(meas);
+ stepUntilDone();
assertFalse(rules[3].fired);
- assertTrue(50 == getAirgate());
+ assertTrue(AIRGATE_50 == getAirgate());
meas.tempI = TEMP_FIRE_OUT + 1;
meas.lambda = LAMBDA_TOO_RICH - 1;
resetRules(true);
- setAirgate(25);
+ resetAirgate(AIRGATE_25);
reason(meas);
+ stepUntilDone();
assertTrue(rules[3].fired);
- assertTrue(50 == getAirgate());
+ assertTrue(AIRGATE_50 == getAirgate());
cancelAlert();
@@ -211,30 +271,34 @@
meas.tempI = TEMP_AIRGATE_50;
meas.lambda = LAMBDA_TOO_LEAN + 1;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
assertFalse(rules[4].fired);
meas.tempI = TEMP_AIRGATE_50 + 1;
meas.lambda = 1300;
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
assertFalse(rules[4].fired);
meas.tempI = TEMP_AIRGATE_50 + 1;
meas.lambda = LAMBDA_TOO_LEAN + 1;
resetRules(true);
- setAirgate(50);
+ resetAirgate(AIRGATE_50);
reason(meas);
+ stepUntilDone();
assertFalse(rules[4].fired);
- assertTrue(50 == getAirgate());
+ assertTrue(AIRGATE_50 == getAirgate());
meas.tempI = TEMP_AIRGATE_50 + 1;
meas.lambda = LAMBDA_TOO_LEAN + 1;
resetRules(true);
- setAirgate(100);
+ resetAirgate(AIRGATE_OPEN);
reason(meas);
+ stepUntilDone();
assertTrue(rules[4].fired);
- assertTrue(50 == getAirgate());
+ assertTrue(AIRGATE_50 == getAirgate());
cancelAlert();
@@ -246,6 +310,7 @@
Measurement meas = {0, 0, 0, 0};
resetRules(true);
+ resetAirgate(AIRGATE_OPEN);
state = firing_up;
meas.tempI = 50;
@@ -285,18 +350,21 @@
setHeaterState(heaterStateOff);
resetRules(true);
+ resetAirgate(AIRGATE_50);
rules[6].fired = false;
- setAirgate(50);
reason(meas);
- assertTrue(50 == getAirgate());
+ stepUntilDone();
+ assertTrue(AIRGATE_50 == getAirgate());
assertTrue(heaterStateOff == getHeaterState());
assertFalse(rules[6].fired);
resetRules(true);
+ resetAirgate(AIRGATE_50);
rules[6].fired = false;
state = firing_up;
reason(meas);
- assertTrue(100 == getAirgate());
+ stepUntilDone();
+ assertTrue(AIRGATE_OPEN == getAirgate());
assertTrue(heaterStateOn == getHeaterState());
assertTrue(rules[6].fired);
diff --git a/lambda-test/usart-test.c b/lambda-test/usart-test.c
index d1a0619..bbfb5c5 100644
--- a/lambda-test/usart-test.c
+++ b/lambda-test/usart-test.c
@@ -8,9 +8,9 @@
*
*/
+#include "usart.h"
#include
#include "avrjunit.h"
-#include "usart.h"
/* Module usart */
diff --git a/lambda/airgate.c b/lambda/airgate.c
index fd172be..0df4769 100644
--- a/lambda/airgate.c
+++ b/lambda/airgate.c
@@ -134,3 +134,12 @@
_delay_ms(2);
}
}
+
+void resetAirgate(uint16_t const position) {
+ dir = 0;
+ pos = position << SCALE;
+ steps = 0;
+ done = 0;
+ ramp = 0;
+ speed = MIN_SPEED;
+}
diff --git a/lambda/airgate.h b/lambda/airgate.h
index 0f2b198..6838014 100644
--- a/lambda/airgate.h
+++ b/lambda/airgate.h
@@ -58,4 +58,9 @@
*/
void setSleepMode(bool const on);
+/**
+ * Resets to initial state and the given position. For unit tests.
+ */
+void resetAirgate(uint16_t const position);
+
#endif /* AIRGATE_H_ */
diff --git a/lambda/rules.c b/lambda/rules.c
index 7429615..ed4fcc4 100644
--- a/lambda/rules.c
+++ b/lambda/rules.c
@@ -66,7 +66,7 @@
* and the temperature has reached TEMP_AIRGATE_50.
*/
static void airgate50(bool* const fired, Measurement const meas) {
- if ((state == firing_up) &&
+ if ((state == firing_up) && ! isAirgateBusy() &&
meas.tempI >= TEMP_AIRGATE_50 &&
meas.lambda >= LAMBDA_TOO_LEAN &&
getAirgate() != AIRGATE_50) {
@@ -81,7 +81,7 @@
* temperature went below TEMP_AIRGATE_25.
*/
static void airgate25(bool* const fired, Measurement const meas) {
- if (state == burning_down &&
+ if (state == burning_down && ! isAirgateBusy() &&
meas.tempI < TEMP_AIRGATE_25 &&
meas.lambda >= LAMBDA_TOO_LEAN && getAirgate() > AIRGATE_25) {
setAirgate(AIRGATE_25);
@@ -95,7 +95,8 @@
* temperature went below TEMP_AIRGATE_0 (no more flames).
*/
static void airgateClose(bool* const fired, Measurement const meas) {
- if (state == burning_down && meas.tempI < TEMP_AIRGATE_0 &&
+ if (state == burning_down && ! isAirgateBusy() &&
+ meas.tempI < TEMP_AIRGATE_0 &&
meas.lambda >= LAMBDA_MAX && getAirgate() > AIRGATE_CLOSE) {
setHeaterState(heaterStateOff);
closeAirgateAndSleep();
@@ -114,7 +115,8 @@
* out of the chimney.
*/
static void tooRich(bool* const fired, Measurement const meas) {
- if (meas.tempI > TEMP_FIRE_OUT && meas.lambda < LAMBDA_TOO_RICH &&
+ if (! isAirgateBusy() &&
+ meas.tempI > TEMP_FIRE_OUT && meas.lambda < LAMBDA_TOO_RICH &&
getHeaterState() == heaterStateReady && getAirgate() < AIRGATE_50) {
setAirgate(AIRGATE_50);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_50_0), PSTR(""), false);
@@ -127,7 +129,8 @@
* gate to 50%.
*/
static void tooLean(bool* const fired, Measurement const meas) {
- if (meas.tempI > TEMP_AIRGATE_50 && meas.lambda > LAMBDA_TOO_LEAN &&
+ if (! isAirgateBusy() &&
+ meas.tempI > TEMP_AIRGATE_50 && meas.lambda > LAMBDA_TOO_LEAN &&
getHeaterState() == heaterStateReady && getAirgate() > AIRGATE_50) {
setAirgate(AIRGATE_50);
alert_P(BEEPS, LENGTH, TONE, PSTR(MSG_AIRGATE_50_0), PSTR(""), false);
@@ -265,7 +268,7 @@
// evaluation of the fire state and rules applied
// at every MEAS_INT'th measurement
- if (measCount == MEAS_INT && ! isAirgateBusy()) {
+ if (measCount == MEAS_INT) {
measCount = 0;
for (size_t i = 0; i < ARRAY_LENGTH(rules); i++) {
@@ -300,7 +303,6 @@
initQueue(TEMP_INIT);
measCount = MEAS_INT;
state = undefined;
- setAirgate(AIRGATE_OPEN);
}
for (size_t i = 0; i < ARRAY_LENGTH(rules); i++) {