diff --git a/driver_axp209.c b/driver_axp209.c index ef96592..82dc484 100755 --- a/driver_axp209.c +++ b/driver_axp209.c @@ -40,14 +40,18 @@ static char i2c0_sysfs_filename[] = "/dev/i2c-0"; * Public functions ****************************************************************/ bool axp209_init(void) { + int err; + + /* Open i2c file interface */ if ((fd_axp209 = open(i2c0_sysfs_filename,O_RDWR)) < 0) { printf("In axp209_init - Failed to open the I2C bus %s", i2c0_sysfs_filename); // ERROR HANDLING; you can check errno to see what went wrong return false; } + /* Acquire AXP209 bus */ if (ioctl(fd_axp209, I2C_SLAVE, AXP209_I2C_ADDR) < 0) { - printf("In axp209_init - Failed to acquire bus access and/or talk to slave.\n"); + printf("In axp209_init - Failed to acquire bus access and/or talk to slave, trying to force it\n"); // ERROR HANDLING; you can check errno to see what went wrong if (ioctl(fd_axp209, I2C_SLAVE_FORCE, AXP209_I2C_ADDR) < 0) { printf("In axp209_init - Failed to acquire FORCED bus access and/or talk to slave.\n"); @@ -56,8 +60,13 @@ bool axp209_init(void) { } } - // Enable only chosen interrupts (PEK short and long presses) - int err; + /* Set N_OE Shutdown delay to 3S*/ + err = i2c_smbus_write_byte_data(fd_axp209 , AXP209_REG_32H, 0x43); + if(err < 0){ + printf("ERROR Setting AXP209 N_OE Shutdown delay to 3S\n"); + } + + /* Enable only chosen interrupts (PEK short and long presses)*/ /*err = i2c_smbus_write_byte_data(fd_axp209 , AXP209_INTERRUPT_BANK_1_ENABLE, 0x00); if(err < 0){ printf("ERROR initializing interrupts 1 for AXP209\n"); diff --git a/driver_axp209.h b/driver_axp209.h index 02a341f..8f4375a 100755 --- a/driver_axp209.h +++ b/driver_axp209.h @@ -14,6 +14,7 @@ #define AXP209_I2C_ADDR 0x34 // Chip registers adresses +#define AXP209_REG_32H 0x32 #define AXP209_INTERRUPT_BANK_1_ENABLE 0x40 #define AXP209_INTERRUPT_BANK_1_STATUS 0x48 #define AXP209_INTERRUPT_BANK_2_ENABLE 0x41 diff --git a/funkey_gpio_management.c b/funkey_gpio_management.c index 6651ef5..b3e40b0 100755 --- a/funkey_gpio_management.c +++ b/funkey_gpio_management.c @@ -45,7 +45,8 @@ int main(int argc, char **argv, char **envp) // Variables STRUCT_MAPPED_GPIO * chained_list_mapping = NULL; int nb_valid_gpios = 0; - int * gpio_pins = NULL; + int * gpio_pins_idx_declared = NULL; + bool * gpios_pins_active_high = NULL; // Set the signal callback for Ctrl-C signal(SIGINT, signal_handler); @@ -54,10 +55,10 @@ int main(int argc, char **argv, char **envp) init_uinput(); // Read Conf File: Get GPIO pins to declare and all valid pin mappings - get_mapping_from_conf_file(&chained_list_mapping, &nb_valid_gpios, &gpio_pins); + get_mapping_from_conf_file(&chained_list_mapping, &nb_valid_gpios, &gpio_pins_idx_declared, &gpios_pins_active_high); // Init GPIOs - init_mapping_gpios(gpio_pins, nb_valid_gpios, chained_list_mapping); + init_mapping_gpios(gpio_pins_idx_declared, gpios_pins_active_high, nb_valid_gpios, chained_list_mapping); // Main Loop while (keepgoing) { diff --git a/funkey_gpio_mapping.conf b/funkey_gpio_mapping.conf index a7c62c8..9b3e094 100755 --- a/funkey_gpio_mapping.conf +++ b/funkey_gpio_mapping.conf @@ -4,7 +4,8 @@ # Format: # # - First all GPIO Pin numbers must be declared (integers separated by commas) -# Example: 0,1,2,3,4,6,7,11,12,13,14,15 +# By default, pins are declared active high, to declare them active low, add char '*' +# Example: 0,1,2,3,4,6,7,10*,11,12,13,14,15 # # - Then the mapping can be done as follows (one line per mapping): # Pin_number[+Pin_number...], type_mapping, value, str_help_name_pin, str_help_fct_pin @@ -22,7 +23,7 @@ ################################### # Pins declaration: -0,1,2,3,4,6,7,10,11,12,13,14,15 +0,1,2,3,4,6,7,10*,11,12,13,14,15 ################################### @@ -50,7 +51,8 @@ 7+13, KEYBOARD, KEY_W, KEY_W, Brightness-- 11, KEYBOARD, KEY_Y, KEY_Y, Y 7+11, KEYBOARD, KEY_C, KEY_C, Volume++ -10, SHELL_COMMAND, poweroff, N_OE, Poweroff because N_OE_received +#10, SHELL_COMMAND, poweroff, N_OE, Poweroff because N_OE_received +10, KEYBOARD, KEY_T, KEY_T, Should Poweroff because N_OE_received # Bypass to remove when button axp working: #7+15, KEYBOARD, KEY_Q, 7+11, Launch menu diff --git a/gpio_mapping.c b/gpio_mapping.c index c654da0..44bb535 100755 --- a/gpio_mapping.c +++ b/gpio_mapping.c @@ -23,6 +23,7 @@ } while(0) #define DEBUG_GPIO_PRINTF (0) +#define DEBUG_PERIODIC_CHECK_PRINTF (0) #define ERROR_GPIO_PRINTF (1) #if (DEBUG_GPIO_PRINTF) @@ -31,6 +32,12 @@ #define GPIO_PRINTF(...) #endif +#if (DEBUG_PERIODIC_CHECK_PRINTF) +#define PERIODIC_CHECK_PRINTF(...) printf(__VA_ARGS__); +#else +#define PERIODIC_CHECK_PRINTF(...) +#endif + #if (ERROR_GPIO_PRINTF) #define GPIO_ERROR_PRINTF(...) printf(__VA_ARGS__); #else @@ -53,7 +60,8 @@ * Static variables ****************************************************************/ static int nb_mapped_gpios; -static int * gpio_pins; +static int * gpio_pins_idx_declared; +static bool * gpios_pins_active_high; STRUCT_MAPPED_GPIO * chained_list_mapping; static int max_fd = 0; static int gpio_fd_interrupt_expander_gpio; @@ -62,8 +70,6 @@ static fd_set fds; static bool * mask_gpio_value; static bool interrupt_i2c_expander_found = false; static bool interrupt_axp209_found = false; -static bool mapping_PEK_short_press_activated = false; -static bool mapping_PEK_long_press_activated = false; /**************************************************************** @@ -136,7 +142,7 @@ static void find_and_call_mapping_function(int idx_gpio_interrupted, //GPIO_PRINTF(" Mapping searching for idx_gpio_interrupted: %d, and %s: \n", idx_gpio_interrupted, activation?"activation":"deactivation") for (i=0; i < current->nb_simultaneous_pins; i++){ - //GPIO_PRINTF(" Pin in mapping: %d, pin_idx=%d\n", gpio_pins[current->pins_idx[i]], current->pins_idx[i]); + //GPIO_PRINTF(" Pin in mapping: %d, pin_idx=%d\n", gpio_pins_idx_declared[current->pins_idx[i]], current->pins_idx[i]); // Find if current mapping contains interrupted pin if (current->pins_idx[i] == idx_gpio_interrupted){ gpio_found_pin_in_mapping = true; @@ -156,7 +162,7 @@ static void find_and_call_mapping_function(int idx_gpio_interrupted, // if real mapping already found => need to deactivate previously activated ones if(mapping_found && current->activated){ GPIO_PRINTF(" Mapping Deactivation because real one already found: GPIO %d found in following activated mapping: \n", - gpio_pins[idx_gpio_interrupted]); + gpio_pins_idx_declared[idx_gpio_interrupted]); print_chained_list_node(current); apply_mapping_desactivation(current); } @@ -167,7 +173,7 @@ static void find_and_call_mapping_function(int idx_gpio_interrupted, } // Print information and activate mapping GPIO_PRINTF(" Mapping Activation: GPIO %d found in following deactivated mapping: \n", - gpio_pins[idx_gpio_interrupted]); + gpio_pins_idx_declared[idx_gpio_interrupted]); print_chained_list_node(current); apply_mapping_activation(current); } @@ -175,7 +181,7 @@ static void find_and_call_mapping_function(int idx_gpio_interrupted, else{ // Treating deactivation cases if(current->activated){ GPIO_PRINTF(" Mapping Desactivation: GPIO %d found in following activated mapping: \n", - gpio_pins[idx_gpio_interrupted]); + gpio_pins_idx_declared[idx_gpio_interrupted]); print_chained_list_node(current); apply_mapping_desactivation(current); } @@ -229,7 +235,9 @@ static int deinit_gpio_interrupt(int fd_saved) * Public functions ****************************************************************/ /***** Init I2C expander pin mappings *****/ -int init_mapping_gpios(int * gpio_pins_to_declare, int nb_gpios_to_declare, +int init_mapping_gpios(int * gpio_pins_to_declare, + bool * gpios_pins_active_high_declared, + int nb_gpios_to_declare, STRUCT_MAPPED_GPIO * chained_list_mapping_gpios) { // Variables @@ -238,7 +246,8 @@ int init_mapping_gpios(int * gpio_pins_to_declare, int nb_gpios_to_declare, // Store arguments nb_mapped_gpios = nb_gpios_to_declare; - gpio_pins = gpio_pins_to_declare; + gpio_pins_idx_declared = gpio_pins_to_declare; + gpios_pins_active_high = gpios_pins_active_high_declared; chained_list_mapping = chained_list_mapping_gpios; // Init values @@ -308,6 +317,7 @@ int listen_gpios_interrupts(void) int nb_interrupts = 0; bool previous_mask_gpio_value[nb_mapped_gpios]; bool mask_gpio_current_interrupts[nb_mapped_gpios]; + bool forced_interrupt = false; // Back up master fd_set dup = fds; @@ -331,11 +341,12 @@ int listen_gpios_interrupts(void) #endif //TIMEOUT_SEC_SANITY_CHECK_GPIO_EXP if(!nb_interrupts){ // Timeout case - GPIO_PRINTF(" Timeout, forcing sanity check\n"); + PERIODIC_CHECK_PRINTF(" Timeout, forcing sanity check\n"); // Timeout forcing a "Found interrupt" event for sanity check interrupt_i2c_expander_found = true; interrupt_axp209_found = true; + forced_interrupt = true; } else if ( nb_interrupts < 0) { perror("select"); @@ -378,7 +389,12 @@ int listen_gpios_interrupts(void) #ifdef ENABLE_AXP209_INTERRUPTS if(interrupt_axp209_found){ - GPIO_PRINTF(" Processing interrupt AXP209\n"); + if(forced_interrupt){ + PERIODIC_CHECK_PRINTF(" Processing forced interrupt AXP209\n"); + } + else{ + GPIO_PRINTF(" Processing real interrupt AXP209\n"); + } int val_int_bank_3 = axp209_read_interrupt_bank_3(); if(val_int_bank_3 < 0){ GPIO_PRINTF(" Could not read AXP209 with I2C\n"); @@ -389,21 +405,23 @@ int listen_gpios_interrupts(void) if(val_int_bank_3 & AXP209_INTERRUPT_PEK_SHORT_PRESS){ GPIO_PRINTF(" AXP209 short PEK key press detected\n"); sendKeyAndStopKey(KEY_IDX_MAPPED_FOR_SHORT_PEK_PRESS); - /*sendKey(KEY_IDX_MAPPED_FOR_SHORT_PEK_PRESS, !mapping_PEK_short_press_activated); - mapping_PEK_short_press_activated = !mapping_PEK_short_press_activated;*/ } if(val_int_bank_3 & AXP209_INTERRUPT_PEK_LONG_PRESS){ GPIO_PRINTF(" AXP209 long PEK key press detected\n"); sendKeyAndStopKey(KEY_IDX_MAPPED_FOR_LONG_PEK_PRESS); - /*sendKey(KEY_IDX_MAPPED_FOR_LONG_PEK_PRESS, !mapping_PEK_long_press_activated); - mapping_PEK_long_press_activated = !mapping_PEK_long_press_activated;*/ } } #endif //ENABLE_AXP209_INTERRUPTS if(interrupt_i2c_expander_found){ - GPIO_PRINTF(" Processing interrupt PCAL6416AHF\n"); + if(forced_interrupt){ + PERIODIC_CHECK_PRINTF(" Processing forced interrupt PCAL6416AHF\n"); + } + else{ + GPIO_PRINTF(" Processing real interrupt PCAL6416AHF\n"); + } + // Read I2C GPIO masks: int val_i2c_mask_interrupted = pcal6416a_read_mask_interrupts(); if(val_i2c_mask_interrupted < 0){ @@ -420,17 +438,17 @@ int listen_gpios_interrupts(void) // Find GPIO idx correspondance for (idx_gpio=0; idx_gpio Interrupt GPIO: %d, idx_pin: %d\n", gpio_pins[idx_gpio], idx_gpio); + GPIO_PRINTF(" --> Interrupt GPIO: %d, idx_pin: %d\n", gpio_pins_idx_declared[idx_gpio], idx_gpio); mask_gpio_current_interrupts[idx_gpio] = true; } @@ -438,7 +456,8 @@ int listen_gpios_interrupts(void) if( !mask_gpio_current_interrupts[idx_gpio] && (mask_gpio_value[idx_gpio] != previous_mask_gpio_value[idx_gpio]) ){ // Print information - GPIO_PRINTF(" --> No Interrupt (missed) but value has changed on GPIO: %d, idx_pin: %d\n", gpio_pins[idx_gpio], idx_gpio); + GPIO_PRINTF(" --> No Interrupt (missed) but value has changed on GPIO: %d, idx_pin: %d\n", + gpio_pins_idx_declared[idx_gpio], idx_gpio); mask_gpio_current_interrupts[idx_gpio] = true; } } @@ -448,7 +467,8 @@ int listen_gpios_interrupts(void) for (idx_gpio=0; idx_gpio