From 39a028c715e79c0a69eabff44839cf6162774aa4 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Sun, 3 Feb 2019 14:22:18 +1100 Subject: [PATCH 01/11] add mock for avr/sleep.h --- SampleProjects/TestSomething/test/sleep.cpp | 65 +++++++++++++++++++++ cpp/arduino/Godmode.h | 22 +++++++ cpp/arduino/avr/sleep.h | 43 ++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 SampleProjects/TestSomething/test/sleep.cpp create mode 100644 cpp/arduino/avr/sleep.h diff --git a/SampleProjects/TestSomething/test/sleep.cpp b/SampleProjects/TestSomething/test/sleep.cpp new file mode 100644 index 00000000..95f59e8a --- /dev/null +++ b/SampleProjects/TestSomething/test/sleep.cpp @@ -0,0 +1,65 @@ +#include +#include + +GodmodeState* state = GODMODE(); + +unittest(sleep_enable) { + state->reset(); + assertFalse(state->sleep.sleep_enable); + assertEqual(0, state->sleep.sleep_enable_count); + + sleep_enable(); + + assertTrue(state->sleep.sleep_enable); + assertEqual(1, state->sleep.sleep_enable_count); +} + +unittest(sleep_disable) { + state->reset(); + assertEqual(0, state->sleep.sleep_disable_count); + + sleep_disable(); + + assertFalse(state->sleep.sleep_enable); + assertEqual(1, state->sleep.sleep_disable_count); +} + +unittest(set_sleep_mode) { + state->reset(); + assertEqual(0, state->sleep.sleep_mode); + + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + + assertEqual(SLEEP_MODE_PWR_DOWN, state->sleep.sleep_mode); +} + +unittest(sleep_bod_disable) { + state->reset(); + assertEqual(0, state->sleep.sleep_bod_disable_count); + + sleep_bod_disable(); + + assertEqual(1, state->sleep.sleep_bod_disable_count); +} + +unittest(sleep_cpu) { + state->reset(); + assertEqual(0, state->sleep.sleep_cpu_count); + + sleep_cpu(); + + assertEqual(1, state->sleep.sleep_cpu_count); +} + +unittest(sleep_mode) { + state->reset(); + assertEqual(0, state->sleep.sleep_mode_count); + + sleep_mode(); + + assertEqual(1, state->sleep.sleep_mode_count); + assertEqual(1, state->sleep.sleep_enable_count); + assertEqual(1, state->sleep.sleep_disable_count); +} + +unittest_main() diff --git a/cpp/arduino/Godmode.h b/cpp/arduino/Godmode.h index b50f99d2..15e026fa 100644 --- a/cpp/arduino/Godmode.h +++ b/cpp/arduino/Godmode.h @@ -43,6 +43,16 @@ class GodmodeState { uint8_t mode; }; + struct SleepDef { + bool sleep_enable = false; + unsigned int sleep_enable_count = 0; + unsigned int sleep_disable_count = 0; + unsigned char sleep_mode = 0; + unsigned int sleep_cpu_count = 0; + unsigned int sleep_mode_count = 0; + unsigned int sleep_bod_disable_count = 0; + }; + public: unsigned long micros; unsigned long seed; @@ -52,6 +62,7 @@ class GodmodeState { struct PortDef serialPort[NUM_SERIAL_PORTS]; struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number struct PortDef spi; + struct SleepDef sleep; void resetPins() { for (int i = 0; i < MOCK_PINS_COUNT; ++i) { @@ -85,12 +96,23 @@ class GodmodeState { spi.readDelayMicros = 0; } + void resetSleep() { + sleep.sleep_enable = false; + sleep.sleep_enable_count = 0; + sleep.sleep_disable_count = 0; + sleep.sleep_mode = 0; + sleep.sleep_cpu_count = 0; + sleep.sleep_mode_count = 0; + sleep.sleep_bod_disable_count = 0; + } + void reset() { resetClock(); resetPins(); resetInterrupts(); resetPorts(); resetSPI(); + resetSleep(); seed = 1; } diff --git a/cpp/arduino/avr/sleep.h b/cpp/arduino/avr/sleep.h new file mode 100644 index 00000000..8ef4d914 --- /dev/null +++ b/cpp/arduino/avr/sleep.h @@ -0,0 +1,43 @@ +#ifndef _AVR_SLEEP_H_ +#define _AVR_SLEEP_H_ + +#include + +void sleep_enable() { + GodmodeState* godmode = GODMODE(); + godmode->sleep.sleep_enable = true; + godmode->sleep.sleep_enable_count++; +} + +void sleep_disable() { + GodmodeState* godmode = GODMODE(); + godmode->sleep.sleep_enable = false; + godmode->sleep.sleep_disable_count++; +} + +void set_sleep_mode(unsigned char mode) { + GodmodeState* godmode = GODMODE(); + godmode->sleep.sleep_mode = mode; +} + +void sleep_bod_disable() { + GodmodeState* godmode = GODMODE(); + godmode->sleep.sleep_bod_disable_count++; +} + +void sleep_cpu() { + GodmodeState* godmode = GODMODE(); + godmode->sleep.sleep_cpu_count++; +} + +void sleep_mode() { + GodmodeState* godmode = GODMODE(); + sleep_enable(); + godmode->sleep.sleep_mode_count++; + sleep_disable(); +} + +unsigned char sfr_store; +#define _SFR_MEM8(mem_addr) sfr_store + +#endif /* _AVR_SLEEP_H_ */ From 3fe65ba7761c3cd701fb60df6080b7ed920f1bb2 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Sun, 3 Feb 2019 14:49:30 +1100 Subject: [PATCH 02/11] add mock for avr/wdt.h --- SampleProjects/TestSomething/test/wdt.cpp | 41 +++++++++++++++++++++++ cpp/arduino/Godmode.h | 20 ++++++++++- cpp/arduino/avr/interrupt.h | 10 ++++++ cpp/arduino/avr/wdt.h | 36 ++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 SampleProjects/TestSomething/test/wdt.cpp create mode 100644 cpp/arduino/avr/interrupt.h create mode 100644 cpp/arduino/avr/wdt.h diff --git a/SampleProjects/TestSomething/test/wdt.cpp b/SampleProjects/TestSomething/test/wdt.cpp new file mode 100644 index 00000000..519aee83 --- /dev/null +++ b/SampleProjects/TestSomething/test/wdt.cpp @@ -0,0 +1,41 @@ +#include +#include + +GodmodeState* state = GODMODE(); + +unittest(taskWdtEnable_checkTimeout) { + state->reset(); + assertEqual(0, state->wdt.timeout); + + wdt_enable(WDTO_1S); + + assertTrue(state->wdt.wdt_enable); + assertEqual(WDTO_1S, state->wdt.timeout); + assertEqual(1, state->wdt.wdt_enable_count); +} + +unittest(taskWdtEnableDisable) { + state->reset(); + assertEqual(0, state->wdt.wdt_enable_count); + + wdt_enable(WDTO_1S); + + assertTrue(state->wdt.wdt_enable); + assertEqual(1, state->wdt.wdt_enable_count); + + wdt_disable(); + + assertFalse(state->wdt.wdt_enable); + assertEqual(1, state->wdt.wdt_enable_count); +} + +unittest(wdt_reset) { + state->reset(); + assertEqual(0, state->wdt.wdt_reset_count); + + wdt_reset(); + + assertEqual(1, state->wdt.wdt_reset_count); +} + +unittest_main() diff --git a/cpp/arduino/Godmode.h b/cpp/arduino/Godmode.h index 15e026fa..db033c38 100644 --- a/cpp/arduino/Godmode.h +++ b/cpp/arduino/Godmode.h @@ -53,6 +53,14 @@ class GodmodeState { unsigned int sleep_bod_disable_count = 0; }; + struct WdtDef { + bool wdt_enable = false; + unsigned char timeout = 0; + unsigned int wdt_enable_count = 0; + unsigned int wdt_disable_count = 0; + unsigned int wdt_reset_count = 0; + }; + public: unsigned long micros; unsigned long seed; @@ -63,6 +71,7 @@ class GodmodeState { struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number struct PortDef spi; struct SleepDef sleep; + struct WdtDef wdt; void resetPins() { for (int i = 0; i < MOCK_PINS_COUNT; ++i) { @@ -106,6 +115,14 @@ class GodmodeState { sleep.sleep_bod_disable_count = 0; } + void resetWdt() { + wdt.wdt_enable = false; + wdt.timeout = 0; + wdt.wdt_enable_count = 0; + wdt.wdt_disable_count = 0; + wdt.wdt_reset_count = 0; + } + void reset() { resetClock(); resetPins(); @@ -113,6 +130,7 @@ class GodmodeState { resetPorts(); resetSPI(); resetSleep(); + resetWdt(); seed = 1; } @@ -136,7 +154,7 @@ int analogRead(uint8_t); void analogWrite(uint8_t, int); #define analogReadResolution(...) _NOP() #define analogWriteResolution(...) _NOP() -void attachInterrupt(uint8_t interrupt, void ISR(void), uint8_t mode); +void attachInterrupt(uint8_t interrupt, void isr(void), uint8_t mode); void detachInterrupt(uint8_t interrupt); // TODO: issue #26 to track the commanded state here diff --git a/cpp/arduino/avr/interrupt.h b/cpp/arduino/avr/interrupt.h new file mode 100644 index 00000000..7d970863 --- /dev/null +++ b/cpp/arduino/avr/interrupt.h @@ -0,0 +1,10 @@ +#ifndef _AVR_INTERRUPT_H_ +#define _AVR_INTERRUPT_H_ + +#define _VECTOR(N) __vector_ ## N + +#define ISR(vector, ...) \ + extern "C" void vector (void) __VA_ARGS__; \ + void vector (void) + +#endif diff --git a/cpp/arduino/avr/wdt.h b/cpp/arduino/avr/wdt.h new file mode 100644 index 00000000..7db5813e --- /dev/null +++ b/cpp/arduino/avr/wdt.h @@ -0,0 +1,36 @@ +#ifndef _AVR_WDT_H_ +#define _AVR_WDT_H_ + +#include +#include + +#define WDTO_15MS 0 +#define WDTO_30MS 1 +#define WDTO_60MS 2 +#define WDTO_120MS 3 +#define WDTO_250MS 4 +#define WDTO_500MS 5 +#define WDTO_1S 6 +#define WDTO_2S 7 +#define WDTO_4S 8 +#define WDTO_8S 9 + +void wdt_enable(unsigned char timeout) { + GodmodeState* godmode = GODMODE(); + godmode->wdt.wdt_enable = true; + godmode->wdt.timeout = timeout; + godmode->wdt.wdt_enable_count++; +} + +void wdt_disable() { + GodmodeState* godmode = GODMODE(); + godmode->wdt.wdt_enable = false; + godmode->wdt.wdt_disable_count++; +} + +void wdt_reset() { + GodmodeState* godmode = GODMODE(); + godmode->wdt.wdt_reset_count++; +} + +#endif /* _AVR_WDT_H_ */ From 3a2f644ddf73252568e32d0592f37ee6cdd07935 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Mon, 4 Feb 2019 22:26:15 +1100 Subject: [PATCH 03/11] add explanation --- cpp/arduino/avr/interrupt.h | 2 +- cpp/arduino/avr/sleep.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/arduino/avr/interrupt.h b/cpp/arduino/avr/interrupt.h index 7d970863..0aa85c03 100644 --- a/cpp/arduino/avr/interrupt.h +++ b/cpp/arduino/avr/interrupt.h @@ -1,8 +1,8 @@ #ifndef _AVR_INTERRUPT_H_ #define _AVR_INTERRUPT_H_ +// allows the production code to define an ISR method #define _VECTOR(N) __vector_ ## N - #define ISR(vector, ...) \ extern "C" void vector (void) __VA_ARGS__; \ void vector (void) diff --git a/cpp/arduino/avr/sleep.h b/cpp/arduino/avr/sleep.h index 8ef4d914..dac5de21 100644 --- a/cpp/arduino/avr/sleep.h +++ b/cpp/arduino/avr/sleep.h @@ -37,6 +37,7 @@ void sleep_mode() { sleep_disable(); } +// mock storage to allow access to ADCSRA unsigned char sfr_store; #define _SFR_MEM8(mem_addr) sfr_store From 200249565592147c3e0aee9a417a01be4697f901 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Wed, 6 Feb 2019 21:15:51 +1100 Subject: [PATCH 04/11] import interrupt.h in Arduino.h and add a declaration test --- SampleProjects/TestSomething/test/isr_declaration.cpp | 7 +++++++ cpp/arduino/Arduino.h | 2 ++ cpp/arduino/avr/interrupt.h | 2 +- cpp/arduino/avr/wdt.h | 1 - 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 SampleProjects/TestSomething/test/isr_declaration.cpp diff --git a/SampleProjects/TestSomething/test/isr_declaration.cpp b/SampleProjects/TestSomething/test/isr_declaration.cpp new file mode 100644 index 00000000..a3343f8d --- /dev/null +++ b/SampleProjects/TestSomething/test/isr_declaration.cpp @@ -0,0 +1,7 @@ +#include +#include + +ISR (WDT_vect) { +} + +unittest_main() diff --git a/cpp/arduino/Arduino.h b/cpp/arduino/Arduino.h index e672c35e..b1a3ba07 100644 --- a/cpp/arduino/Arduino.h +++ b/cpp/arduino/Arduino.h @@ -24,6 +24,8 @@ typedef uint8_t byte; // Math and Trig #include "AvrMath.h" +#include + #include "Godmode.h" diff --git a/cpp/arduino/avr/interrupt.h b/cpp/arduino/avr/interrupt.h index 0aa85c03..a2213fcb 100644 --- a/cpp/arduino/avr/interrupt.h +++ b/cpp/arduino/avr/interrupt.h @@ -7,4 +7,4 @@ extern "C" void vector (void) __VA_ARGS__; \ void vector (void) -#endif +#endif // _AVR_INTERRUPT_H_ diff --git a/cpp/arduino/avr/wdt.h b/cpp/arduino/avr/wdt.h index 7db5813e..4e68a9b6 100644 --- a/cpp/arduino/avr/wdt.h +++ b/cpp/arduino/avr/wdt.h @@ -1,7 +1,6 @@ #ifndef _AVR_WDT_H_ #define _AVR_WDT_H_ -#include #include #define WDTO_15MS 0 From 16655d5c7c8b1431fb98f0ebc30a87383225772f Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Wed, 6 Feb 2019 21:19:49 +1100 Subject: [PATCH 05/11] separate ADC definition into separate files and add a test --- SampleProjects/TestSomething/test/adc.cpp | 10 ++++++++++ SampleProjects/TestSomething/test/isr_declaration.cpp | 1 + cpp/arduino/Arduino.h | 1 + cpp/arduino/AvrAdc.cpp | 4 ++++ cpp/arduino/AvrAdc.h | 8 ++++++++ cpp/arduino/avr/sleep.h | 4 ---- 6 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 SampleProjects/TestSomething/test/adc.cpp create mode 100644 cpp/arduino/AvrAdc.cpp create mode 100644 cpp/arduino/AvrAdc.h diff --git a/SampleProjects/TestSomething/test/adc.cpp b/SampleProjects/TestSomething/test/adc.cpp new file mode 100644 index 00000000..3deea670 --- /dev/null +++ b/SampleProjects/TestSomething/test/adc.cpp @@ -0,0 +1,10 @@ +#include +#include + +unittest(check_ADCSRA_read_write) { + ADCSRA = 123; + + assertEqual(123, ADCSRA); +} + +unittest_main() diff --git a/SampleProjects/TestSomething/test/isr_declaration.cpp b/SampleProjects/TestSomething/test/isr_declaration.cpp index a3343f8d..9e1a302e 100644 --- a/SampleProjects/TestSomething/test/isr_declaration.cpp +++ b/SampleProjects/TestSomething/test/isr_declaration.cpp @@ -1,6 +1,7 @@ #include #include +// just check if declaration compiles ISR (WDT_vect) { } diff --git a/cpp/arduino/Arduino.h b/cpp/arduino/Arduino.h index b1a3ba07..bcabbbf4 100644 --- a/cpp/arduino/Arduino.h +++ b/cpp/arduino/Arduino.h @@ -24,6 +24,7 @@ typedef uint8_t byte; // Math and Trig #include "AvrMath.h" +#include "AvrAdc.h" #include #include "Godmode.h" diff --git a/cpp/arduino/AvrAdc.cpp b/cpp/arduino/AvrAdc.cpp new file mode 100644 index 00000000..4699e8ca --- /dev/null +++ b/cpp/arduino/AvrAdc.cpp @@ -0,0 +1,4 @@ +#include "AvrAdc.h" + +// mock storage to allow access to ADCSRA +unsigned char sfr_store; diff --git a/cpp/arduino/AvrAdc.h b/cpp/arduino/AvrAdc.h new file mode 100644 index 00000000..79b1143c --- /dev/null +++ b/cpp/arduino/AvrAdc.h @@ -0,0 +1,8 @@ +#ifndef _AVR_ADC_H_ +#define _AVR_ADC_H_ + +// mock storage to allow access to ADCSRA +extern unsigned char sfr_store; +#define _SFR_MEM8(mem_addr) sfr_store + +#endif // _AVR_ADC_H_ diff --git a/cpp/arduino/avr/sleep.h b/cpp/arduino/avr/sleep.h index dac5de21..6f97e7b0 100644 --- a/cpp/arduino/avr/sleep.h +++ b/cpp/arduino/avr/sleep.h @@ -37,8 +37,4 @@ void sleep_mode() { sleep_disable(); } -// mock storage to allow access to ADCSRA -unsigned char sfr_store; -#define _SFR_MEM8(mem_addr) sfr_store - #endif /* _AVR_SLEEP_H_ */ From e56c2e048adef41569f8df24c18f635f1f04e8a3 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Wed, 6 Feb 2019 22:09:38 +1100 Subject: [PATCH 06/11] adjust include --- cpp/arduino/Arduino.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/arduino/Arduino.h b/cpp/arduino/Arduino.h index bcabbbf4..149dccac 100644 --- a/cpp/arduino/Arduino.h +++ b/cpp/arduino/Arduino.h @@ -25,7 +25,7 @@ typedef uint8_t byte; #include "AvrMath.h" #include "AvrAdc.h" -#include +#include "avr/interrupt.h" #include "Godmode.h" From 062d4912ad91ecd097905c31c79a4cfb8f88e9d1 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Sun, 3 Feb 2019 14:24:24 +1100 Subject: [PATCH 07/11] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 808b83d7..1bd59461 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Proper `ostream operator <<` for `nullptr` - Proper comparison operations fro `nullptr` +- Mocks for avr/sleep.h and avr/wdt.h +- Definitions for ISR and ADCSRA ### Changed - `Compare.h` heavily refactored to use a smallish macro From 364da411feb951a28798612a47ce5f495e0e54b9 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Thu, 7 Feb 2019 18:53:53 +1100 Subject: [PATCH 08/11] change to #pragma once --- cpp/arduino/AvrAdc.h | 5 +---- cpp/arduino/avr/interrupt.h | 5 +---- cpp/arduino/avr/sleep.h | 5 +---- cpp/arduino/avr/wdt.h | 5 +---- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/cpp/arduino/AvrAdc.h b/cpp/arduino/AvrAdc.h index 79b1143c..5690a85a 100644 --- a/cpp/arduino/AvrAdc.h +++ b/cpp/arduino/AvrAdc.h @@ -1,8 +1,5 @@ -#ifndef _AVR_ADC_H_ -#define _AVR_ADC_H_ +#pragma once // mock storage to allow access to ADCSRA extern unsigned char sfr_store; #define _SFR_MEM8(mem_addr) sfr_store - -#endif // _AVR_ADC_H_ diff --git a/cpp/arduino/avr/interrupt.h b/cpp/arduino/avr/interrupt.h index a2213fcb..0279f363 100644 --- a/cpp/arduino/avr/interrupt.h +++ b/cpp/arduino/avr/interrupt.h @@ -1,10 +1,7 @@ -#ifndef _AVR_INTERRUPT_H_ -#define _AVR_INTERRUPT_H_ +#pragma once // allows the production code to define an ISR method #define _VECTOR(N) __vector_ ## N #define ISR(vector, ...) \ extern "C" void vector (void) __VA_ARGS__; \ void vector (void) - -#endif // _AVR_INTERRUPT_H_ diff --git a/cpp/arduino/avr/sleep.h b/cpp/arduino/avr/sleep.h index 6f97e7b0..6d22cbff 100644 --- a/cpp/arduino/avr/sleep.h +++ b/cpp/arduino/avr/sleep.h @@ -1,5 +1,4 @@ -#ifndef _AVR_SLEEP_H_ -#define _AVR_SLEEP_H_ +#pragma once #include @@ -36,5 +35,3 @@ void sleep_mode() { godmode->sleep.sleep_mode_count++; sleep_disable(); } - -#endif /* _AVR_SLEEP_H_ */ diff --git a/cpp/arduino/avr/wdt.h b/cpp/arduino/avr/wdt.h index 4e68a9b6..145ab7f4 100644 --- a/cpp/arduino/avr/wdt.h +++ b/cpp/arduino/avr/wdt.h @@ -1,5 +1,4 @@ -#ifndef _AVR_WDT_H_ -#define _AVR_WDT_H_ +#pragma once #include @@ -31,5 +30,3 @@ void wdt_reset() { GodmodeState* godmode = GODMODE(); godmode->wdt.wdt_reset_count++; } - -#endif /* _AVR_WDT_H_ */ From 7e3eedc97f090edfefb27dca35fa826cc3491e50 Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Thu, 7 Feb 2019 19:02:42 +1100 Subject: [PATCH 09/11] move ISR declaration check to interrupts.cpp and add explanation --- SampleProjects/TestSomething/test/interrupts.cpp | 7 ++++++- SampleProjects/TestSomething/test/isr_declaration.cpp | 8 -------- 2 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 SampleProjects/TestSomething/test/isr_declaration.cpp diff --git a/SampleProjects/TestSomething/test/interrupts.cpp b/SampleProjects/TestSomething/test/interrupts.cpp index 0a558d84..ed2a7ea7 100644 --- a/SampleProjects/TestSomething/test/interrupts.cpp +++ b/SampleProjects/TestSomething/test/interrupts.cpp @@ -23,6 +23,11 @@ unittest(interrupt_attachment) { assertFalse(state->interrupt[0].attached); } - +// Just check if declaration compiles. +// WDT_vect defines the interrupt of the watchdog timer +// if configured accordinly. +// See avr/interrupt.h +ISR (WDT_vect) { +} unittest_main() diff --git a/SampleProjects/TestSomething/test/isr_declaration.cpp b/SampleProjects/TestSomething/test/isr_declaration.cpp deleted file mode 100644 index 9e1a302e..00000000 --- a/SampleProjects/TestSomething/test/isr_declaration.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -// just check if declaration compiles -ISR (WDT_vect) { -} - -unittest_main() From 6321cbad00fe3a04791cb1cc9997ac10734c1d4a Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Thu, 7 Feb 2019 19:03:03 +1100 Subject: [PATCH 10/11] add explanations --- cpp/arduino/AvrAdc.h | 6 +++++- cpp/arduino/avr/interrupt.h | 10 +++++++++- cpp/arduino/avr/sleep.h | 5 +++++ cpp/arduino/avr/wdt.h | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cpp/arduino/AvrAdc.h b/cpp/arduino/AvrAdc.h index 5690a85a..f5e2cd55 100644 --- a/cpp/arduino/AvrAdc.h +++ b/cpp/arduino/AvrAdc.h @@ -1,5 +1,9 @@ #pragma once -// mock storage to allow access to ADCSRA +// ADCSRA is defined in the CPU specific header files +// like iom328p.h. +// It is liked to _SFR_MEM8 what does not exists in the test environment. +// Therefore we define _SFR_MEM8 here and provide it a storage +// location so that the test code can read/write on it. extern unsigned char sfr_store; #define _SFR_MEM8(mem_addr) sfr_store diff --git a/cpp/arduino/avr/interrupt.h b/cpp/arduino/avr/interrupt.h index 0279f363..72e244a9 100644 --- a/cpp/arduino/avr/interrupt.h +++ b/cpp/arduino/avr/interrupt.h @@ -1,6 +1,14 @@ +/* + This header file defines the macros required for the production + code for AVR CPUs to declare ISRs in the test environment. + See for more details + https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html +*/ #pragma once -// allows the production code to define an ISR method +// Allows the production code to define an ISR method. +// These definitions come from the original avr/interrupt.h file +// https://www.nongnu.org/avr-libc/user-manual/interrupt_8h_source.html #define _VECTOR(N) __vector_ ## N #define ISR(vector, ...) \ extern "C" void vector (void) __VA_ARGS__; \ diff --git a/cpp/arduino/avr/sleep.h b/cpp/arduino/avr/sleep.h index 6d22cbff..a9d5dc8e 100644 --- a/cpp/arduino/avr/sleep.h +++ b/cpp/arduino/avr/sleep.h @@ -1,3 +1,8 @@ +/* + This header file defines the functionality to put AVR CPUs to sleep mode. + For details see + https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html +*/ #pragma once #include diff --git a/cpp/arduino/avr/wdt.h b/cpp/arduino/avr/wdt.h index 145ab7f4..51df4068 100644 --- a/cpp/arduino/avr/wdt.h +++ b/cpp/arduino/avr/wdt.h @@ -1,3 +1,9 @@ +/* + This header file defines the funtionality to use the watchdog timer on + AVR CPUs. + For details see + https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html +*/ #pragma once #include From 2600fb5072be3402a72a0c44d67d4f2bf160df5b Mon Sep 17 00:00:00 2001 From: Peter Rosenberg Date: Thu, 7 Feb 2019 20:11:30 +1100 Subject: [PATCH 11/11] add sleep and wdt examples --- .../AvrSleepInterrupt/.arduino-ci.yaml | 11 +++++++ .../AvrSleepInterrupt/AvrSleepInterrupt.ino | 27 +++++++++++++++++ .../examples/AvrWdtReset/.arduino-ci.yaml | 11 +++++++ .../examples/AvrWdtReset/AvrWdtReset.ino | 29 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 SampleProjects/DoSomething/examples/AvrSleepInterrupt/.arduino-ci.yaml create mode 100644 SampleProjects/DoSomething/examples/AvrSleepInterrupt/AvrSleepInterrupt.ino create mode 100644 SampleProjects/DoSomething/examples/AvrWdtReset/.arduino-ci.yaml create mode 100644 SampleProjects/DoSomething/examples/AvrWdtReset/AvrWdtReset.ino diff --git a/SampleProjects/DoSomething/examples/AvrSleepInterrupt/.arduino-ci.yaml b/SampleProjects/DoSomething/examples/AvrSleepInterrupt/.arduino-ci.yaml new file mode 100644 index 00000000..ef2b2c04 --- /dev/null +++ b/SampleProjects/DoSomething/examples/AvrSleepInterrupt/.arduino-ci.yaml @@ -0,0 +1,11 @@ +compile: + libraries: ~ + platforms: + - uno + - leonardo + +unittest: + libraries: ~ + platforms: + - uno + - leonardo diff --git a/SampleProjects/DoSomething/examples/AvrSleepInterrupt/AvrSleepInterrupt.ino b/SampleProjects/DoSomething/examples/AvrSleepInterrupt/AvrSleepInterrupt.ino new file mode 100644 index 00000000..5d7d7c25 --- /dev/null +++ b/SampleProjects/DoSomething/examples/AvrSleepInterrupt/AvrSleepInterrupt.ino @@ -0,0 +1,27 @@ +#include + +#define BUTTON_INT_PIN 2 + +void setup() { + Serial.begin(115200); + Serial.println("start"); + delay(200); + pinMode(BUTTON_INT_PIN, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(BUTTON_INT_PIN), isrButtonTrigger, FALLING); +} + +void loop() { + // sleep unti an interrupt occurs + sleep_enable(); // enables the sleep bit, a safety pin + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_cpu(); // here the device is actually put to sleep + sleep_disable(); // disables the sleep bit, a safety pin + + Serial.println("interrupt"); + delay(200); +} + +void isrButtonTrigger() { + // nothing to do, wakes up the CPU +} + diff --git a/SampleProjects/DoSomething/examples/AvrWdtReset/.arduino-ci.yaml b/SampleProjects/DoSomething/examples/AvrWdtReset/.arduino-ci.yaml new file mode 100644 index 00000000..ef2b2c04 --- /dev/null +++ b/SampleProjects/DoSomething/examples/AvrWdtReset/.arduino-ci.yaml @@ -0,0 +1,11 @@ +compile: + libraries: ~ + platforms: + - uno + - leonardo + +unittest: + libraries: ~ + platforms: + - uno + - leonardo diff --git a/SampleProjects/DoSomething/examples/AvrWdtReset/AvrWdtReset.ino b/SampleProjects/DoSomething/examples/AvrWdtReset/AvrWdtReset.ino new file mode 100644 index 00000000..a9d8f6b7 --- /dev/null +++ b/SampleProjects/DoSomething/examples/AvrWdtReset/AvrWdtReset.ino @@ -0,0 +1,29 @@ +#include + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + + wdt_enable(WDTO_4S); + // First timeout executes interrupt, second does reset. + // So first LED 4s off + // then LED 4s on + // then reset CPU and start again + WDTCSR |= (1 << WDIE); +} + +void loop() { + // the program is alive...for now. + wdt_reset(); + + while (1) + ; // do nothing. the program will lockup here. + + // Can not get here +} + +ISR (WDT_vect) { + // WDIE & WDIF is cleared in hardware upon entering this ISR + digitalWrite(LED_BUILTIN, HIGH); +} +