diff --git a/lambda-test/Makefile b/lambda-test/Makefile index 051c63a..76c37ca 100644 --- a/lambda-test/Makefile +++ b/lambda-test/Makefile @@ -14,7 +14,8 @@ ## If you've split your program into multiple .c / .h files, ## include the additional source (in same directory) here -LOCAL_SOURCE = avrjunit.c +LOCAL_SOURCE = avrjunit.c adc-test.c command-test.c display-test.c \ +integers-test.c interrupts-test.c sensors-test.c strings-test.c ## Here you can link to one more directory (and multiple .c files) EXTRA_SOURCE_DIR = ../lambda/ diff --git a/lambda-test/adc-test.c b/lambda-test/adc-test.c new file mode 100644 index 0000000..bb54600 --- /dev/null +++ b/lambda-test/adc-test.c @@ -0,0 +1,60 @@ +/* + * adc-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include "avrjunit.h" +#include "interrupts.h" +#include "adc.h" +#include "pins.h" + +/* Module adc */ + +bool testSetupADC(void) { + setupADC(); + + // AVCC is set as AREF + assertTrue(bit_is_set(ADMUX, REFS0)); + // digital inputs are disabled + uint8_t adcPorts = (1 << ADC_TEMPI) | (1 << ADC_TEMPO) | (1 << ADC_LAMBDA); + assertTrue((DIDR0 & adcPorts) == adcPorts); + // ADC clock prescaler/8 + uint8_t prescalerBy8 = (1 << ADPS1) | (1 << ADPS0); + assertTrue((ADCSRA & prescalerBy8) == prescalerBy8); + // ADC enabled + assertTrue(bit_is_set(ADCSRA, ADEN)); + + return true; +} + +bool testGetVoltage(void) { + initInterrupts(); + setupADC(); + setupSleepMode(); + + // enable pull-up resistor so the measured voltage + // should be close to AREF + PORTC |= (1 << PC1); + + uint16_t mV = getVoltage(PC1); + + return mV > 4900; +} + +/* Test "class" */ +const char adc_P[] PROGMEM = "adc"; + +/* Test names */ +const char testSetupADC_P[] PROGMEM = "testSetupADC"; +const char testGetVoltage_P[] PROGMEM = "testGetVoltage"; + +/* Tests */ +TestCase const adcTests[] = { + {adc_P, testSetupADC_P, testSetupADC}, + {adc_P, testGetVoltage_P, testGetVoltage} +}; diff --git a/lambda-test/command-test.c b/lambda-test/command-test.c new file mode 100644 index 0000000..0910059 --- /dev/null +++ b/lambda-test/command-test.c @@ -0,0 +1,47 @@ +/* + * command-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include "avrjunit.h" +#include "command.h" + +/* Module command */ + +bool testIsSimulation(void) { + assertFalse(isSimulation()); + runCommand("se"); + assertTrue(isSimulation()); + runCommand("sd"); + assertFalse(isSimulation()); + + return true; +} + +bool testIsLogging(void) { + assertFalse(isLogging()); + runCommand("le"); + assertTrue(isLogging()); + runCommand("ld"); + assertFalse(isLogging()); + + return true; +} + +/* Test "class" */ +const char command_P[] PROGMEM = "command"; + +/* Test names */ +const char testIsSimulation_P[] PROGMEM = "testIsSimulation"; +const char testIsLogging_P[] PROGMEM = "testIsLogging"; + +/* Tests */ +TestCase const commandTests[] = { + {command_P, testIsSimulation_P, testIsSimulation}, + {command_P, testIsLogging_P, testIsLogging}, +}; diff --git a/lambda-test/display-test.c b/lambda-test/display-test.c new file mode 100644 index 0000000..4c68053 --- /dev/null +++ b/lambda-test/display-test.c @@ -0,0 +1,167 @@ +/* + * lambda-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include "avrjunit.h" +#include "display.h" +#include "sensors.h" +#include "alert.h" + +/* Module display */ + +bool testCycle(void) { + extern uint8_t position; + extern bool updatePending; + + extern uint8_t beepCount; + extern uint16_t beepLength; + + updatePending = false; + + assertTrue(position == 0); + assertFalse(updatePending); + + cycleDisplay(); + assertTrue(position == 1); + assertTrue(updatePending); + assertTrue(beepCount == 1); + assertTrue(beepLength == 2); + + cycleDisplay(); + assertTrue(position == 0); + + return true; +} + +bool testCycleCancelAlert(void) { + extern uint8_t position; + extern bool updatePending; + + updatePending = false; + + alert(1, 1, "", ""); + assertTrue(isAlertActive()); + + cycleDisplay(); + assertFalse(isAlertActive()); + assertTrue(position == 0); + assertTrue(updatePending); + + return true; +} + +bool testUpdateMeas(void) { + extern bool updatePending; + extern Measurement measLatest; + extern Measurement measMax; // = {0, 0, 2000}; + + updatePending = false; + + // initial measurements + assertTrue(measLatest.tempI == 0); + assertTrue(measLatest.tempO == 0); + assertTrue(measLatest.lambda == 0); + // initial max measurements + assertTrue(measMax.tempI == 0); + assertTrue(measMax.tempO == 0); + assertTrue(measMax.lambda == 2000); + + Measurement meas1 = {1, 2, 3}; + updateMeas(meas1); + // updated measurements + assertTrue(measLatest.tempI == 1); + assertTrue(measLatest.tempO == 2); + assertTrue(measLatest.lambda == 3); + // updated max measurements + assertTrue(measMax.tempI == 1); + assertTrue(measMax.tempO == 2); + assertTrue(measMax.lambda == 3); + assertTrue(updatePending); + + Measurement meas2 = {0, 0, 10}; + updateMeas(meas2); + // updated max measurements + assertTrue(measMax.tempI == 1); + assertTrue(measMax.tempO == 2); + assertTrue(measMax.lambda == 3); + + return true; +} + +bool testResetMeas(void) { + extern bool updatePending; + extern Measurement measLatest; + extern Measurement measMax; + + updatePending = false; + + resetMeas(); + // reset max measurements + assertTrue(measMax.tempI == 0); + assertTrue(measMax.tempO == 0); + assertTrue(measMax.lambda == 2000); + assertTrue(updatePending); + + return true; +} + +bool testUpdateDisplayIfPending(void) { + extern bool updatePending; + + updatePending = true; + + updateDisplayIfPending(); + assertFalse(updatePending); + + return true; +} + +bool testUpdateDisplayIfPendingAlertActive(void) { + extern bool updatePending; + + updatePending = true; + alert(1, 1, "", ""); + assertTrue(isAlertActive()); + + // update should be skipped if alert is active + updateDisplayIfPending(); + assertTrue(updatePending); + + return true; +} + +bool testDisplayText(void) { + // won't actually display anything + displayText("testDisplayText", "testDisplayTextLineTooLong"); + + return true; +} + +/* Test "class" */ +const char display_P[] PROGMEM = "display"; + +/* Test names */ +const char testCycle_P[] PROGMEM = "testCycle"; +const char testCycleCancelAlert_P[] PROGMEM = "testCycleCancelAlert"; +const char testUpdateMeas_P[] PROGMEM = "testUpdateMeas"; +const char testResetMeas_P[] PROGMEM = "testResetMeas"; +const char testUpdateDisplayIfPending_P[] PROGMEM = "testUpdateDisplayIfPending"; +const char testUpdateDisplayIfPendingAlertActive_P[] PROGMEM = "testUpdateDisplayIfPendingAlertActive"; +const char testDisplayText_P[] PROGMEM = "testDisplayText"; + +/* Tests */ +TestCase const displayTests[] = { + {display_P, testCycle_P, testCycle}, + {display_P, testCycleCancelAlert_P, testCycleCancelAlert}, + {display_P, testUpdateMeas_P, testUpdateMeas}, + {display_P, testResetMeas_P, testResetMeas}, + {display_P, testUpdateDisplayIfPending_P, testUpdateDisplayIfPending}, + {display_P, testUpdateDisplayIfPendingAlertActive_P, testUpdateDisplayIfPendingAlertActive}, + {display_P, testDisplayText_P, testDisplayText} +}; diff --git a/lambda-test/integers-test.c b/lambda-test/integers-test.c new file mode 100644 index 0000000..ce1a60a --- /dev/null +++ b/lambda-test/integers-test.c @@ -0,0 +1,103 @@ +/* + * integers-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include "avrjunit.h" +#include "integers.h" + +/* Module integers */ + +bool testDivRoundNearest(void) { + assertTrue(divRoundNearest(4, 2) == 2); + assertTrue(divRoundNearest(5, 2) == 3); + assertTrue(divRoundNearest(10, 3) == 3); + + return true; +} + +bool testDivRoundNearestNumNeg(void) { + assertTrue(divRoundNearest(-4, 2) == -2); + assertTrue(divRoundNearest(-5, 2) == -3); + assertTrue(divRoundNearest(-10, 3) == -3); + + return true; +} + +bool testDivRoundNearestDenNeg(void) { + assertTrue(divRoundNearest(4, -2) == -2); + assertTrue(divRoundNearest(5, -2) == -3); + assertTrue(divRoundNearest(10, -3) == -3); + + return true; +} + +bool testDivRoundNearestBothNeg(void) { + assertTrue(divRoundNearest(-4, -2) == 2); + assertTrue(divRoundNearest(-5, -2) == 3); + assertTrue(divRoundNearest(-10, -3) == 3); + + return true; +} + +bool testDivRoundUp(void) { + assertTrue(divRoundUp(4, 2) == 2); + assertTrue(divRoundUp(5, 2) == 3); + assertTrue(divRoundUp(10, 3) == 4); + + return true; +} + +bool testDivRoundUpNumNeg(void) { + assertTrue(divRoundUp(-4, 2) == -2); + assertTrue(divRoundUp(-5, 2) == -3); + assertTrue(divRoundUp(-10, 3) == -4); + + return true; +} + +bool testDivRoundUpDenNeg(void) { + assertTrue(divRoundUp(4, -2) == -2); + assertTrue(divRoundUp(5, -2) == -3); + assertTrue(divRoundUp(10, -3) == -4); + + return true; +} + +bool testDivRoundUpBothNeg(void) { + assertTrue(divRoundUp(-4, -2) == 2); + assertTrue(divRoundUp(-5, -2) == 3); + assertTrue(divRoundUp(-10, -3) == 4); + + return true; +} + +/* Test "class" */ +const char integers_P[] PROGMEM = "integers"; + +/* Test names */ +const char testDivRoundNearest_P[] PROGMEM = "testDivRoundNearest"; +const char testDivRoundNearestNumNeg_P[] PROGMEM = "testDivRoundNearestNumNeg"; +const char testDivRoundNearestDenNeg_P[] PROGMEM = "testDivRoundNearestDenNeg"; +const char testDivRoundNearestBothNeg_P[] PROGMEM = "testDivRoundNearestBothNeg"; +const char testDivRoundUp_P[] PROGMEM = "testDivRoundUp"; +const char testDivRoundUpNumNeg_P[] PROGMEM = "testDivRoundUpNumNeg"; +const char testDivRoundUpDenNeg_P[] PROGMEM = "testDivRoundUpDenNeg"; +const char testDivRoundUpBothNeg_P[] PROGMEM = "testDivRoundUpBothNeg"; + +/* Tests */ +TestCase const integersTests[] = { + {integers_P, testDivRoundNearest_P, testDivRoundNearest}, + {integers_P, testDivRoundNearestNumNeg_P, testDivRoundNearestNumNeg}, + {integers_P, testDivRoundNearestDenNeg_P, testDivRoundNearestDenNeg}, + {integers_P, testDivRoundNearestBothNeg_P, testDivRoundNearestBothNeg}, + {integers_P, testDivRoundUp_P, testDivRoundUp}, + {integers_P, testDivRoundUpNumNeg_P, testDivRoundUpNumNeg}, + {integers_P, testDivRoundUpDenNeg_P, testDivRoundUpDenNeg}, + {integers_P, testDivRoundUpBothNeg_P, testDivRoundUpBothNeg}, +}; diff --git a/lambda-test/interrupts-test.c b/lambda-test/interrupts-test.c new file mode 100644 index 0000000..0757731 --- /dev/null +++ b/lambda-test/interrupts-test.c @@ -0,0 +1,92 @@ +/* + * lambda-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include "avrjunit.h" +#include "interrupts.h" + +/* Module interrupts */ + +bool testSetupPorts(void) { + setupPorts(); + + // test that the pull-up resistor for the mouton is enabled + assertTrue(bit_is_set(PORTB, PB0)); + + // test that the beep output pin is enabled + assertTrue(bit_is_set(DDRB, PB1)); + + return true; +} + +bool testSetupSleepMode(void) { + setupSleepMode(); + + // set_sleep_mode(SLEEP_MODE_IDLE); + assertFalse(bit_is_set(SMCR, SM2)); + assertFalse(bit_is_set(SMCR, SM1)); + assertFalse(bit_is_set(SMCR, SM0)); + + return true; +} + +bool testInitInterrupts(void) { + initInterrupts(); + + // ADC interrupt enabled + assertTrue(bit_is_set(ADCSRA, ADIE)); + // PC interrupts enabled + // assertTrue(bit_is_set(PCICR, PCIE0)); + // assertTrue(bit_is_set(PCMSK0, PB0)); + // enable timer 0 overflow interrupt + assertTrue(bit_is_set(TIMSK0, TOIE0)); + // USART RX complete interrupt 0 enabled + assertTrue(bit_is_set(UCSR0B, RXCIE0)); + + // sei(); // enable global interrupts + assertTrue(bit_is_set(SREG, SREG_I)); + + return true; +} + +bool testInitTimers(void) { + initTimers(); + + // timer0 clock prescaler /64 = 15.625 kHz overflowing every 16.2 ms + uint8_t prescalerBy64 = (1 << CS00) | (1 << CS01); + assertTrue((TCCR0B & prescalerBy64) == prescalerBy64); + + // timer1 Clear Timer on Compare Match mode, TOP OCR1A + assertTrue(bit_is_set(TCCR1B, WGM12)); + // timer1 clock prescaler/8 + assertTrue(bit_is_set(TCCR1B, CS11)); + // toggles PB1 at 7.8 kHz generating a 3.9 kHz beep + // assertTrue(OCR1A == 15); + // 1.8 kHz is less noisy on the small piezo beeper + assertTrue(OCR1A == 31); + + return true; +} + +/* Test "class" */ +const char interrupts_P[] PROGMEM = "interrupts"; + +/* Test names */ +const char testSetupPorts_P[] PROGMEM = "testSetupPorts"; +const char testSetupSleepMode_P[] PROGMEM = "testSetupSleepMode"; +const char testInitInterrupts_P[] PROGMEM = "testInitInterrupts"; +const char testInitTimers_P[] PROGMEM = "testInitTimers"; + +/* Tests */ +TestCase const interruptsTests[] = { + {interrupts_P, testSetupPorts_P, testSetupPorts}, + {interrupts_P, testSetupSleepMode_P, testSetupSleepMode}, + {interrupts_P, testInitInterrupts_P, testInitInterrupts}, + {interrupts_P, testInitTimers_P, testInitTimers}, +}; diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c index b795838..2b35879 100644 --- a/lambda-test/lambda-test.c +++ b/lambda-test/lambda-test.c @@ -16,602 +16,28 @@ * http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung */ -#include -#include -#include #include -#include -#include -#include -#include #include "USART.h" #include "avrjunit.h" -#include "interrupts.h" -#include "adc.h" -#include "alert.h" -#include "integers.h" -#include "sensors.h" -#include "display.h" -#include "pins.h" -#include "command.h" -#include "strings.h" - -static TableEntry const testTable[] = { - {10, 10}, - {20, 20} -}; - -/* Module adc */ - -bool testSetupADC(void) { - setupADC(); - - // AVCC is set as AREF - assertTrue(bit_is_set(ADMUX, REFS0)); - // digital inputs are disabled - uint8_t adcPorts = (1 << ADC_TEMPI) | (1 << ADC_TEMPO) | (1 << ADC_LAMBDA); - assertTrue((DIDR0 & adcPorts) == adcPorts); - // ADC clock prescaler/8 - uint8_t prescalerBy8 = (1 << ADPS1) | (1 << ADPS0); - assertTrue((ADCSRA & prescalerBy8) == prescalerBy8); - // ADC enabled - assertTrue(bit_is_set(ADCSRA, ADEN)); - - return true; -} - -bool testGetVoltage(void) { - initInterrupts(); - setupADC(); - setupSleepMode(); - - // enable pull-up resistor so the measured voltage - // should be close to AREF - PORTC |= (1 << PC1); - - uint16_t mV = getVoltage(PC1); - - return mV > 4900; -} - -/* Module command */ - -bool testIsSimulation(void) { - assertFalse(isSimulation()); - runCommand("se"); - assertTrue(isSimulation()); - runCommand("sd"); - assertFalse(isSimulation()); - - return true; -} - -bool testIsLogging(void) { - assertFalse(isLogging()); - runCommand("le"); - assertTrue(isLogging()); - runCommand("ld"); - assertFalse(isLogging()); - - return true; -} - -/* Module display */ - -bool testCycle(void) { - extern uint8_t position; - extern bool updatePending; - - extern uint8_t beepCount; - extern uint16_t beepLength; - - updatePending = false; - - assertTrue(position == 0); - assertFalse(updatePending); - - cycleDisplay(); - assertTrue(position == 1); - assertTrue(updatePending); - assertTrue(beepCount == 1); - assertTrue(beepLength == 2); - - cycleDisplay(); - assertTrue(position == 0); - - return true; -} - -bool testCycleCancelAlert(void) { - extern uint8_t position; - extern bool updatePending; - - updatePending = false; - - alert(1, 1, "", ""); - assertTrue(isAlertActive()); - - cycleDisplay(); - assertFalse(isAlertActive()); - assertTrue(position == 0); - assertTrue(updatePending); - - return true; -} - -bool testUpdateMeas(void) { - extern bool updatePending; - extern Measurement measLatest; - extern Measurement measMax; // = {0, 0, 2000}; - - updatePending = false; - - // initial measurements - assertTrue(measLatest.tempI == 0); - assertTrue(measLatest.tempO == 0); - assertTrue(measLatest.lambda == 0); - // initial max measurements - assertTrue(measMax.tempI == 0); - assertTrue(measMax.tempO == 0); - assertTrue(measMax.lambda == 2000); - - Measurement meas1 = {1, 2, 3}; - updateMeas(meas1); - // updated measurements - assertTrue(measLatest.tempI == 1); - assertTrue(measLatest.tempO == 2); - assertTrue(measLatest.lambda == 3); - // updated max measurements - assertTrue(measMax.tempI == 1); - assertTrue(measMax.tempO == 2); - assertTrue(measMax.lambda == 3); - assertTrue(updatePending); - - Measurement meas2 = {0, 0, 10}; - updateMeas(meas2); - // updated max measurements - assertTrue(measMax.tempI == 1); - assertTrue(measMax.tempO == 2); - assertTrue(measMax.lambda == 3); - - return true; -} - -bool testResetMeas(void) { - extern bool updatePending; - extern Measurement measLatest; - extern Measurement measMax; - - updatePending = false; - - resetMeas(); - // reset max measurements - assertTrue(measMax.tempI == 0); - assertTrue(measMax.tempO == 0); - assertTrue(measMax.lambda == 2000); - assertTrue(updatePending); - - return true; -} - -bool testUpdateDisplayIfPending(void) { - extern bool updatePending; - - updatePending = true; - - updateDisplayIfPending(); - assertFalse(updatePending); - - return true; -} - -bool testUpdateDisplayIfPendingAlertActive(void) { - extern bool updatePending; - - updatePending = true; - alert(1, 1, "", ""); - assertTrue(isAlertActive()); - - // update should be skipped if alert is active - updateDisplayIfPending(); - assertTrue(updatePending); - - return true; -} - -bool testDisplayText(void) { - // won't actually display anything - displayText("testDisplayText", "testDisplayTextLineTooLong"); - - return true; -} - -/* Module integers */ - -bool testDivRoundNearest(void) { - assertTrue(divRoundNearest(4, 2) == 2); - assertTrue(divRoundNearest(5, 2) == 3); - assertTrue(divRoundNearest(10, 3) == 3); - - return true; -} - -bool testDivRoundNearestNumNeg(void) { - assertTrue(divRoundNearest(-4, 2) == -2); - assertTrue(divRoundNearest(-5, 2) == -3); - assertTrue(divRoundNearest(-10, 3) == -3); - - return true; -} - -bool testDivRoundNearestDenNeg(void) { - assertTrue(divRoundNearest(4, -2) == -2); - assertTrue(divRoundNearest(5, -2) == -3); - assertTrue(divRoundNearest(10, -3) == -3); - - return true; -} - -bool testDivRoundNearestBothNeg(void) { - assertTrue(divRoundNearest(-4, -2) == 2); - assertTrue(divRoundNearest(-5, -2) == 3); - assertTrue(divRoundNearest(-10, -3) == 3); - - return true; -} - -bool testDivRoundUp(void) { - assertTrue(divRoundUp(4, 2) == 2); - assertTrue(divRoundUp(5, 2) == 3); - assertTrue(divRoundUp(10, 3) == 4); - - return true; -} - -bool testDivRoundUpNumNeg(void) { - assertTrue(divRoundUp(-4, 2) == -2); - assertTrue(divRoundUp(-5, 2) == -3); - assertTrue(divRoundUp(-10, 3) == -4); - - return true; -} - -bool testDivRoundUpDenNeg(void) { - assertTrue(divRoundUp(4, -2) == -2); - assertTrue(divRoundUp(5, -2) == -3); - assertTrue(divRoundUp(10, -3) == -4); - - return true; -} - -bool testDivRoundUpBothNeg(void) { - assertTrue(divRoundUp(-4, -2) == 2); - assertTrue(divRoundUp(-5, -2) == 3); - assertTrue(divRoundUp(-10, -3) == 4); - - return true; -} - -/* Module interrupts */ - -bool testSetupPorts(void) { - setupPorts(); - - // test that the pull-up resistor for the mouton is enabled - assertTrue(bit_is_set(PORTB, PB0)); - - // test that the beep output pin is enabled - assertTrue(bit_is_set(DDRB, PB1)); - - return true; -} - -bool testSetupSleepMode(void) { - setupSleepMode(); - - // set_sleep_mode(SLEEP_MODE_IDLE); - assertFalse(bit_is_set(SMCR, SM2)); - assertFalse(bit_is_set(SMCR, SM1)); - assertFalse(bit_is_set(SMCR, SM0)); - - return true; -} - -bool testInitInterrupts(void) { - initInterrupts(); - - // ADC interrupt enabled - assertTrue(bit_is_set(ADCSRA, ADIE)); - // PC interrupts enabled - // assertTrue(bit_is_set(PCICR, PCIE0)); - // assertTrue(bit_is_set(PCMSK0, PB0)); - // enable timer 0 overflow interrupt - assertTrue(bit_is_set(TIMSK0, TOIE0)); - // USART RX complete interrupt 0 enabled - assertTrue(bit_is_set(UCSR0B, RXCIE0)); - - // sei(); // enable global interrupts - assertTrue(bit_is_set(SREG, SREG_I)); - - return true; -} - -bool testInitTimers(void) { - initTimers(); - - // timer0 clock prescaler /64 = 15.625 kHz overflowing every 16.2 ms - uint8_t prescalerBy64 = (1 << CS00) | (1 << CS01); - assertTrue((TCCR0B & prescalerBy64) == prescalerBy64); - - // timer1 Clear Timer on Compare Match mode, TOP OCR1A - assertTrue(bit_is_set(TCCR1B, WGM12)); - // timer1 clock prescaler/8 - assertTrue(bit_is_set(TCCR1B, CS11)); - // toggles PB1 at 7.8 kHz generating a 3.9 kHz beep - // assertTrue(OCR1A == 15); - // 1.8 kHz is less noisy on the small piezo beeper - assertTrue(OCR1A == 31); - - return true; -} - -/* Module sensors */ - -bool testMeasure(void) { - setupADC(); - setupSleepMode(); - - // enable pull-up resistor so the measured voltage - // should be close to AREF - PORTC |= ((1 << ADC_TEMPI) | (1 << ADC_TEMPO) | (1 << ADC_LAMBDA)); - - // do many measurements so the averaged voltages are near the measured - // voltages (close to AREF) - Measurement meas; - for (uint8_t i = 0; i < 64; i++) { - meas = measure(); - } - - // verify that temperatures and lambda are calculated correctly - // for voltages > 4950 and <= 5000 mV - assertTrue(meas.tempI >= 990 && meas.tempI <= 1000); - assertTrue(meas.tempO == 400); - assertTrue(meas.lambda == 997); - - return true; -} - -bool testReadMeas(void) { - char* fields[] = {"1", "2", "3"}; - - Measurement meas = readMeas(fields, 3); - assertTrue(meas.tempI == 1); - assertTrue(meas.tempO == 2); - assertTrue(meas.lambda == 3); - - return true; -} - -bool testReadMeasTooFewFields(void) { - char* fields[] = {"1"}; - - Measurement meas = readMeas(fields, 1); - assertTrue(meas.tempI == 0); - assertTrue(meas.tempO == 0); - assertTrue(meas.lambda == 0); - - return true; -} - -bool testToLambdaValue(void) { - int16_t lambda = toLambda(132); - - return lambda == 1500; -} - -bool testToLambdaInter(void) { - int16_t lambda = toLambda(550); - - return lambda == 1073; -} - -bool testToTempI(void) { - int16_t temp = toTempI(100); - - return temp == 20; -} - -bool testToTempOValue(void) { - int16_t temp = toTempO(454); - - return temp == 0; -} - -bool testToTempOInter(void) { - int16_t temp = toTempO(929); - - return temp == 50; -} - -bool testLookupLinInterBelow(void) { - int16_t value = lookupLinInter(0, testTable, 2); - - return value == 10; -} - -bool testLookupLinInterAbove(void) { - int16_t value = lookupLinInter(30, testTable, 2); - - return value == 20; -} - -bool testLookupLinInterValue(void) { - int16_t value = lookupLinInter(10, testTable, 2); - - return value == 10; -} - -bool testLookupLinInterInter(void) { - int16_t value = lookupLinInter(15, testTable, 2); - - return value == 15; -} - -bool testToInfoLean(void) { - char* info = toInfo(191); - - return ! strcmp(info, LEAN); -} - -bool testToInfoOkay(void) { - assertTrue(0 == strcmp(toInfo(190), OKAY)); - assertTrue(0 == strcmp(toInfo(170), OKAY)); - assertTrue(0 == strcmp(toInfo(151), OKAY)); - - return true; -} - -bool testToInfoIdeal(void) { - assertTrue(0 == strcmp(toInfo(150), IDEAL)); - assertTrue(0 == strcmp(toInfo(140), IDEAL)); - assertTrue(0 == strcmp(toInfo(130), IDEAL)); - - return true; -} - -bool testToInfoRich(void) { - char* info = toInfo(129); - - return ! strcmp(info, RICH); -} - -/* Module strings */ - -bool testSplit(void) { - char string[] = "f1 f2 f3 "; - char* fields[4]; - split(string, " ", fields, 4); - - assertTrue(strcmp("f1", fields[0]) == 0); - assertTrue(strcmp("f2", fields[1]) == 0); - assertTrue(strcmp("f3", fields[2]) == 0); - assertTrue(strcmp("", fields[3]) == 0); - - return true; -} - -bool testSplitSizeTooSmall(void) { - char string[] = "f1 f2"; - char* fields[1]; - split(string, " ", fields, 1); - - assertTrue(strcmp("f1", fields[0]) == 0); - - return true; -} - -/* Test "classes" */ -const char adc_P[] PROGMEM = "adc"; -const char command_P[] PROGMEM = "command"; -const char display_P[] PROGMEM = "display"; -const char integers_P[] PROGMEM = "integers"; -const char interrupts_P[] PROGMEM = "interrupts"; -const char sensors_P[] PROGMEM = "sensors"; -const char strings_P[] PROGMEM = "strings"; - -/* Test names */ -const char testSetupADC_P[] PROGMEM = "testSetupADC"; -const char testGetVoltage_P[] PROGMEM = "testGetVoltage"; -const char testIsSimulation_P[] PROGMEM = "testIsSimulation"; -const char testIsLogging_P[] PROGMEM = "testIsLogging"; -const char testCycle_P[] PROGMEM = "testCycle"; -const char testCycleCancelAlert_P[] PROGMEM = "testCycleCancelAlert"; -const char testUpdateMeas_P[] PROGMEM = "testUpdateMeas"; -const char testResetMeas_P[] PROGMEM = "testResetMeas"; -const char testUpdateDisplayIfPending_P[] PROGMEM = "testUpdateDisplayIfPending"; -const char testUpdateDisplayIfPendingAlertActive_P[] PROGMEM = "testUpdateDisplayIfPendingAlertActive"; -const char testDisplayText_P[] PROGMEM = "testDisplayText"; -const char testDivRoundNearest_P[] PROGMEM = "testDivRoundNearest"; -const char testDivRoundNearestNumNeg_P[] PROGMEM = "testDivRoundNearestNumNeg"; -const char testDivRoundNearestDenNeg_P[] PROGMEM = "testDivRoundNearestDenNeg"; -const char testDivRoundNearestBothNeg_P[] PROGMEM = "testDivRoundNearestBothNeg"; -const char testDivRoundUp_P[] PROGMEM = "testDivRoundUp"; -const char testDivRoundUpNumNeg_P[] PROGMEM = "testDivRoundUpNumNeg"; -const char testDivRoundUpDenNeg_P[] PROGMEM = "testDivRoundUpDenNeg"; -const char testDivRoundUpBothNeg_P[] PROGMEM = "testDivRoundUpBothNeg"; -const char testSetupPorts_P[] PROGMEM = "testSetupPorts"; -const char testSetupSleepMode_P[] PROGMEM = "testSetupSleepMode"; -const char testInitInterrupts_P[] PROGMEM = "testInitInterrupts"; -const char testInitTimers_P[] PROGMEM = "testInitTimers"; -const char testMeasure_P[] PROGMEM = "testMeasure"; -const char testReadMeas_P[] PROGMEM = "testReadMeas"; -const char testReadMeasTooFewFields_P[] PROGMEM = "testReadMeasTooFewFields"; -const char testToLambdaValue_P[] PROGMEM = "testToLambdaValue"; -const char testToLambdaInter_P[] PROGMEM = "testToLambdaInter"; -const char testToTempI_P[] PROGMEM = "testToTempI"; -const char testToTempOValue_P[] PROGMEM = "testToTempOValue"; -const char testToTempOInter_P[] PROGMEM = "testToTempOInter"; -const char testLookupLinInterValue_P[] PROGMEM = "testLookupLinInterValue"; -const char testLookupLinInterInter_P[] PROGMEM = "testLookupLinInterInter"; -const char testLookupLinInterBelow_P[] PROGMEM = "testLookupLinInterBelow"; -const char testLookupLinInterAbove_P[] PROGMEM = "testLookupLinInterAbove"; -const char testToInfoLean_P[] PROGMEM = "testToInfoLean"; -const char testToInfoOkay_P[] PROGMEM = "testToInfoOkay"; -const char testToInfoIdeal_P[] PROGMEM = "testToInfoIdeal"; -const char testToInfoRich_P[] PROGMEM = "testToInfoRich"; -const char testSplit_P[] PROGMEM = "testSplit"; -const char testSplitSizeTooSmall_P[] PROGMEM = "testSplitSizeTooSmall"; - -/* Tests */ -TestCase const tests[] = { - {adc_P, testSetupADC_P, testSetupADC}, - {adc_P, testGetVoltage_P, testGetVoltage}, - {command_P, testIsSimulation_P, testIsSimulation}, - {command_P, testIsLogging_P, testIsLogging}, - {display_P, testCycle_P, testCycle}, - {display_P, testCycleCancelAlert_P, testCycleCancelAlert}, - {display_P, testUpdateMeas_P, testUpdateMeas}, - {display_P, testResetMeas_P, testResetMeas}, - {display_P, testUpdateDisplayIfPending_P, testUpdateDisplayIfPending}, - {display_P, testUpdateDisplayIfPendingAlertActive_P, testUpdateDisplayIfPendingAlertActive}, - {display_P, testDisplayText_P, testDisplayText}, - {integers_P, testDivRoundNearest_P, testDivRoundNearest}, - {integers_P, testDivRoundNearestNumNeg_P, testDivRoundNearestNumNeg}, - {integers_P, testDivRoundNearestDenNeg_P, testDivRoundNearestDenNeg}, - {integers_P, testDivRoundNearestBothNeg_P, testDivRoundNearestBothNeg}, - {integers_P, testDivRoundUp_P, testDivRoundUp}, - {integers_P, testDivRoundUpNumNeg_P, testDivRoundUpNumNeg}, - {integers_P, testDivRoundUpDenNeg_P, testDivRoundUpDenNeg}, - {integers_P, testDivRoundUpBothNeg_P, testDivRoundUpBothNeg}, - {interrupts_P, testSetupPorts_P, testSetupPorts}, - {interrupts_P, testSetupSleepMode_P, testSetupSleepMode}, - {interrupts_P, testInitInterrupts_P, testInitInterrupts}, - {interrupts_P, testInitTimers_P, testInitTimers}, - {sensors_P, testMeasure_P, testMeasure}, - {sensors_P, testReadMeas_P, testReadMeas}, - {sensors_P, testReadMeasTooFewFields_P, testReadMeasTooFewFields}, - {sensors_P, testToLambdaValue_P, testToLambdaValue}, - {sensors_P, testToLambdaInter_P, testToLambdaInter}, - {sensors_P, testToTempI_P, testToTempI}, - {sensors_P, testToTempOValue_P, testToTempOValue}, - {sensors_P, testToTempOInter_P, testToTempOInter}, - {sensors_P, testLookupLinInterValue_P, testLookupLinInterValue}, - {sensors_P, testLookupLinInterInter_P, testLookupLinInterInter}, - {sensors_P, testLookupLinInterBelow_P, testLookupLinInterBelow}, - {sensors_P, testLookupLinInterAbove_P, testLookupLinInterAbove}, - {sensors_P, testToInfoLean_P, testToInfoLean}, - {sensors_P, testToInfoOkay_P, testToInfoOkay}, - {sensors_P, testToInfoIdeal_P, testToInfoIdeal}, - {sensors_P, testToInfoRich_P, testToInfoRich}, - {strings_P, testSplit_P, testSplit}, - {strings_P, testSplitSizeTooSmall_P, testSplitSizeTooSmall} -}; int main(void) { initUSART(); - size_t count = sizeof(tests) / sizeof(tests[0]); - runTests("lambda", tests, count); + extern const TestCase adcTests[]; + extern const TestCase commandTests[]; + extern const TestCase displayTests[]; + extern const TestCase integersTests[]; + extern const TestCase interruptsTests[]; + extern const TestCase sensorsTests[]; + extern const TestCase stringsTests[]; + + runTests("lambda", adcTests, 2); + runTests("lambda", commandTests, 2); + runTests("lambda", displayTests, 7); + runTests("lambda", integersTests, 8); + runTests("lambda", interruptsTests, 4); + runTests("lambda", sensorsTests, 16); + runTests("lambda", stringsTests, 2); return 0; } diff --git a/lambda-test/sensors-test.c b/lambda-test/sensors-test.c new file mode 100644 index 0000000..49ccf51 --- /dev/null +++ b/lambda-test/sensors-test.c @@ -0,0 +1,192 @@ +/* + * lambda-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include +#include "avrjunit.h" +#include "interrupts.h" +#include "adc.h" +#include "sensors.h" +#include "pins.h" + +static TableEntry const testTable[] = { + {10, 10}, + {20, 20} +}; + +/* Module sensors */ + +bool testMeasure(void) { + setupADC(); + setupSleepMode(); + + // enable pull-up resistor so the measured voltage + // should be close to AREF + PORTC |= ((1 << ADC_TEMPI) | (1 << ADC_TEMPO) | (1 << ADC_LAMBDA)); + + // do many measurements so the averaged voltages are near the measured + // voltages (close to AREF) + Measurement meas; + for (uint8_t i = 0; i < 64; i++) { + meas = measure(); + } + + // verify that temperatures and lambda are calculated correctly + // for voltages > 4950 and <= 5000 mV + assertTrue(meas.tempI >= 990 && meas.tempI <= 1000); + assertTrue(meas.tempO == 400); + assertTrue(meas.lambda == 997); + + return true; +} + +bool testReadMeas(void) { + char* fields[] = {"1", "2", "3"}; + + Measurement meas = readMeas(fields, 3); + assertTrue(meas.tempI == 1); + assertTrue(meas.tempO == 2); + assertTrue(meas.lambda == 3); + + return true; +} + +bool testReadMeasTooFewFields(void) { + char* fields[] = {"1"}; + + Measurement meas = readMeas(fields, 1); + assertTrue(meas.tempI == 0); + assertTrue(meas.tempO == 0); + assertTrue(meas.lambda == 0); + + return true; +} + +bool testToLambdaValue(void) { + int16_t lambda = toLambda(132); + + return lambda == 1500; +} + +bool testToLambdaInter(void) { + int16_t lambda = toLambda(550); + + return lambda == 1073; +} + +bool testToTempI(void) { + int16_t temp = toTempI(100); + + return temp == 20; +} + +bool testToTempOValue(void) { + int16_t temp = toTempO(454); + + return temp == 0; +} + +bool testToTempOInter(void) { + int16_t temp = toTempO(929); + + return temp == 50; +} + +bool testLookupLinInterBelow(void) { + int16_t value = lookupLinInter(0, testTable, 2); + + return value == 10; +} + +bool testLookupLinInterAbove(void) { + int16_t value = lookupLinInter(30, testTable, 2); + + return value == 20; +} + +bool testLookupLinInterValue(void) { + int16_t value = lookupLinInter(10, testTable, 2); + + return value == 10; +} + +bool testLookupLinInterInter(void) { + int16_t value = lookupLinInter(15, testTable, 2); + + return value == 15; +} + +bool testToInfoLean(void) { + char* info = toInfo(191); + + return ! strcmp(info, LEAN); +} + +bool testToInfoOkay(void) { + assertTrue(0 == strcmp(toInfo(190), OKAY)); + assertTrue(0 == strcmp(toInfo(170), OKAY)); + assertTrue(0 == strcmp(toInfo(151), OKAY)); + + return true; +} + +bool testToInfoIdeal(void) { + assertTrue(0 == strcmp(toInfo(150), IDEAL)); + assertTrue(0 == strcmp(toInfo(140), IDEAL)); + assertTrue(0 == strcmp(toInfo(130), IDEAL)); + + return true; +} + +bool testToInfoRich(void) { + char* info = toInfo(129); + + return ! strcmp(info, RICH); +} + +/* Test "class" */ +const char sensors_P[] PROGMEM = "sensors"; + +/* Test names */ +const char testMeasure_P[] PROGMEM = "testMeasure"; +const char testReadMeas_P[] PROGMEM = "testReadMeas"; +const char testReadMeasTooFewFields_P[] PROGMEM = "testReadMeasTooFewFields"; +const char testToLambdaValue_P[] PROGMEM = "testToLambdaValue"; +const char testToLambdaInter_P[] PROGMEM = "testToLambdaInter"; +const char testToTempI_P[] PROGMEM = "testToTempI"; +const char testToTempOValue_P[] PROGMEM = "testToTempOValue"; +const char testToTempOInter_P[] PROGMEM = "testToTempOInter"; +const char testLookupLinInterValue_P[] PROGMEM = "testLookupLinInterValue"; +const char testLookupLinInterInter_P[] PROGMEM = "testLookupLinInterInter"; +const char testLookupLinInterBelow_P[] PROGMEM = "testLookupLinInterBelow"; +const char testLookupLinInterAbove_P[] PROGMEM = "testLookupLinInterAbove"; +const char testToInfoLean_P[] PROGMEM = "testToInfoLean"; +const char testToInfoOkay_P[] PROGMEM = "testToInfoOkay"; +const char testToInfoIdeal_P[] PROGMEM = "testToInfoIdeal"; +const char testToInfoRich_P[] PROGMEM = "testToInfoRich"; + +/* Tests */ +TestCase const sensorsTests[] = { + {sensors_P, testMeasure_P, testMeasure}, + {sensors_P, testReadMeas_P, testReadMeas}, + {sensors_P, testReadMeasTooFewFields_P, testReadMeasTooFewFields}, + {sensors_P, testToLambdaValue_P, testToLambdaValue}, + {sensors_P, testToLambdaInter_P, testToLambdaInter}, + {sensors_P, testToTempI_P, testToTempI}, + {sensors_P, testToTempOValue_P, testToTempOValue}, + {sensors_P, testToTempOInter_P, testToTempOInter}, + {sensors_P, testLookupLinInterValue_P, testLookupLinInterValue}, + {sensors_P, testLookupLinInterInter_P, testLookupLinInterInter}, + {sensors_P, testLookupLinInterBelow_P, testLookupLinInterBelow}, + {sensors_P, testLookupLinInterAbove_P, testLookupLinInterAbove}, + {sensors_P, testToInfoLean_P, testToInfoLean}, + {sensors_P, testToInfoOkay_P, testToInfoOkay}, + {sensors_P, testToInfoIdeal_P, testToInfoIdeal}, + {sensors_P, testToInfoRich_P, testToInfoRich}, +}; diff --git a/lambda-test/strings-test.c b/lambda-test/strings-test.c new file mode 100644 index 0000000..d5e11d7 --- /dev/null +++ b/lambda-test/strings-test.c @@ -0,0 +1,51 @@ +/* + * lambda-test.c + * + * Unit tests for the lambda project. + * + * Created on: 15.05.2015 + * Author: dode@luniks.net + * + */ + +#include +#include "avrjunit.h" +#include "strings.h" + +/* Module strings */ + +bool testSplit(void) { + char string[] = "f1 f2 f3 "; + char* fields[4]; + split(string, " ", fields, 4); + + assertTrue(strcmp("f1", fields[0]) == 0); + assertTrue(strcmp("f2", fields[1]) == 0); + assertTrue(strcmp("f3", fields[2]) == 0); + assertTrue(strcmp("", fields[3]) == 0); + + return true; +} + +bool testSplitSizeTooSmall(void) { + char string[] = "f1 f2"; + char* fields[1]; + split(string, " ", fields, 1); + + assertTrue(strcmp("f1", fields[0]) == 0); + + return true; +} + +/* Test "class" */ +const char strings_P[] PROGMEM = "strings"; + +/* Test names */ +const char testSplit_P[] PROGMEM = "testSplit"; +const char testSplitSizeTooSmall_P[] PROGMEM = "testSplitSizeTooSmall"; + +/* Tests */ +TestCase const stringsTests[] = { + {strings_P, testSplit_P, testSplit}, + {strings_P, testSplitSizeTooSmall_P, testSplitSizeTooSmall} +}; diff --git a/lambda/display.c b/lambda/display.c index 9ed53a5..c35219a 100644 --- a/lambda/display.c +++ b/lambda/display.c @@ -16,7 +16,6 @@ #include "USART.h" #include "lcdroutines.h" #include "integers.h" -#include "sensors.h" #include "display.h" #include "alert.h" diff --git a/lambda/display.h b/lambda/display.h index 7abf0bb..969c395 100644 --- a/lambda/display.h +++ b/lambda/display.h @@ -11,6 +11,8 @@ #ifndef DISPLAY_H_ #define DISPLAY_H_ +#include "sensors.h" + uint8_t getPosition(void); /**