From 3fa55b8fa23d5263cf99a3666f6a1051a2bf71c4 Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Sat, 11 Oct 2025 12:53:52 +0300 Subject: [PATCH] fix: isr handler wrong interrupt processing --- version.txt | 2 +- zh_avr_pcf8574.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/version.txt b/version.txt index 6261a05..d5e98f7 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.1 \ No newline at end of file +1.3.2 \ No newline at end of file diff --git a/zh_avr_pcf8574.c b/zh_avr_pcf8574.c index b0c29f9..5c9c47c 100644 --- a/zh_avr_pcf8574.c +++ b/zh_avr_pcf8574.c @@ -5,6 +5,7 @@ static uint8_t _interrupt_gpio = 0xFF; static uint8_t _interrupt_port = 0; static SemaphoreHandle_t _interrupt_semaphore = NULL; static const uint8_t _gpio_matrix[8] PROGMEM = {AVR_BIT0, AVR_BIT1, AVR_BIT2, AVR_BIT3, AVR_BIT4, AVR_BIT5, AVR_BIT6, AVR_BIT7}; +volatile static bool _interrupt_on = false; static zh_avr_vector_t _vector = {0}; @@ -161,21 +162,60 @@ BaseType_t zh_avr_pcf8574_isr_handler(void) switch (_interrupt_port) { case AVR_PORTB: + if ((PINB & (1 << _interrupt_gpio)) == (1 << _interrupt_gpio)) + { + if (_interrupt_on == false) + { + _interrupt_on = true; + } + break; + } if ((PINB & (1 << _interrupt_gpio)) == 0) { - xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + if (_interrupt_on == true) + { + _interrupt_on = false; + xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + } + break; } break; case AVR_PORTC: + if ((PINC & (1 << _interrupt_gpio)) == (1 << _interrupt_gpio)) + { + if (_interrupt_on == false) + { + _interrupt_on = true; + } + break; + } if ((PINC & (1 << _interrupt_gpio)) == 0) { - xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + if (_interrupt_on == true) + { + _interrupt_on = false; + xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + } + break; } break; case AVR_PORTD: + if ((PIND & (1 << _interrupt_gpio)) == (1 << _interrupt_gpio)) + { + if (_interrupt_on == false) + { + _interrupt_on = true; + } + break; + } if ((PIND & (1 << _interrupt_gpio)) == 0) { - xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + if (_interrupt_on == true) + { + _interrupt_on = false; + xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken); + } + break; } break; default: