handling pins polarity now: if they need to be activated high or low

This commit is contained in:
Vincent-FK 2020-01-14 08:24:04 +08:00
parent 14099e2859
commit 8ce97243a6
8 changed files with 98 additions and 43 deletions

View File

@ -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");

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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<nb_mapped_gpios; idx_gpio++){
uint16_t tmp_mask_gpio = (1 << gpio_pins[idx_gpio]);
uint16_t tmp_mask_gpio = (1 << gpio_pins_idx_declared[idx_gpio]);
// Found GPIO idx in active GPIOs
if(val_i2c_mask_active & tmp_mask_gpio){
mask_gpio_value[idx_gpio] = true;
}
// Found GPIO idx in interrupt mask
if(val_i2c_mask_interrupted & tmp_mask_gpio){
// Print information
GPIO_PRINTF(" --> 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<nb_mapped_gpios; idx_gpio++){
if(!mask_gpio_current_interrupts[idx_gpio]) continue;
if (mask_gpio_value[idx_gpio]){
if ( (mask_gpio_value[idx_gpio] && gpios_pins_active_high[idx_gpio]) ||
(!mask_gpio_value[idx_gpio] && !gpios_pins_active_high[idx_gpio]) ){
find_and_call_mapping_function(idx_gpio,
chained_list_mapping,
mask_gpio_current_interrupts,

View File

@ -6,7 +6,7 @@
****************************************************************/
#include "gpio-utils.h"
#include "uinput.h"
#include "read_conf_file.h"
#include "read_conf_file.h"
/****************************************************************
* Defines
@ -17,7 +17,9 @@
/****************************************************************
* Public functions
****************************************************************/
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);
int deinit_mapping_gpios(void);
int listen_gpios_interrupts(void);

View File

@ -19,6 +19,7 @@
} while(0)
#define DEBUG_READ_CONF_FILE_PRINTF (0)
#define ERROR_READ_CONF_FILE_PRINTF (1)
#if (DEBUG_READ_CONF_FILE_PRINTF)
#define READ_CONF_FILE_PRINTF(...) printf(__VA_ARGS__);
@ -26,6 +27,12 @@
#define READ_CONF_FILE_PRINTF(...)
#endif
#if (ERROR_READ_CONF_FILE_PRINTF)
#define ERROR_CONF_FILE_PRINTF(...) printf(__VA_ARGS__);
#else
#define ERROR_CONF_FILE_PRINTF(...)
#endif
/****************************************************************
* Extern variables
@ -39,6 +46,7 @@ extern key_names_s key_names[];
static STRUCT_MAPPED_GPIO * head_chained_list_mapping_gpio = NULL;
static int count_valid_gpios = 0;
static int gpio_pins[MAX_NUM_GPIO];
static bool gpio_active_high[MAX_NUM_GPIO];
/****************************************************************
@ -136,7 +144,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
* Public functions
****************************************************************/
void get_mapping_from_conf_file(STRUCT_MAPPED_GPIO ** chained_list_mapping,
int* nb_valid_gpios, int ** valid_gpio_pins){
int* nb_valid_gpios, int ** valid_gpio_pins, bool ** gpio_pins_active_high){
/* Variables */
READ_CONF_FILE_PRINTF("Reading the config file:\n");
FILE *fp;
@ -164,7 +172,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
}
}
if(fp){
READ_CONF_FILE_PRINTF("Config file found at %s\n", conffile);
printf("GPIO config file used: %s\n", conffile);
}
/* Main loop to read conf file (purposely exploded and not in multiple sub-functions) */
@ -183,14 +191,25 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
//count nb valid GPIOs and store them
token = strtok(ln, ",");
while(token != NULL){
// Search for char '*' which means active low
bool cur_active_high = true;
char *substr = strchr(token, '*');
if(substr != NULL){
// Save polarity and set this char to \0 to end string
cur_active_high = false;
substr[0] = 0;
}
// Read pin idx
token_int = atoi(token);
if(token_int || !strcmp(token, "0")){
gpio_pins[count_valid_gpios] = token_int;
gpio_active_high[count_valid_gpios] = cur_active_high;
count_valid_gpios++;
READ_CONF_FILE_PRINTF("GPIO %d declared\n", token_int);
READ_CONF_FILE_PRINTF("GPIO %d declared - active %s\n", token_int, cur_active_high?"high":"low");
}
else{
READ_CONF_FILE_PRINTF("Could not declare GPIO: %s\n", token);
ERROR_CONF_FILE_PRINTF("Could not declare GPIO: %s\n", token);
}
token = strtok(NULL, ",");
}
@ -225,7 +244,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
if(cur_pin || !strcmp(token_plus, "0")){
int idx_cur_pin = get_idx_pin(gpio_pins, count_valid_gpios, cur_pin);
if(idx_cur_pin == -1){
READ_CONF_FILE_PRINTF(" Could not find GPIO: %s in previously instanciated GPIOs\n", token_plus);
ERROR_CONF_FILE_PRINTF(" Could not find GPIO: %s in previously instanciated GPIOs\n", token_plus);
add_current_mapping = false;
break;
}
@ -234,7 +253,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
READ_CONF_FILE_PRINTF(" GPIO %d in current mapping\n", cur_pin);
}
else{
READ_CONF_FILE_PRINTF(" Could not find GPIO: %s\n", token_plus);
ERROR_CONF_FILE_PRINTF(" Could not find GPIO: %s\n", token_plus);
add_current_mapping = false;
break;
}
@ -250,7 +269,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
cur_gpio_mapping.type_mapping = TYPE_MAPPING_SHELL_COMMAND;
}
else{
READ_CONF_FILE_PRINTF(" %s is not a valid mapping type\n", current_arg);
ERROR_CONF_FILE_PRINTF(" %s is not a valid mapping type\n", current_arg);
add_current_mapping = false;
break;
}
@ -260,7 +279,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
case TYPE_MAPPING_KEYBOARD:
cur_gpio_mapping.key_value = find_key(current_arg);
if(!cur_gpio_mapping.key_value){
READ_CONF_FILE_PRINTF(" Could not find Key: %s\n", current_arg);
ERROR_CONF_FILE_PRINTF(" Could not find Key: %s\n", current_arg);
add_current_mapping = false;
}
break;
@ -269,7 +288,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
strcpy(cur_gpio_mapping.shell_command, current_arg);
break;
default:
READ_CONF_FILE_PRINTF(" %d is not a valid mapping type\n", cur_gpio_mapping.type_mapping);
ERROR_CONF_FILE_PRINTF(" %d is not a valid mapping type\n", cur_gpio_mapping.type_mapping);
add_current_mapping = false;
break;
}
@ -299,7 +318,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
READ_CONF_FILE_PRINTF("Current Mapping added successfully\n\n");
}
else{
READ_CONF_FILE_PRINTF("Current Mapping not added\n\n");
ERROR_CONF_FILE_PRINTF("Current Mapping not added\n\n");
}
}
}
@ -319,6 +338,7 @@ static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
*chained_list_mapping = head_chained_list_mapping_gpio;
*nb_valid_gpios = count_valid_gpios;
*valid_gpio_pins = gpio_pins;
*gpio_pins_active_high = gpio_active_high;
}

View File

@ -66,7 +66,7 @@ typedef struct gpio_mapping_s{
* Public functions
****************************************************************/
void get_mapping_from_conf_file(STRUCT_MAPPED_GPIO ** chained_list_mapping,
int* nb_valid_gpios, int ** valid_gpio_pins);
int* nb_valid_gpios, int ** valid_gpio_pins, bool ** gpio_pins_active_high);
void print_all_chained_list(STRUCT_MAPPED_GPIO * head);
void print_chained_list_node(STRUCT_MAPPED_GPIO * node);
void print_gpios(int * valid_gpio_pins, int nb_valid_gpios);