diff --git a/README.md b/README.md index 9b63694..a32baf5 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ ISR(WATCHDOG) { ## Версии - v2.1 - v2.2 - оптимизация и мелкие исправления +- v2.3 - исправлена ошибка компиляции на тини ## Баги и обратная связь diff --git a/library.properties b/library.properties index 86a596e..6f00a89 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=GyverWDT -version=2.2 +version=2.3.0 author=AlexGyver maintainer=AlexGyver sentence=Advanced WDT control library for ATmega328p/32U4/2560 & ATtiny85/84/167 diff --git a/src/GyverWDT.h b/src/GyverWDT.h index 74e4d04..39f935d 100644 --- a/src/GyverWDT.h +++ b/src/GyverWDT.h @@ -1,31 +1,31 @@ /* Библиотека для управления watchdog таймером, список поддерживаемых МК ниже. - ВНИМАНИЕ! Использование watchdog с Arduino-загрузчиком версии 'OLD' НЕДОСТУПНО + ВНИМАНИЕ! Использование watchdog с Arduino-загрузчиком версии 'OLD' НЕДОСТУПНО Документация: https://alexgyver.ru/gyverwdt/ GitHub: https://github.com/GyverLibs/GyverWDT - + Возможности: - Настройка режима работы watchdog - Настройка прерываний Поддержка МК: - > AVR ATmega48p/88p/168p/328p (Arduino UNO/NANO/MINI/PRO MINI) - > AVR ATmega32u4 (Arduino LEONARDO/PRO MICRO) - > AVR ATmega1280/2560 (Arduino MEGA) - > AVR ATtiny87/167 (Naked chip) - > AVR ATtiny45/85 (Naked chip) - > AVR ATtiny44/84 (Naked chip) - > AVR ATtiny13 (Naked chip) - Доступные режимы: - > RST_MODE (RESET_MODE) - Сброс МК при тайм-ауте - > ISR_MODE (INTERRUPT_MODE) - Прерывание при тайм-ауте - > ISR_RST_MODE (INTERRUPT_RESET_MODE) - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) - + > AVR ATmega48p/88p/168p/328p (Arduino UNO/NANO/MINI/PRO MINI) + > AVR ATmega32u4 (Arduino LEONARDO/PRO MICRO) + > AVR ATmega1280/2560 (Arduino MEGA) + > AVR ATtiny87/167 (Naked chip) + > AVR ATtiny45/85 (Naked chip) + > AVR ATtiny44/84 (Naked chip) + > AVR ATtiny13 (Naked chip) + Доступные режимы: + > RST_MODE (RESET_MODE) - Сброс МК при тайм-ауте + > ISR_MODE (INTERRUPT_MODE) - Прерывание при тайм-ауте + > ISR_RST_MODE (INTERRUPT_RESET_MODE) - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) + Egor 'Nich1con' Zaharov for AlexGyver, alex@alexgyver.ru https://alexgyver.ru/ MIT License Версии: - v2.2 ~ 08.11.2021 + v2.3 ~ 08.11.2021 */ #ifndef GyverWDT_h @@ -33,92 +33,89 @@ #include /************************ -* Режим работы watchdog * -************************/ + * Режим работы watchdog * + ************************/ /* Краткие - определения */ -#define RST_MODE (RESET_MODE) // - Сброс МК при тайм-ауте -#define ISR_MODE (INTERRUPT_MODE) // - Прерывание при тайм-ауте -#define ISR_RST_MODE (INTERRUPT_RESET_MODE) // - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) +#define RST_MODE (RESET_MODE) // - Сброс МК при тайм-ауте +#define ISR_MODE (INTERRUPT_MODE) // - Прерывание при тайм-ауте +#define ISR_RST_MODE (INTERRUPT_RESET_MODE) // - Прерывание при тайм-ауте и переключение в RST_MODE (RESET_MODE) /* Legacy - определения */ -#define RESET_MODE (1 << WDE) -#define INTERRUPT_MODE (1 << WDIE) -#define INTERRUPT_RESET_MODE (1 << WDE | 1 << WDIE) - +#define RESET_MODE (1 << WDE) +#define INTERRUPT_MODE (1 << WDIE) +#define INTERRUPT_RESET_MODE (1 << WDE | 1 << WDIE) + /* Вектор прерывания watchdog */ -#define WATCHDOG WDT_vect +#define WATCHDOG WDT_vect /* ISR(WATCHDOG){ - ... + ... } */ - /**************************************************** -* Предделители watchdog и приблизительные тайм-ауты * -****************************************************/ + * Предделители watchdog и приблизительные тайм-ауты * + ****************************************************/ /* Выбор по тайм-ауту, примерный разброс ~ 10% */ -#define WDT_TIMEOUT_16MS (WDT_PRESCALER_2) // (16 ± 1.6) ms -#define WDT_TIMEOUT_32MS (WDT_PRESCALER_4) // (32 ± 3.2) ms -#define WDT_TIMEOUT_64MS (WDT_PRESCALER_8) // (64 ± 6.4) ms -#define WDT_TIMEOUT_128MS (WDT_PRESCALER_16) // (128 ± 12.8) ms -#define WDT_TIMEOUT_256MS (WDT_PRESCALER_32) // (256 ± 25.6) ms -#define WDT_TIMEOUT_512MS (WDT_PRESCALER_64) // (512 ± 51.2) ms -#define WDT_TIMEOUT_1S (WDT_PRESCALER_128) // (1024 ± 102.4) ms -#define WDT_TIMEOUT_2S (WDT_PRESCALER_256) // (2048 ± 204.8) ms -#define WDT_TIMEOUT_4S (WDT_PRESCALER_512) // (4096 ± 409.6) ms -#define WDT_TIMEOUT_8S (WDT_PRESCALER_1024) // (8192 ± 819.2) ms +#define WDT_TIMEOUT_16MS (WDT_PRESCALER_2) // (16 ± 1.6) ms +#define WDT_TIMEOUT_32MS (WDT_PRESCALER_4) // (32 ± 3.2) ms +#define WDT_TIMEOUT_64MS (WDT_PRESCALER_8) // (64 ± 6.4) ms +#define WDT_TIMEOUT_128MS (WDT_PRESCALER_16) // (128 ± 12.8) ms +#define WDT_TIMEOUT_256MS (WDT_PRESCALER_32) // (256 ± 25.6) ms +#define WDT_TIMEOUT_512MS (WDT_PRESCALER_64) // (512 ± 51.2) ms +#define WDT_TIMEOUT_1S (WDT_PRESCALER_128) // (1024 ± 102.4) ms +#define WDT_TIMEOUT_2S (WDT_PRESCALER_256) // (2048 ± 204.8) ms +#define WDT_TIMEOUT_4S (WDT_PRESCALER_512) // (4096 ± 409.6) ms +#define WDT_TIMEOUT_8S (WDT_PRESCALER_1024) // (8192 ± 819.2) ms /* Выбор по предделителю */ -#define WDT_PRESCALER_2 0x00 // (16 ± 1.6) ms -#define WDT_PRESCALER_4 0x01 // (32 ± 3.2) ms -#define WDT_PRESCALER_8 0x02 // (64 ± 6.4) ms -#define WDT_PRESCALER_16 0x03 // (128 ± 12.8) ms -#define WDT_PRESCALER_32 0x04 // (256 ± 25.6) ms -#define WDT_PRESCALER_64 0x05 // (512 ± 51.2) ms -#define WDT_PRESCALER_128 0x06 // (1024 ± 102.4) ms -#define WDT_PRESCALER_256 0x07 // (2048 ± 204.8) ms -#define WDT_PRESCALER_512 0x08 // (4096 ± 409.6) ms -#define WDT_PRESCALER_1024 0x09 // (8192 ± 819.2) ms - +#define WDT_PRESCALER_2 0x00 // (16 ± 1.6) ms +#define WDT_PRESCALER_4 0x01 // (32 ± 3.2) ms +#define WDT_PRESCALER_8 0x02 // (64 ± 6.4) ms +#define WDT_PRESCALER_16 0x03 // (128 ± 12.8) ms +#define WDT_PRESCALER_32 0x04 // (256 ± 25.6) ms +#define WDT_PRESCALER_64 0x05 // (512 ± 51.2) ms +#define WDT_PRESCALER_128 0x06 // (1024 ± 102.4) ms +#define WDT_PRESCALER_256 0x07 // (2048 ± 204.8) ms +#define WDT_PRESCALER_512 0x08 // (4096 ± 409.6) ms +#define WDT_PRESCALER_1024 0x09 // (8192 ± 819.2) ms /***************** -* Класс watchdog * -*****************/ + * Класс watchdog * + *****************/ /* Проверка совместимости выбранного МК с библиотекой */ -#if not ( \ -defined (__AVR_ATmega48P__) || \ -defined (__AVR_ATmega88P__) || \ -defined (__AVR_ATmega168P__) || \ -defined (__AVR_ATmega328P__) || \ -defined (__AVR_ATmega32u4__) || \ -defined (__AVR_ATmega1280__) || \ -defined (__AVR_ATmega2560__) || \ -defined (__AVR_ATtiny87__) || \ -defined (__AVR_ATtiny167__) || \ -defined (__AVR_ATtiny44__) || \ -defined (__AVR_ATtiny84__) || \ -defined (__AVR_ATtiny45__) || \ -defined (__AVR_ATtiny85__) || \ -defined (__AVR_ATtiny13__)) -#error "This MCU is not supported in GyverWDT.h library" +#if not( \ + defined(__AVR_ATmega48P__) || \ + defined(__AVR_ATmega88P__) || \ + defined(__AVR_ATmega168P__) || \ + defined(__AVR_ATmega328P__) || \ + defined(__AVR_ATmega32u4__) || \ + defined(__AVR_ATmega1280__) || \ + defined(__AVR_ATmega2560__) || \ + defined(__AVR_ATtiny87__) || \ + defined(__AVR_ATtiny167__) || \ + defined(__AVR_ATtiny44__) || \ + defined(__AVR_ATtiny84__) || \ + defined(__AVR_ATtiny45__) || \ + defined(__AVR_ATtiny85__) || \ + defined(__AVR_ATtiny13__)) +#error "This MCU is not supported in GyverWDT.h library" #endif #if defined(WDTCSR) -# define _WD_CONTROL_REG WDTCSR +#define _WD_CONTROL_REG WDTCSR #elif defined(WDTCR) -# define _WD_CONTROL_REG WDTCR +#define _WD_CONTROL_REG WDTCR #else -# define _WD_CONTROL_REG WDT +#define _WD_CONTROL_REG WDT #endif class GyverWDT { - public: - - void reset() { // Сбросить watchdog таймер - asm volatile ("WDR"); // ASM команда 'watchdog reset' + public: + void reset() { // Сбросить watchdog таймер + asm volatile("WDR"); // ASM команда 'watchdog reset' } /* Watchdog.reset(); @@ -128,13 +125,12 @@ class GyverWDT { Можно размещать по своему усмотрению */ - - void disable() { // Сбросить watchdog таймер - uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) - noInterrupts(); // Запрещаем глобальные прерывания - WDTCSR = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК - WDTCSR = 0x00; // Очищаем все настройки watchdog - SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого + void disable() { // Сбросить watchdog таймер + uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) + noInterrupts(); // Запрещаем глобальные прерывания + _WD_CONTROL_REG = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК + _WD_CONTROL_REG = 0x00; // Очищаем все настройки watchdog + SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого } /* Watchdog.disable(); @@ -144,14 +140,13 @@ class GyverWDT { Можно использовать перед выполнением долгих атомарных операций */ - - void enable(uint8_t mode, uint8_t prescaler) { // Настроить и запустить watchdog таймер - uint8_t _WDT_REG = mode | ((prescaler > 7) ? ((1 << WDP3) | (prescaler - 8)) : prescaler); // Cоставляем содержимое регистра WDT - uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) - noInterrupts(); // Запрещаем глобальные прерывания - WDTCSR = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК - WDTCSR = _WDT_REG; // Сразу же загружаем готовые настройки watchdog - SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого + void enable(uint8_t mode, uint8_t prescaler) { // Настроить и запустить watchdog таймер + uint8_t _WDT_REG = mode | ((prescaler > 7) ? ((1 << WDP3) | (prescaler - 8)) : prescaler); // Cоставляем содержимое регистра WDT + uint8_t _SREG_COPY = SREG; // Сохраняем SREG (и настройки глобальных прерываний) + noInterrupts(); // Запрещаем глобальные прерывания + _WD_CONTROL_REG = ((1 << WDCE) | (1 << WDE)); // Разблокировка доступа к watchdog, см. документацию на МК + _WD_CONTROL_REG = _WDT_REG; // Сразу же загружаем готовые настройки watchdog + SREG = _SREG_COPY; // Возвращаем SREG и прерывания, если они были включены до этого } /* Watchdog.enable(mode, prescaler); @@ -173,12 +168,12 @@ class GyverWDT { Примеры использования: ЕСЛИ не вызывать Watchdog.reset(); - Watchdog.enable(RST_MODE, WDT_PRESCALER_128); - Сбросить МК через ~1с, + Watchdog.enable(RST_MODE, WDT_PRESCALER_128); - Сбросить МК через ~1с, Watchdog.enable(ISR_MODE, WDT_PRESCALER_2); - Вызывать прерывание ISR(WATCHDOG){} каждую секунду - Watchdog.enable(ISR_RST_MODE, WDT_PRESCALER_1024); - Вызвать прерывание ISR(WATCHDOG){} через ~8с, переключиться в режим RST_MODE + Watchdog.enable(ISR_RST_MODE, WDT_PRESCALER_1024); - Вызвать прерывание ISR(WATCHDOG){} через ~8с, переключиться в режим RST_MODE */ - private: + private: }; extern GyverWDT Watchdog;