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 @@ - - - + + + - + + + + + 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++) {