Compare commits
	
		
			5 Commits
		
	
	
		
			v1.0.0
			...
			e6eb45dd9b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e6eb45dd9b | |||
| 6b8b8c3314 | |||
| 196398ac6f | |||
| dfebb15213 | |||
| 8c6460a1d1 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.DS_Store
 | 
				
			||||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							@@ -9,7 +9,7 @@
 | 
				
			|||||||
## Note
 | 
					## Note
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Enable interrupt support only if input GPIO's are used.
 | 
					1. Enable interrupt support only if input GPIO's are used.
 | 
				
			||||||
2. All the INT GPIO's on the extenders must be connected to the one GPIO on AVR. Only PORTD4 - PORTD7 are acceptable!
 | 
					2. All the INT GPIO's on the extenders must be connected to the one GPIO on AVR.
 | 
				
			||||||
3. The input GPIO's are always pullup to the power supply.
 | 
					3. The input GPIO's are always pullup to the power supply.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Dependencies
 | 
					## Dependencies
 | 
				
			||||||
@@ -79,6 +79,7 @@ void pcf8574_example_task(void *pvParameters)
 | 
				
			|||||||
    zh_avr_pcf8574_init_config_t pcf8574_init_config = ZH_AVR_PCF8574_INIT_CONFIG_DEFAULT();
 | 
					    zh_avr_pcf8574_init_config_t pcf8574_init_config = ZH_AVR_PCF8574_INIT_CONFIG_DEFAULT();
 | 
				
			||||||
    pcf8574_init_config.i2c_address = 0x38;
 | 
					    pcf8574_init_config.i2c_address = 0x38;
 | 
				
			||||||
    pcf8574_init_config.p0_gpio_work_mode = true;   // Required only for input GPIO.
 | 
					    pcf8574_init_config.p0_gpio_work_mode = true;   // Required only for input GPIO.
 | 
				
			||||||
 | 
					    pcf8574_init_config.interrupt_port = AVR_PORTD; // Required only if used input GPIO interrupts.
 | 
				
			||||||
    pcf8574_init_config.interrupt_gpio = PORTD4;    // Required only if used input GPIO interrupts.
 | 
					    pcf8574_init_config.interrupt_gpio = PORTD4;    // Required only if used input GPIO interrupts.
 | 
				
			||||||
    zh_avr_pcf8574_init(&pcf8574_init_config, &pcf8574_handle);
 | 
					    zh_avr_pcf8574_init(&pcf8574_init_config, &pcf8574_handle);
 | 
				
			||||||
    uint8_t reg = 0;
 | 
					    uint8_t reg = 0;
 | 
				
			||||||
@@ -118,14 +119,19 @@ int main(void)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void zh_avr_pcf8574_event_handler(zh_avr_pcf8574_event_on_isr_t *event) // Required only if used input GPIO interrupts.
 | 
					void zh_avr_pcf8574_event_handler(zh_avr_pcf8574_event_on_isr_t *event) // Do not delete! Leave blank if interrupts are not used.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    printf("Interrupt happened on device address 0x%02X on GPIO number %d at level %d.\n", event->i2c_address, event->gpio_number, event->gpio_level);
 | 
					    printf("Interrupt happened on device address 0x%02X on GPIO number %d at level %d.\n", event->i2c_address, event->gpio_number, event->gpio_level);
 | 
				
			||||||
    printf("Interrupt Task Remaining Stack Size %d.\n", uxTaskGetStackHighWaterMark(NULL));
 | 
					    printf("Interrupt Task Remaining Stack Size %d.\n", uxTaskGetStackHighWaterMark(NULL));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ISR(PCINT2_vect) // Required only if used input GPIO interrupts.
 | 
					// ISR(PCINT0_vect) // For AVR_PORTB. Required only if used input GPIO interrupts.
 | 
				
			||||||
 | 
					// ISR(PCINT1_vect) // For AVR_PORTC. Required only if used input GPIO interrupts.
 | 
				
			||||||
 | 
					ISR(PCINT2_vect) // For AVR_PORTD. Required only if used input GPIO interrupts.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    zh_avr_pcf8574_isr_handler();
 | 
					    if (zh_avr_pcf8574_isr_handler() == pdTRUE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        portYIELD();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "FreeRTOS.h"
 | 
					#include "FreeRTOS.h"
 | 
				
			||||||
#include "semphr.h"
 | 
					#include "semphr.h"
 | 
				
			||||||
 | 
					#include "avr/pgmspace.h"
 | 
				
			||||||
#include "zh_avr_i2c.h"
 | 
					#include "zh_avr_i2c.h"
 | 
				
			||||||
#include "zh_avr_vector.h"
 | 
					#include "zh_avr_vector.h"
 | 
				
			||||||
#include "avr_err.h"
 | 
					#include "avr_err.h"
 | 
				
			||||||
 | 
					#include "avr_port.h"
 | 
				
			||||||
#include "avr_bit_defs.h"
 | 
					#include "avr_bit_defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ZH_AVR_PCF8574_INIT_CONFIG_DEFAULT()   \
 | 
					#define ZH_AVR_PCF8574_INIT_CONFIG_DEFAULT()   \
 | 
				
			||||||
@@ -20,7 +22,8 @@
 | 
				
			|||||||
        .p5_gpio_work_mode = 0,                \
 | 
					        .p5_gpio_work_mode = 0,                \
 | 
				
			||||||
        .p6_gpio_work_mode = 0,                \
 | 
					        .p6_gpio_work_mode = 0,                \
 | 
				
			||||||
        .p7_gpio_work_mode = 0,                \
 | 
					        .p7_gpio_work_mode = 0,                \
 | 
				
			||||||
        .interrupt_gpio = 0xFF}
 | 
					        .interrupt_gpio = 0xFF,                \
 | 
				
			||||||
 | 
					        .interrupt_port = 0}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C"
 | 
					extern "C"
 | 
				
			||||||
@@ -41,6 +44,7 @@ extern "C"
 | 
				
			|||||||
        bool p6_gpio_work_mode; // Expander GPIO P6 work mode. True for input, false for output.
 | 
					        bool p6_gpio_work_mode; // Expander GPIO P6 work mode. True for input, false for output.
 | 
				
			||||||
        bool p7_gpio_work_mode; // Expander GPIO P7 work mode. True for input, false for output.
 | 
					        bool p7_gpio_work_mode; // Expander GPIO P7 work mode. True for input, false for output.
 | 
				
			||||||
        uint8_t interrupt_gpio; // Interrupt GPIO. @attention Must be same for all PCF8574 expanders.
 | 
					        uint8_t interrupt_gpio; // Interrupt GPIO. @attention Must be same for all PCF8574 expanders.
 | 
				
			||||||
 | 
					        uint8_t interrupt_port; // Interrupt port.
 | 
				
			||||||
    } zh_avr_pcf8574_init_config_t;
 | 
					    } zh_avr_pcf8574_init_config_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    typedef struct // PCF8574 expander handle.
 | 
					    typedef struct // PCF8574 expander handle.
 | 
				
			||||||
@@ -133,7 +137,7 @@ extern "C"
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @brief PCF8574 ISR handler.
 | 
					     * @brief PCF8574 ISR handler.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    void zh_avr_pcf8574_isr_handler(void);
 | 
					    BaseType_t zh_avr_pcf8574_isr_handler(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
1.0.0
 | 
					1.3.0
 | 
				
			||||||
@@ -1,8 +1,10 @@
 | 
				
			|||||||
#include "zh_avr_pcf8574.h"
 | 
					#include "zh_avr_pcf8574.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TaskHandle_t zh_avr_pcf8574 = NULL;
 | 
				
			||||||
static uint8_t _interrupt_gpio = 0xFF;
 | 
					static uint8_t _interrupt_gpio = 0xFF;
 | 
				
			||||||
 | 
					static uint8_t _interrupt_port = 0;
 | 
				
			||||||
static SemaphoreHandle_t _interrupt_semaphore = NULL;
 | 
					static SemaphoreHandle_t _interrupt_semaphore = NULL;
 | 
				
			||||||
static uint8_t _gpio_matrix[8] = {AVR_BIT0, AVR_BIT1, AVR_BIT2, AVR_BIT3, AVR_BIT4, AVR_BIT5, AVR_BIT6, AVR_BIT7};
 | 
					static const uint8_t _gpio_matrix[8] PROGMEM = {AVR_BIT0, AVR_BIT1, AVR_BIT2, AVR_BIT3, AVR_BIT4, AVR_BIT5, AVR_BIT6, AVR_BIT7};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static zh_avr_vector_t _vector = {0};
 | 
					static zh_avr_vector_t _vector = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,7 +60,7 @@ avr_err_t zh_avr_pcf8574_reset(zh_avr_pcf8574_handle_t *handle)
 | 
				
			|||||||
avr_err_t zh_avr_pcf8574_read_gpio(zh_avr_pcf8574_handle_t *handle, uint8_t gpio, bool *status)
 | 
					avr_err_t zh_avr_pcf8574_read_gpio(zh_avr_pcf8574_handle_t *handle, uint8_t gpio, bool *status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ZH_ERROR_CHECK(gpio <= 7, AVR_FAIL);
 | 
					    ZH_ERROR_CHECK(gpio <= 7, AVR_FAIL);
 | 
				
			||||||
    uint8_t gpio_temp = _gpio_matrix[gpio];
 | 
					    uint8_t gpio_temp = pgm_read_byte(&_gpio_matrix[gpio]);
 | 
				
			||||||
    uint8_t reg_temp = 0;
 | 
					    uint8_t reg_temp = 0;
 | 
				
			||||||
    avr_err_t err = _zh_avr_pcf8574_read_register(handle, ®_temp);
 | 
					    avr_err_t err = _zh_avr_pcf8574_read_register(handle, ®_temp);
 | 
				
			||||||
    *status = ((reg_temp & gpio_temp) ? 1 : 0);
 | 
					    *status = ((reg_temp & gpio_temp) ? 1 : 0);
 | 
				
			||||||
@@ -68,7 +70,7 @@ avr_err_t zh_avr_pcf8574_read_gpio(zh_avr_pcf8574_handle_t *handle, uint8_t gpio
 | 
				
			|||||||
avr_err_t zh_avr_pcf8574_write_gpio(zh_avr_pcf8574_handle_t *handle, uint8_t gpio, bool status)
 | 
					avr_err_t zh_avr_pcf8574_write_gpio(zh_avr_pcf8574_handle_t *handle, uint8_t gpio, bool status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ZH_ERROR_CHECK(gpio <= 7, AVR_FAIL);
 | 
					    ZH_ERROR_CHECK(gpio <= 7, AVR_FAIL);
 | 
				
			||||||
    uint8_t gpio_temp = _gpio_matrix[gpio];
 | 
					    uint8_t gpio_temp = pgm_read_byte(&_gpio_matrix[gpio]);
 | 
				
			||||||
    if (status == true)
 | 
					    if (status == true)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _zh_avr_pcf8574_write_register(handle, handle->gpio_status | handle->gpio_work_mode | gpio_temp);
 | 
					        return _zh_avr_pcf8574_write_register(handle, handle->gpio_status | handle->gpio_work_mode | gpio_temp);
 | 
				
			||||||
@@ -81,7 +83,12 @@ static avr_err_t _zh_avr_pcf8574_validate_config(const zh_avr_pcf8574_init_confi
 | 
				
			|||||||
    ZH_ERROR_CHECK(config != NULL, AVR_ERR_INVALID_ARG);
 | 
					    ZH_ERROR_CHECK(config != NULL, AVR_ERR_INVALID_ARG);
 | 
				
			||||||
    ZH_ERROR_CHECK((config->i2c_address >= 0x20 && config->i2c_address <= 0x27) || (config->i2c_address >= 0x38 && config->i2c_address <= 0x3F), AVR_ERR_INVALID_ARG);
 | 
					    ZH_ERROR_CHECK((config->i2c_address >= 0x20 && config->i2c_address <= 0x27) || (config->i2c_address >= 0x38 && config->i2c_address <= 0x3F), AVR_ERR_INVALID_ARG);
 | 
				
			||||||
    ZH_ERROR_CHECK(config->task_priority > tskIDLE_PRIORITY && config->stack_size >= 124, AVR_ERR_INVALID_ARG);
 | 
					    ZH_ERROR_CHECK(config->task_priority > tskIDLE_PRIORITY && config->stack_size >= 124, AVR_ERR_INVALID_ARG);
 | 
				
			||||||
    ZH_ERROR_CHECK(config->interrupt_gpio == 0xFF || config->interrupt_gpio == PORTD4 || config->interrupt_gpio == PORTD5 || config->interrupt_gpio == PORTD6 || config->interrupt_gpio == PORTD7, AVR_ERR_INVALID_ARG);
 | 
					    ZH_ERROR_CHECK(config->interrupt_gpio == 0xFF || (config->interrupt_gpio >= 0 && config->interrupt_gpio <= 7), AVR_ERR_INVALID_ARG);
 | 
				
			||||||
 | 
					    if (config->interrupt_gpio != 0xFF)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ZH_ERROR_CHECK(config->interrupt_port >= AVR_PORTB && config->interrupt_port <= AVR_PORTD, AVR_ERR_INVALID_ARG);
 | 
				
			||||||
 | 
					        _interrupt_port = config->interrupt_port;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return AVR_OK;
 | 
					    return AVR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -114,13 +121,32 @@ static avr_err_t _zh_avr_pcf8574_configure_interrupts(const zh_avr_pcf8574_init_
 | 
				
			|||||||
    ZH_ERROR_CHECK(err == AVR_OK, err);
 | 
					    ZH_ERROR_CHECK(err == AVR_OK, err);
 | 
				
			||||||
    err = zh_avr_vector_push_back(&_vector, &handle);
 | 
					    err = zh_avr_vector_push_back(&_vector, &handle);
 | 
				
			||||||
    ZH_ERROR_CHECK(err == AVR_OK, err);
 | 
					    ZH_ERROR_CHECK(err == AVR_OK, err);
 | 
				
			||||||
 | 
					    switch (_interrupt_port)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case AVR_PORTB:
 | 
				
			||||||
 | 
					        DDRB &= ~(1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        PORTB |= (1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        PCICR |= (1 << PCIE0);
 | 
				
			||||||
 | 
					        PCMSK0 |= (1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case AVR_PORTC:
 | 
				
			||||||
 | 
					        DDRC &= ~(1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        PORTC |= (1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        PCICR |= (1 << PCIE1);
 | 
				
			||||||
 | 
					        PCMSK1 |= (1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case AVR_PORTD:
 | 
				
			||||||
        DDRD &= ~(1 << _interrupt_gpio);
 | 
					        DDRD &= ~(1 << _interrupt_gpio);
 | 
				
			||||||
        PORTD |= (1 << _interrupt_gpio);
 | 
					        PORTD |= (1 << _interrupt_gpio);
 | 
				
			||||||
        PCICR |= (1 << PCIE2);
 | 
					        PCICR |= (1 << PCIE2);
 | 
				
			||||||
        PCMSK2 |= (1 << _interrupt_gpio);
 | 
					        PCMSK2 |= (1 << _interrupt_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    _interrupt_semaphore = xSemaphoreCreateBinary();
 | 
					    _interrupt_semaphore = xSemaphoreCreateBinary();
 | 
				
			||||||
    ZH_ERROR_CHECK(_interrupt_semaphore != NULL, AVR_ERR_NO_MEM);
 | 
					    ZH_ERROR_CHECK(_interrupt_semaphore != NULL, AVR_ERR_NO_MEM);
 | 
				
			||||||
    BaseType_t x_err = xTaskCreate(_zh_avr_pcf8574_isr_processing_task, NULL, config->stack_size, NULL, config->task_priority, NULL);
 | 
					    BaseType_t x_err = xTaskCreate(_zh_avr_pcf8574_isr_processing_task, "zh_avr_pcf8574", config->stack_size, NULL, config->task_priority, &zh_avr_pcf8574);
 | 
				
			||||||
    if (x_err != pdPASS)
 | 
					    if (x_err != pdPASS)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        vSemaphoreDelete(_interrupt_semaphore);
 | 
					        vSemaphoreDelete(_interrupt_semaphore);
 | 
				
			||||||
@@ -129,17 +155,33 @@ static avr_err_t _zh_avr_pcf8574_configure_interrupts(const zh_avr_pcf8574_init_
 | 
				
			|||||||
    return AVR_OK;
 | 
					    return AVR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void zh_avr_pcf8574_isr_handler(void)
 | 
					BaseType_t zh_avr_pcf8574_isr_handler(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 | 
				
			||||||
 | 
					    switch (_interrupt_port)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case AVR_PORTB:
 | 
				
			||||||
 | 
					        if ((PINB & (1 << _interrupt_gpio)) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case AVR_PORTC:
 | 
				
			||||||
 | 
					        if ((PINC & (1 << _interrupt_gpio)) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case AVR_PORTD:
 | 
				
			||||||
        if ((PIND & (1 << _interrupt_gpio)) == 0)
 | 
					        if ((PIND & (1 << _interrupt_gpio)) == 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 | 
					 | 
				
			||||||
            xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken);
 | 
					            xSemaphoreGiveFromISR(_interrupt_semaphore, &xHigherPriorityTaskWoken);
 | 
				
			||||||
        if (xHigherPriorityTaskWoken == pdTRUE)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            portYIELD();
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return xHigherPriorityTaskWoken;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void _zh_avr_pcf8574_isr_processing_task(void *pvParameter)
 | 
					static void _zh_avr_pcf8574_isr_processing_task(void *pvParameter)
 | 
				
			||||||
@@ -166,12 +208,12 @@ static void _zh_avr_pcf8574_isr_processing_task(void *pvParameter)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            for (uint8_t j = 0; j <= 7; ++j)
 | 
					            for (uint8_t j = 0; j <= 7; ++j)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if ((handle->gpio_work_mode & _gpio_matrix[j]) != 0)
 | 
					                if ((handle->gpio_work_mode & pgm_read_byte(&_gpio_matrix[j])) != 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if ((old_reg & _gpio_matrix[j]) != (new_reg & _gpio_matrix[j]))
 | 
					                    if ((old_reg & pgm_read_byte(&_gpio_matrix[j])) != (new_reg & pgm_read_byte(&_gpio_matrix[j])))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        event.gpio_number = j;
 | 
					                        event.gpio_number = j;
 | 
				
			||||||
                        event.gpio_level = new_reg & _gpio_matrix[j];
 | 
					                        event.gpio_level = new_reg & pgm_read_byte(&_gpio_matrix[j]);
 | 
				
			||||||
                        extern void zh_avr_pcf8574_event_handler(zh_avr_pcf8574_event_on_isr_t * event);
 | 
					                        extern void zh_avr_pcf8574_event_handler(zh_avr_pcf8574_event_on_isr_t * event);
 | 
				
			||||||
                        zh_avr_pcf8574_event_handler(&event);
 | 
					                        zh_avr_pcf8574_event_handler(&event);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user