From 58cb88f9a082de5345d30948abc7bf16d2dbb8cc Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 14:25:33 +0200 Subject: [PATCH 1/7] Fix bug with serial device access in containers --- Dockerfile | 5 +++-- Dockerfile.arduino | 7 +++++-- Makefile | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index a12397e..538c4e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,9 +5,8 @@ ARG UID=1000 ARG GID=1000 RUN apt-get update && apt-get install -y build-essential -RUN useradd -m ${USER} --uid=${UID} +RUN groupadd --gid=${GID} g${GID} && useradd -m ${USER} --uid=${UID} -g${GID} -G dialout -USER ${UID}:${GID} WORKDIR /usr/src/app @@ -15,4 +14,6 @@ COPY requirements.txt ./ RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt +USER ${UID}:${GID} + CMD [ "echo", "./gen_qr_codes.py" ] diff --git a/Dockerfile.arduino b/Dockerfile.arduino index 4783710..443c33e 100644 --- a/Dockerfile.arduino +++ b/Dockerfile.arduino @@ -6,7 +6,7 @@ ARG USER=docker ARG UID=1000 ARG GID=1000 -RUN groupadd --gid=${GID} g${GID} && useradd -m ${USER} --uid=${UID} -g${GID} -G dialout +RUN useradd --create-home $USER -u $UID RUN cd /tmp/ \ && wget https://github.com/arduino/arduino-cli/releases/download/0.18.3/arduino-cli_0.18.3_Linux_64bit.tar.gz \ @@ -16,10 +16,13 @@ RUN cd /tmp/ \ && cp ./arduino-cli /usr/bin/arduino-cli \ && chmod +x /usr/bin/arduino-cli +RUN usermod -a -G dialout ${USER} + +RUN arduino-cli core update-index && arduino-cli core install arduino:avr + USER ${UID}:${GID} WORKDIR /usr/src/app -RUN arduino-cli core update-index && arduino-cli core install arduino:avr CMD [ "arduino-cli" ] diff --git a/Makefile b/Makefile index 17c25d6..f9c85f2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ DEVICE_SERIAL ?= /dev/ttyUSB0 KEY_NUM ?= 99 -DOCKER_ARDUINO_CLI = docker run --device=$(DEVICE_SERIAL) --mount src="$(shell pwd)",target=/usr/src/app,type=bind -it --rm arduino-cli -DOCKER_PYTHON_CLI = docker run --device=$(DEVICE_SERIAL) --mount src="$(shell pwd)",target=/usr/src/app,type=bind -it --rm hs-ldz-totp-lock +DOCKER_ARDUINO_CLI = docker run --device=$(DEVICE_SERIAL) --mount src="$(shell pwd)",target=/usr/src/app,type=bind -it -u root --rm arduino-cli +DOCKER_PYTHON_CLI = docker run --device=$(DEVICE_SERIAL) --mount src="$(shell pwd)",target=/usr/src/app,type=bind -it -u root --rm hs-ldz-totp-lock decrypt: openssl aes-256-cbc -d -a -md sha512 -pbkdf2 -iter 100000 -salt -pass env:HSLOCK_SECRET -in backup/rawdata.out.enc -out backup/rawdata.out @@ -39,7 +39,7 @@ uno-configure-ds3231: ac-build build $(DOCKER_PYTHON_CLI) python ./configure_DS3231/configure_time.py $(DEVICE_SERIAL) $(DOCKER_PYTHON_CLI) python ./configure_DS3231/dump_eeprom.py $(DEVICE_SERIAL) # Do not uncomment this one - it will reset all locked keys unless the Git copy is up to date. - #$(DOCKER_PYTHON_CLI) python ./configure_DS3231/load_eeprom.py $(DEVICE_SERIAL) backup/rawdata.out + $(DOCKER_PYTHON_CLI) python ./configure_DS3231/load_eeprom.py $(DEVICE_SERIAL) backup/rawdata.out uno-upload-lock: ac-build $(DOCKER_ARDUINO_CLI) arduino-cli board list @@ -52,4 +52,5 @@ uno-upload-isp: ac-build $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/ArduinoISP && arduino-cli compile --fqbn arduino:avr:uno --libraries=../vendor/librares/ && arduino-cli upload --verbose --verify -p $(DEVICE_SERIAL) --fqbn arduino:avr:uno" pro-mini-upload-lock: ac-build + echo RESET pin is 10 $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/hsldz_totp_lock && arduino-cli compile --fqbn arduino:avr:uno --libraries=../vendor/librares/ && arduino-cli upload --verbose --verify -p $(DEVICE_SERIAL) --fqbn arduino:avr:mini --programmer arduinoasisp" From 68a6d6ce458138c5002823089df2d6ae9376367d Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 14:26:28 +0200 Subject: [PATCH 2/7] Add make commands for arduino nano --- Makefile | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Makefile b/Makefile index f9c85f2..cca4f2a 100644 --- a/Makefile +++ b/Makefile @@ -53,4 +53,26 @@ uno-upload-isp: ac-build pro-mini-upload-lock: ac-build echo RESET pin is 10 + echo see https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP/ $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/hsldz_totp_lock && arduino-cli compile --fqbn arduino:avr:uno --libraries=../vendor/librares/ && arduino-cli upload --verbose --verify -p $(DEVICE_SERIAL) --fqbn arduino:avr:mini --programmer arduinoasisp" + + + +nano-configure-ds3231: ac-build build + $(DOCKER_ARDUINO_CLI) arduino-cli board list + $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/configure_DS3231 && arduino-cli compile --fqbn arduino:avr:nano --libraries=../vendor/librares/ && arduino-cli upload -p $(DEVICE_SERIAL) --fqbn arduino:avr:nano" + $(DOCKER_PYTHON_CLI) python ./configure_DS3231/configure_time.py $(DEVICE_SERIAL) + $(DOCKER_PYTHON_CLI) python ./configure_DS3231/dump_eeprom.py $(DEVICE_SERIAL) + # Do not uncomment this one - it will reset all locked keys unless the Git copy is up to date. + $(DOCKER_PYTHON_CLI) python ./configure_DS3231/load_eeprom.py $(DEVICE_SERIAL) backup/rawdata.out + +nano-configure-time: ac-build build + $(DOCKER_ARDUINO_CLI) arduino-cli board list + $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/configure_DS3231 && arduino-cli compile --fqbn arduino:avr:nano --libraries=../vendor/librares/ && arduino-cli upload -p $(DEVICE_SERIAL) --fqbn arduino:avr:nano" + $(DOCKER_PYTHON_CLI) python ./configure_DS3231/configure_time.py $(DEVICE_SERIAL) + + +nano-upload-lock: ac-build + $(DOCKER_ARDUINO_CLI) arduino-cli board list + $(DOCKER_ARDUINO_CLI) bash -c "cd /usr/src/app/hsldz_totp_lock && arduino-cli compile --fqbn arduino:avr:nano --libraries=../vendor/librares/ && arduino-cli upload -p $(DEVICE_SERIAL) --fqbn arduino:avr:nano" + From 01b8675bb2801eeb8b1e3d1bbf48ff3ac0dada8f Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 14:26:53 +0200 Subject: [PATCH 3/7] Add Morse code notification for clock desynchronization. --- hsldz_totp_lock/hsldz_totp_lock.ino | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hsldz_totp_lock/hsldz_totp_lock.ino b/hsldz_totp_lock/hsldz_totp_lock.ino index d8ee949..cc7d7dd 100644 --- a/hsldz_totp_lock/hsldz_totp_lock.ino +++ b/hsldz_totp_lock/hsldz_totp_lock.ino @@ -20,9 +20,9 @@ #define FREQ_OPEN 2500 #define FREQ_ERROR 800 -#define MORSE_SOUND_TIME 100 -#define MORSE_PAUSE 15 -#define MORSE_FREQ 500 +#define MORSE_SOUND_TIME 60 +#define MORSE_PAUSE 5 +#define MORSE_FREQ 880 #define EEPROM_ADDRESS 0x57 #define EEPROM_CODE 32 @@ -218,16 +218,21 @@ bool isTOTPCodeValid(String userInput) { }; DateTime now = RTC.now(); unsigned long currentUnixTimestamp = now.unixtime(); - int timeDeviations[5] = {-60, -30, 0, 30, 60}; + int timeDeviations[7] = {0, -30, 30, 60, -60, -90, 90}; String userCode = userInput.substring(2, 8); Serial.print("Time: "); Serial.println(currentUnixTimestamp); TOTP totp = TOTP(keyBytes, hmacKeySize); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 7; i++) { int delta = timeDeviations[i]; char* correctCode = totp.getCode(currentUnixTimestamp + delta); // Serial.println(userCode); // Serial.println(correctCode); if (userCode == correctCode) { + if (i > 4) { + DateTime now = RTC.now(); + unsigned long currentUnixTimestamp = now.unixtime(); + echo_morse_reversed_int(currentUnixTimestamp); + } // Serial.println("+++++++++++++++++++++++"); return userCode == correctCode; } From 8dfb374aa626f6805d65b36f1ac9231adf6db490 Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 14:30:48 +0200 Subject: [PATCH 4/7] Drop support for lock-open-button --- hsldz_totp_lock/hsldz_totp_lock.ino | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/hsldz_totp_lock/hsldz_totp_lock.ino b/hsldz_totp_lock/hsldz_totp_lock.ino index cc7d7dd..406aec1 100644 --- a/hsldz_totp_lock/hsldz_totp_lock.ino +++ b/hsldz_totp_lock/hsldz_totp_lock.ino @@ -9,7 +9,6 @@ #define BUZZER_PIN 10 #define LOCK_PIN 12 -#define BUTTON_OPEN_PIN 13 #define SOUND_TIME_BUTTON_PRESS 50 #define SOUND_TIME_OPEN 3000 @@ -95,7 +94,6 @@ void setup(){ Serial.begin(9600); Wire.begin(); eeprom.initialize(); - pinMode(BUTTON_OPEN_PIN, INPUT); pinMode(BUZZER_PIN, OUTPUT); pinMode(LOCK_PIN, OUTPUT); int size = sizeof(melodyMain) / sizeof(int); @@ -354,29 +352,7 @@ void makeMaintenance(String userInputPrev) { void loop(){ - - digitalWrite(LOCK_PIN, LOW); - boolean openButtonIsDown = digitalRead(BUTTON_OPEN_PIN); - if (openButtonIsDown) { - // Serial.println(__TIMESTAMP__); - int timeout = 30; // ms - int iterations = 15; - int limit = 7; - int press_counter = 0; - for (int i = 0; i < iterations; i++) { - tone(BUZZER_PIN, FREQ_OPEN_BUTTON_PRESS, timeout - 10); - delay(timeout); - if (digitalRead(BUTTON_OPEN_PIN) == HIGH) { - press_counter += 1; - }; - }; - if (press_counter > limit) { - unlockTheDoor(); - } else { - press_counter = 0; - }; - }; - + digitalWrite(LOCK_PIN, LOW); char customKey = customKeypad.getKey(); if (customKey){ tone(BUZZER_PIN, FREQ_BUTTON_PRESS, SOUND_TIME_BUTTON_PRESS); From c27fa665ef69c45a90c2bcf08c0f1b0586a7bab7 Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 17:50:07 +0200 Subject: [PATCH 5/7] Add submodules into github workflows --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5fee0fe..7a83ccc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master + with: + submodules: 'recursive' - uses: arduino/setup-arduino-cli@v1.1.1 - name: Install platform and compile run: | From 9da0acf7f454c6e9e22e07e314732885a95d7ea8 Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 17:52:54 +0200 Subject: [PATCH 6/7] Drop submodules --- .gitmodules | 3 --- vendor/librares/Watchdog | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 vendor/librares/Watchdog diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 37e82ff..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "vendor/librares/Watchdog"] - path = vendor/librares/Watchdog - url = git@github.com:janelia-arduino/Watchdog.git diff --git a/vendor/librares/Watchdog b/vendor/librares/Watchdog deleted file mode 160000 index 7cbbb1b..0000000 --- a/vendor/librares/Watchdog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7cbbb1b017131973f8d762bb0eec0531f288a08c From e73502c37f6042282550a9c33336a327891d3fb1 Mon Sep 17 00:00:00 2001 From: Aleksy W <63035950+cb4b1fd915@users.noreply.github.com> Date: Sun, 30 Jun 2024 17:57:07 +0200 Subject: [PATCH 7/7] Add Watchdog 3.0.2 --- vendor/librares/Watchdog/LICENSE | 32 +++ vendor/librares/Watchdog/README.org | 41 +++ .../WatchdogTester/WatchdogTester.ino | 97 +++++++ vendor/librares/Watchdog/library.properties | 9 + vendor/librares/Watchdog/src/Watchdog.h | 60 +++++ .../Watchdog/src/Watchdog/Watchdog.cpp | 35 +++ .../Watchdog/src/Watchdog/WatchdogBaseAvr.cpp | 18 ++ .../Watchdog/src/Watchdog/WatchdogBaseAvr.h | 25 ++ .../src/Watchdog/WatchdogBaseMegaavr.cpp | 18 ++ .../src/Watchdog/WatchdogBaseMegaavr.h | 25 ++ .../src/Watchdog/WatchdogBaseTeensy2.cpp | 111 ++++++++ .../src/Watchdog/WatchdogBaseTeensy2.h | 28 +++ .../src/Watchdog/WatchdogBaseTeensy3.cpp | 55 ++++ .../src/Watchdog/WatchdogBaseTeensy3.h | 26 ++ .../src/Watchdog/WatchdogBaseTeensy4.cpp | 35 +++ .../src/Watchdog/WatchdogBaseTeensy4.h | 28 +++ .../librares/Watchdog/src/Watchdog/WdtAvr.cpp | 79 ++++++ .../librares/Watchdog/src/Watchdog/WdtAvr.h | 37 +++ .../Watchdog/src/Watchdog/WdtTeensy4.h | 88 +++++++ .../Watchdog/src/Watchdog/WdtTeensy4.tpp | 238 ++++++++++++++++++ 20 files changed, 1085 insertions(+) create mode 100644 vendor/librares/Watchdog/LICENSE create mode 100644 vendor/librares/Watchdog/README.org create mode 100644 vendor/librares/Watchdog/examples/WatchdogTester/WatchdogTester.ino create mode 100644 vendor/librares/Watchdog/library.properties create mode 100644 vendor/librares/Watchdog/src/Watchdog.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/Watchdog.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseAvr.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseAvr.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseMegaavr.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseMegaavr.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy2.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy2.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WdtAvr.cpp create mode 100644 vendor/librares/Watchdog/src/Watchdog/WdtAvr.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.h create mode 100644 vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.tpp diff --git a/vendor/librares/Watchdog/LICENSE b/vendor/librares/Watchdog/LICENSE new file mode 100644 index 0000000..76862c5 --- /dev/null +++ b/vendor/librares/Watchdog/LICENSE @@ -0,0 +1,32 @@ +License Agreement +(3-clause BSD License) +Janelia Research Campus Software Copyright 1.1 + +Copyright (c) 2021, Howard Hughes Medical Institute +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the Howard Hughes Medical Institute nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/librares/Watchdog/README.org b/vendor/librares/Watchdog/README.org new file mode 100644 index 0000000..8fe506c --- /dev/null +++ b/vendor/librares/Watchdog/README.org @@ -0,0 +1,41 @@ +#+TITLE: Watchdog +#+AUTHOR: Peter Polidoro +#+EMAIL: peterpolidoro@gmail.com + +* Library Information + - Name :: Watchdog + - Version :: 3.0.2 + - License :: BSD + - URL :: https://github.com/janelia-arduino/Watchdog + - Author :: Peter Polidoro, Antonio Brewer, Steve Sawtelle + - Email :: peterpolidoro@gmail.com + + The watchdog monitors the operation of the system by expecting periodic + communication from the software, generally known as servicing or refreshing the + watchdog. If this periodic refreshing does not occur, the watchdog resets the + system. Works with avr, megaavr, and teensy processors. + + When the watchdog timer is enabled, a call to the reset instruction is + required before the timer expires after the timeout duration, otherwise a + watchdog-initiated device reset will occur. + +** Timeout Durations + + Possible timeout durations are 15ms, 30ms, 60ms, 120ms, 250ms, 500ms, 1s, 2s, 4s, and 8s. + + Not all devices allow timeout durations. + - Teensy 4.x does not allow timeout durations below 1s. + - Other processors do not allow timeout durations of 4s or 8s. + +** Teensy 4 + + The watchdog code for the Teensy 4 was written by Antonio Brewer: + + https://github.com/tonton81/WDT_T4 + +** Tripped Method + + The tripped method was written by Steve Sawtelle. + + Unfortunately this method does not work with certain microprocessors and + boards, such as the Arduino Mega 2560, Teensy 2.0, and Teensy++ 2.0. diff --git a/vendor/librares/Watchdog/examples/WatchdogTester/WatchdogTester.ino b/vendor/librares/Watchdog/examples/WatchdogTester/WatchdogTester.ino new file mode 100644 index 0000000..e69c1ea --- /dev/null +++ b/vendor/librares/Watchdog/examples/WatchdogTester/WatchdogTester.ino @@ -0,0 +1,97 @@ +// ---------------------------------------------------------------------------- +// WatchdogTester.ino +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +// This sample program shows how to use the watchdog timer. + +// When the device first powers on, it turns the LED off for 1 seconds. It then +// turns the LED on, and pauses for 4 seconds letting you know it is ready to +// start. Watchdog is initialized and the loop starts. It will flash the LED and +// reset watchdog for the first 6 secs. After that, it stops resetting watchdog. +// This causes the watchdog to reboot the device. When the device powers on +// after a watchdog device reset, it blinks the LED twice for 1.5 seconds before +// flashing the LED to let you know the watchdog had been previously tripped. + +#include + + +const unsigned long SETUP_LED_OFF_DURATION = 1000; +const unsigned long SETUP_LED_ON_IF_NOT_TRIPPED_DURATION = 4000; +const unsigned long SETUP_LED_ON_IF_TRIPPED_DURATION = 1500; +const unsigned long TIMEOUT_DURATION = 6000; +const unsigned long BLINK_HALF_PERIOD = 100; +const unsigned long RESET_DURATION = 500; + +Watchdog watchdog; +unsigned long enabled_time; +unsigned long blink_time; +unsigned long reset_time; + +void setLedOff() +{ + digitalWrite(LED_BUILTIN,LOW); + delay(SETUP_LED_OFF_DURATION); +} + +void setLedOn(unsigned long duration) +{ + digitalWrite(LED_BUILTIN,HIGH); + delay(duration); +} + +void toggleLed() +{ + digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN)); +} + +void setup() +{ + pinMode(LED_BUILTIN,OUTPUT); + + // Indicate we are starting over by holding led off + setLedOff(); + + // Indicate we are in setup by holding LED on + if (!watchdog.tripped()) + { + // blink once to indicate power cycle reset + setLedOn(SETUP_LED_ON_IF_NOT_TRIPPED_DURATION); + } + else + { + // blink twice to indicate watchdog tripped reset + setLedOn(SETUP_LED_ON_IF_TRIPPED_DURATION); + setLedOff(); + setLedOn(SETUP_LED_ON_IF_TRIPPED_DURATION); + } + + // Setup watchdog + watchdog.enable(Watchdog::TIMEOUT_1S); + + enabled_time = millis(); + blink_time = enabled_time; + reset_time = enabled_time; +} + +void loop() +{ + const unsigned long time = millis(); + + // Toggle led + if ((time - blink_time) >= BLINK_HALF_PERIOD) + { + blink_time = time; + toggleLed(); + } + + // Stop resetting watchdog after timeout + if (((time - enabled_time) <= TIMEOUT_DURATION) && + ((time - reset_time) >= RESET_DURATION)) + { + reset_time = time; + watchdog.reset(); + } +} diff --git a/vendor/librares/Watchdog/library.properties b/vendor/librares/Watchdog/library.properties new file mode 100644 index 0000000..299775f --- /dev/null +++ b/vendor/librares/Watchdog/library.properties @@ -0,0 +1,9 @@ +name=Watchdog +version=3.0.2 +author=Peter Polidoro , Antonio Brewer, Steve Sawtelle +maintainer=Peter Polidoro +sentence=Watchdog resets the device if the timer expires before the watchdog is reset. +paragraph=Like this project? Please star it on GitHub! +category=Device Control +url=https://github.com/janelia-arduino/Watchdog.git +architectures=avr,megaavr,teensy diff --git a/vendor/librares/Watchdog/src/Watchdog.h b/vendor/librares/Watchdog/src/Watchdog.h new file mode 100644 index 0000000..75da490 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog.h @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------- +// Watchdog.h +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include + +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) + +#include "Watchdog/WatchdogBaseTeensy2.h" + +#elif defined(__AVR__) && defined(MCUSR) && !defined(__AVR_ATmega32U4__) && !defined(__AVR_AT90USB1286__) + +#include "Watchdog/WatchdogBaseAvr.h" + +#elif defined(__AVR__) && defined(RSTCTRL_RSTFR) + +#include "Watchdog/WatchdogBaseMegaavr.h" + +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + +#include "Watchdog/WatchdogBaseTeensy3.h" + +#elif defined(__IMXRT1062__) + +#include "Watchdog/WatchdogBaseTeensy4.h" + +#endif + + +class Watchdog : public WatchdogBase +{ +public: + enum Timeout { + TIMEOUT_15MS=15, + TIMEOUT_30MS=30, + TIMEOUT_60MS=60, + TIMEOUT_120MS=120, + TIMEOUT_250MS=250, + TIMEOUT_500MS=500, + TIMEOUT_1S=1000, + TIMEOUT_2S=2000, + TIMEOUT_4S=4000, + TIMEOUT_8S=8000 + }; + Watchdog(); + void enable(Timeout timeout=TIMEOUT_1S); + bool enabled(); + void reset(); + bool tripped(); +private: + bool enabled_; +}; + +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/Watchdog.cpp b/vendor/librares/Watchdog/src/Watchdog/Watchdog.cpp new file mode 100644 index 0000000..57c6a58 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/Watchdog.cpp @@ -0,0 +1,35 @@ +// ---------------------------------------------------------------------------- +// Watchdog.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "../Watchdog.h" + + +Watchdog::Watchdog() + : enabled_{false} +{ +} + +void Watchdog::enable(Timeout timeout) +{ + WatchdogBase::enable(timeout); + enabled_ = true; +} + +bool Watchdog::enabled() +{ + return enabled_; +} + +void Watchdog::reset() +{ + WatchdogBase::reset(); +} + +bool Watchdog::tripped() +{ + return WatchdogBase::tripped(); +} diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseAvr.cpp b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseAvr.cpp new file mode 100644 index 0000000..5e1b862 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseAvr.cpp @@ -0,0 +1,18 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseAvr.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WatchdogBaseAvr.h" + +#if defined(__AVR__) && defined(MCUSR) && !defined(__AVR_ATmega32U4__) && !defined(__AVR_AT90USB1286__) + + +bool WatchdogBase::tripped() +{ + return ( (MCUSR & (1< + +#if defined(__AVR__) && defined(MCUSR) && !defined(__AVR_ATmega32U4__) && !defined(__AVR_AT90USB1286__) + +#include "WdtAvr.h" + + +class WatchdogBase : public WdtAvr +{ +public: + bool tripped(); +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseMegaavr.cpp b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseMegaavr.cpp new file mode 100644 index 0000000..779b727 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseMegaavr.cpp @@ -0,0 +1,18 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseMegaavr.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WatchdogBaseMegaavr.h" + +#if defined(__AVR__) && defined(RSTCTRL_RSTFR) + + +bool WatchdogBase::tripped() +{ + return ( (RSTCTRL_RSTFR & (1< + +#if defined(__AVR__) && defined(RSTCTRL_RSTFR) + +#include "WdtAvr.h" + + +class WatchdogBase : public WdtAvr +{ +public: + bool tripped(); +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy2.cpp b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy2.cpp new file mode 100644 index 0000000..658aaa7 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy2.cpp @@ -0,0 +1,111 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseTeensy2.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WatchdogBaseTeensy2.h" + +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) + + +//WDT Interrupt which will soft reset the board +ISR(WDT_vect) +{ + wdt_disable(); + _restart_Teensyduino_(); +} + +void WatchdogBase::reset() +{ + wdt_reset(); +} + +bool WatchdogBase::tripped() +{ + return ( (MCUSR & (1< + +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) + +#include +#include + +class WatchdogBase +{ +public: + void reset(); + bool tripped(); +protected: + void enable(int timeout_ms); +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.cpp b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.cpp new file mode 100644 index 0000000..73c60ba --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.cpp @@ -0,0 +1,55 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseTeensy3.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WatchdogBaseTeensy3.h" + +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + + +void WatchdogBase::reset() +{ + noInterrupts(); + + WDOG_REFRESH = 0xA602; + WDOG_REFRESH = 0xB480; + + interrupts(); +} + +bool WatchdogBase::tripped() +{ + return ( (RCM_SRS0 & RCM_SRS0_WDOG) != 0 ); +} + +void WatchdogBase::enable(int timeout_ms) +{ + const uint32_t WDT_CYCLES_PER_MS = F_CPU/10000; + uint8_t REGISTER_BITS = 16; + + uint16_t tovalh = (uint16_t)((WDT_CYCLES_PER_MS*timeout_ms)>>REGISTER_BITS); + uint16_t tovall = (uint16_t)(WDT_CYCLES_PER_MS*timeout_ms); + + noInterrupts(); + + WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; + WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; + + delayMicroseconds(1); + + WDOG_TOVALH = tovalh; + WDOG_TOVALL = tovall; + + WDOG_PRESC = 0x400; + + WDOG_STCTRLH |= WDOG_STCTRLH_ALLOWUPDATE | + WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | + WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_CLKSRC; + + interrupts(); +} + +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.h b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.h new file mode 100644 index 0000000..f0eaf2f --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy3.h @@ -0,0 +1,26 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseTeensy3.h +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#ifndef WATCHDOG_BASE_TEENSY3_H +#define WATCHDOG_BASE_TEENSY3_H + +#include + +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + + +class WatchdogBase +{ +public: + void reset(); + bool tripped(); +protected: + void enable(int timeout_ms); +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.cpp b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.cpp new file mode 100644 index 0000000..6d265e7 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.cpp @@ -0,0 +1,35 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseTeensy4.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WatchdogBaseTeensy4.h" + +#if defined(__IMXRT1062__) + + +void WatchdogBase::reset() +{ + wdt_.feed(); +} + +bool WatchdogBase::tripped() +{ + return ( (SRC_SRSR & 0x10) != 0); +} + +void WatchdogBase::enable(int timeout_ms) +{ + uint32_t timeout_s = timeout_ms / 1000; + if (timeout_s < 1) + { + timeout_s = 1; + } + WDT_timings_t config; + config.timeout = timeout_s; + wdt_.begin(config); +} + +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.h b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.h new file mode 100644 index 0000000..8461acb --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WatchdogBaseTeensy4.h @@ -0,0 +1,28 @@ +// ---------------------------------------------------------------------------- +// WatchdogBaseTeensy4.h +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#ifndef WATCHDOG_BASE_TEENSY4_H +#define WATCHDOG_BASE_TEENSY4_H + +#if defined(__IMXRT1062__) + +#include "WdtTeensy4.h" + + +class WatchdogBase +{ +public: + void reset(); + bool tripped(); +protected: + void enable(int timeout_ms); +private: + WDT_T4 wdt_; +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WdtAvr.cpp b/vendor/librares/Watchdog/src/Watchdog/WdtAvr.cpp new file mode 100644 index 0000000..dcc98ff --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WdtAvr.cpp @@ -0,0 +1,79 @@ +// ---------------------------------------------------------------------------- +// WdtAvr.cpp +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#include "WdtAvr.h" + +#if defined(__AVR__) + + +void WdtAvr::reset() +{ + wdt_reset(); +} + +void WdtAvr::enable(int timeout_ms) +{ + uint8_t wdt_timeout = 0; + + switch (timeout_ms) + { + case 15: + { + wdt_timeout = WDTO_15MS; + break; + } + case 30: + { + wdt_timeout = WDTO_30MS; + break; + } + case 60: + { + wdt_timeout = WDTO_60MS; + break; + } + case 120: + { + wdt_timeout = WDTO_120MS; + break; + } + case 250: + { + wdt_timeout = WDTO_250MS; + break; + } + case 500: + { + wdt_timeout = WDTO_500MS; + break; + } + case 1000: + { + wdt_timeout = WDTO_1S; + break; + } + case 2000: + { + wdt_timeout = WDTO_2S; + break; + } + case 4000: + { + wdt_timeout = WDTO_4S; + break; + } + case 8000: + { + wdt_timeout = WDTO_8S; + break; + } + } + + wdt_enable(wdt_timeout); +} + +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WdtAvr.h b/vendor/librares/Watchdog/src/Watchdog/WdtAvr.h new file mode 100644 index 0000000..cca0efa --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WdtAvr.h @@ -0,0 +1,37 @@ +// ---------------------------------------------------------------------------- +// WdtAvr.h +// +// Authors: +// Peter Polidoro peterpolidoro@gmail.com +// ---------------------------------------------------------------------------- + +#ifndef WDT_AVR_H +#define WDT_AVR_H + +#if defined(__AVR__) + +#include + +#if !defined(WDTO_4S) + +#define WDTO_4S WDTO_1S + +#endif + +#if !defined(WDTO_8S) + +#define WDTO_8S WDTO_1S + +#endif + + +class WdtAvr +{ +public: + void reset(); +protected: + void enable(int timeout_ms); +}; + +#endif +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.h b/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.h new file mode 100644 index 0000000..204a342 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.h @@ -0,0 +1,88 @@ +// MIT License + +// Copyright (c) 2020 Antonio Brewer + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#if !defined(_WATCHDOG_T4_H_) && defined(__IMXRT1062__) +#define _WATCHDOG_T4_H_ + +#include "Arduino.h" + +typedef void (*watchdog_class_ptr)(); + +typedef enum WDT_DEV_TABLE { + WDT1 = (uint32_t)0x400B8000, + WDT2 = (uint32_t)0x400D0000, + WDT3 = (uint32_t)0x400BC000, + EWM = (uint32_t)0x400B4000 +} WDT_DEV_TABLE; + +typedef enum RTWDOG_CLK_TABLE { + BUS_CLK = 0, + LPO_CLK = 1, + INT_CLK = 2, + ER_CLK = 3 +} RTWDOG_CLK_TABLE; + +typedef struct WDT_timings_t { + double trigger = 5; + double timeout = 10; + double window = 0; + uint8_t pin = 0; + RTWDOG_CLK_TABLE clock = LPO_CLK; /* default clock, 32KHz */ + bool lp_suspend = 0; + uint8_t input = 0; + bool update = 1; + bool cmd32en = 1; + watchdog_class_ptr callback = nullptr; +} WDT_timings_t; + +#define WDT_CLASS template +#define WDT_FUNC template +#define WDT_OPT WDT_T4<_device> + +class WDT_T4_Base { +public: + virtual void watchdog_isr() = 0; + virtual void ewatchdog_isr() = 0; + watchdog_class_ptr watchdog_class_handler = 0; +private: +}; + +static WDT_T4_Base* _WDT1 = nullptr; +static WDT_T4_Base* _WDT2 = nullptr; +static WDT_T4_Base* _WDT3 = nullptr; +static WDT_T4_Base* _EWM = nullptr; + +WDT_CLASS class WDT_T4 : public WDT_T4_Base { +public: + void begin(WDT_timings_t config); + void callback(watchdog_class_ptr handler) { watchdog_class_handler = handler; } + void reset(); + void feed(); + bool expired(); +private: + watchdog_class_ptr watchdog_class_handler; + void watchdog_isr(); + void ewatchdog_isr(); +}; + +#include "WdtTeensy4.tpp" +#endif diff --git a/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.tpp b/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.tpp new file mode 100644 index 0000000..3aef426 --- /dev/null +++ b/vendor/librares/Watchdog/src/Watchdog/WdtTeensy4.tpp @@ -0,0 +1,238 @@ +// MIT License + +// Copyright (c) 2020 Antonio Brewer + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#if defined(__IMXRT1062__) + +#define WDOGb_WCR(b) (*(volatile uint16_t*)(b)) +#define WDOGb_WSR(b) (*(volatile uint16_t*)(b+0x2)) +#define WDOGb_WRSR(b) (*(volatile uint16_t*)(b+0x4)) +#define WDOGb_WICR(b) (*(volatile uint16_t*)(b+0x6)) +#define WDOGb_WMCR(b) (*(volatile uint16_t*)(b+0x8)) +#define WDOGb_CS(b) (*(volatile uint16_t*)(b)) +#define WDOGb_CNT(b) (*(volatile uint16_t*)(b+0x4)) +#define WDOGb_CNT32(b) (*(volatile uint32_t*)(b+0x4)) +#define WDOGb_TOVAL(b) (*(volatile uint16_t*)(b+0x8)) +#define WDOGb_WIN(b) (*(volatile uint16_t*)(b+0xC)) +#define WDOG_WICR_WIE ((uint16_t)(1<<15)) +#define WDOG_WICR_WTIS ((uint16_t)(1<<14)) +#define WDOG_WICR_WICT(n) ((uint16_t)((n) & 0xFF)) +#define EWM_CTRL_INTEN ((uint8_t)(1<<3)) +#define EWM_CTRL_EWMEN ((uint8_t)(1<<0)) + +static void watchdog1_isr(); +static void watchdog2_isr(); +static void watchdog3_isr(); +static void ewm_isr(); + +WDT_FUNC void WDT_OPT::begin(WDT_timings_t config) { + IOMUXC_GPR_GPR16 |= 0x200000; /* undocumented register found by PaulS to fix reset */ + uint32_t nvicIRQ = 0; + watchdog_class_handler = config.callback; + + if ( _device == WDT1 ) { + CCM_CCGR3 |= (3UL << 16); /* enable WDOG1 clocks */ + _WDT1 = this; + nvicIRQ = IRQ_WDOG1; + _VectorsRam[16 + nvicIRQ] = watchdog1_isr; + } + if ( _device == WDT2 ) { + CCM_CCGR5 |= (3UL << 10); /* enable WDOG2 clocks */ + _WDT2 = this; + nvicIRQ = IRQ_WDOG2; + _VectorsRam[16 + nvicIRQ] = watchdog2_isr; + } + if ( _device == WDT3 ) { + CCM_CCGR5 |= (3UL << 4); /* enable WDOG3 clocks */ + _WDT3 = this; + nvicIRQ = IRQ_RTWDOG; + _VectorsRam[16 + nvicIRQ] = watchdog3_isr; + + bool preScaler = 0; + uint16_t toVal = 0; + + if ( config.clock == LPO_CLK || config.clock == INT_CLK ) { /* LPO_CLOCK & INT_CLOCK are 32KHz */ + double highest_limit_without_prescaler = ((1.0f/32.0f)*65535.0f); + double lowest_limit_without_prescaler = ((1.0f/32.0f)*1.0f); + double highest_limit_with_prescaler = ((255.0f/32.0f)*65535.0f); + double lowest_limit_with_prescaler = ((255.0f/32.0f)*1.0f); + (void)lowest_limit_with_prescaler; /* unused, kept for reference */ + config.timeout = constrain(config.timeout, lowest_limit_without_prescaler, highest_limit_with_prescaler); + config.window = constrain(config.window, lowest_limit_without_prescaler, highest_limit_with_prescaler); + if ( config.timeout < highest_limit_without_prescaler ) { /* prescaler not needed */ + toVal = (config.timeout/(1.0f/32.0f)); + if ( config.window ) config.window = (config.window/(1.0f/32.0f)); + } + else { /* use prescaler */ + preScaler = 1; + toVal = (config.timeout/(255.0f/32.0f)); + if ( config.window ) config.window = (config.window/(255.0f/32.0f)); + } + } + + __disable_irq(); + if ( WDOGb_CS(_device) & WDOG_CS_CMD32EN ) WDOGb_CNT32(_device) = 0xD928C520; + else { + WDOGb_CNT(_device) = 0xC520; + WDOGb_CNT(_device) = 0xD928; + } + WDOGb_WIN(_device) = config.window; + WDOGb_TOVAL(_device) = toVal; + WDOGb_CS(_device) = ((config.window) ? WDOG_CS_WIN : 0) | ((preScaler) ? WDOG_CS_PRES : 0) | WDOG_CS_FLG | (config.update << 5) | (config.cmd32en << 13) | (config.clock << 8) | ((config.callback) ? WDOG_CS_INT : 0) | WDOG_CS_EN; + __enable_irq(); + NVIC_ENABLE_IRQ(nvicIRQ); + return; + } + + if ( _device == EWM ) { + CCM_CCGR3 |= (3UL << 14); /* enable EWM clocks */ + _EWM = this; + nvicIRQ = IRQ_EWM; + _VectorsRam[16 + nvicIRQ] = ewm_isr; + + if ( config.pin == 21 ) { + IOMUXC_CSI_DATA06_SELECT_INPUT = 0; + IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11 = 0x11; // pin21 + IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11 = 0x30b0; // pin21 + } + else if ( config.pin == 25 ) { + IOMUXC_CSI_DATA06_SELECT_INPUT = 0; + IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13 = 0x13; // pin25 + IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13 = 0x30b0; // pin25 + } + else config.pin = 0; + + double highest_limit_without_prescaler = ((1.0f/32.0f)*254.0f); + (void)highest_limit_without_prescaler; /* unused, kept for reference */ + double lowest_limit_without_prescaler = ((1.0f/32.0f)*1.0f); + double highest_limit_with_prescaler = ((255.0f/32.0f)*254.0f); + double lowest_limit_with_prescaler = ((255.0f/32.0f)*1.0f); + (void)lowest_limit_with_prescaler; /* unused, kept for reference */ + config.timeout = constrain(config.timeout, lowest_limit_without_prescaler, highest_limit_with_prescaler); + config.window = constrain(config.window, lowest_limit_without_prescaler, highest_limit_with_prescaler); + config.timeout = (config.timeout/(255.0f/32.0f)); + config.window = (config.window/(255.0f/32.0f)); + EWM_CLKPRESCALER = 0xFF; + EWM_CLKCTRL = 0x0; + EWM_CMPL = (uint8_t)config.window; + EWM_CMPH = (uint8_t)config.timeout; + EWM_CTRL = ((config.callback) ? EWM_CTRL_INTEN : 0) | EWM_CTRL_EWMEN; + NVIC_ENABLE_IRQ(nvicIRQ); + return; + } + + if ( config.pin ) { + /* WDOG1 PINS */ + if ( config.pin == 19 ) { + IOMUXC_QTIMER3_TIMER0_SELECT_INPUT = 1; + IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 0x14; // pin19 + IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 = 0x30b0; // pin19 + } + else if ( config.pin == 20 ) { + IOMUXC_CSI_DATA07_SELECT_INPUT = 0; + IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10 = 0x11; // pin20 + IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10 = 0x30b0; // pin20 + } + + /* WDOG2 PINS */ + else if ( config.pin == 24 ) { + IOMUXC_LPI2C4_SCL_SELECT_INPUT = 1; + IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12 = 0x13; // pin24 + IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12 = 0x30b0; // pin24 + } + else if ( config.pin == 13 ) { + IOMUXC_LPSPI4_SCK_SELECT_INPUT = 0; + IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 0x16; // pin13 + IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0x30b0; // pin13 + } + else config.pin = 0; + } + + config.timeout = constrain(config.timeout, 0.5f, 128.0f); /* timeout to reset */ + config.timeout = (config.timeout - 0.5f)/0.5f; + WDOGb_WCR(_device) = WDOG_WCR_SRS | WDOG_WCR_WT((uint8_t)config.timeout); /* do NOT negate the reset signal when clearing register */ + config.trigger = constrain(config.trigger, 0.0f, 127.5); /* callback trigger before timeout */ + config.trigger /= 0.5f; + WDOGb_WICR(_device) = ((config.callback) ? WDOG_WICR_WIE : 0) | WDOG_WICR_WTIS | WDOG_WICR_WICT((uint8_t)config.trigger); /* enable interrupt, clear interrupt */ + WDOGb_WCR(_device) |= WDOG_WCR_WDE | ((config.lp_suspend) ? WDOG_WCR_WDZST : 0) | WDOG_WCR_WDA | WDOG_WCR_WDT | WDOG_WCR_SRE; + WDOGb_WMCR(_device) = 0; /* Disable power down counter, else GPIO will force LOW indefinately after 16 seconds */ + NVIC_ENABLE_IRQ(nvicIRQ); +} + +WDT_FUNC bool WDT_OPT::expired() { + if ( WDT3 == _device ) return SRC_SRSR & SRC_SRSR_WDOG3_RST_B; + if ( EWM == _device ) return 0; /* No status register? */ + return WDOGb_WRSR(_device) & WDOG_WRSR_TOUT; +} + +WDT_FUNC void WDT_OPT::reset() { + if ( WDT3 == _device || EWM == _device ) SCB_AIRCR = 0x05FA0004; /* WDT3 & EWM doesn't have a reset register, fall back to ARM */ + WDOGb_WCR(_device) &= ~WDOG_WCR_SRS; +} + +WDT_FUNC void WDT_OPT::feed() { + if ( _device == EWM ) { + EWM_SERV = 0xB4; + EWM_SERV = 0x2C; + return; + } + if ( _device == WDT1 || _device == WDT2 ) { + WDOGb_WSR(_device) = 0x5555; + WDOGb_WSR(_device) = 0xAAAA; + } + else { + if ( WDOGb_CS(_device) & WDOG_CS_CMD32EN ) WDOGb_CNT32(_device) = 0xB480A602; + else { + WDOGb_CNT(_device) = 0xA602; + WDOGb_CNT(_device) = 0xB480; + } + } +} + +void watchdog1_isr() { + if ( _WDT1 ) _WDT1->watchdog_isr(); +} + +void watchdog2_isr() { + if ( _WDT2 ) _WDT2->watchdog_isr(); +} + +void watchdog3_isr() { + if ( _WDT3 ) _WDT3->watchdog_isr(); +} + +WDT_FUNC void WDT_OPT::watchdog_isr() { + if ( watchdog_class_handler ) watchdog_class_handler(); + if ( WDT3 == _device ) WDOGb_CS(_device) = WDOG_CS_FLG; + else WDOGb_WICR(_device) |= WDOG_WICR_WTIS; + asm volatile ("dsb"); /* disable double firing of interrupt */ +} + +void ewm_isr() { + if ( _EWM ) _EWM->ewatchdog_isr(); +} + +WDT_FUNC void WDT_OPT::ewatchdog_isr() { + if ( watchdog_class_handler ) watchdog_class_handler(); + EWM_CTRL &= ~(1U << 3); /* disable further interrupts, EWM has been triggered, only way out is reset */ + asm volatile ("dsb"); /* disable double firing of interrupt */ +} +#endif