RaspberrPi project source code
guowenxue
5 hours ago 72fea370ff20ecb2494ab985c4431b4bd691e7cd
project/lightd/hal/gpio.c
@@ -11,13 +11,16 @@
 *
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "logger.h"
#include "util_proc.h"
#include "gpio.h"
#define RPI_GPIONAME        "gpiochip0"
#include <errno.h>
#include "logger.h"
@@ -35,13 +38,11 @@
    int                 rv;
    s_gpio = gpio;
    if( !gpio )
    {
        log_error("Invalid input arguments $gpio\n");
        return -1;
    }
    if( !gpio->incnt && !gpio->outcnt )
    {
@@ -58,7 +59,6 @@
    }
    log_info("gpiod initialise open chip ok\n");
    /*  gpiod request all output pins */
    for(i=0; i<gpio->outcnt; i++)
    {
@@ -66,19 +66,21 @@
        if( !gpio->output[i].line )
        {
            log_error("gpiod get line for '%s' pin[#%d] failure\n", gpio->output[i].name, gpio->output[i].pin );
            return -2;
            rv = -3;
            goto failed;
        }
        if( gpiod_line_request_output(gpio->output[i].line, gpio->output[i].name, !gpio->output[i].active_level) < 0 )
        {
            log_error("gpiod request '%s' pin[#%d] output failure: %s\n", gpio->output[i].name, gpio->output[i].pin, strerror(errno));
            rv = -3;
            goto failed;
        }
        else
        {
            log_info("gpiod request '%s' pin[#%d] output ok\n", gpio->output[i].name, gpio->output[i].pin);
        }
    }
    /*  gpiod request all input pins */
    for(i=0; i<gpio->incnt; i++)
@@ -87,7 +89,8 @@
        if( !gpio->input[i].line )
        {
            log_error("gpiod get line for '%s' pin[#%d] failure\n", gpio->input[i].name, gpio->input[i].pin );
            return -2;
            rv = -4;
            goto failed;
        }
        if( gpio->output[i].active_level )
@@ -99,6 +102,8 @@
        {
            log_error("gpiod request '%s' pin[#%d] event edge [%s] failure: %s\n",
                    gpio->input[i].name, gpio->input[i].pin, gpio->output[i].active_level?"rising":"falling", strerror(errno));
            rv = -4;
            goto failed;
        }
        else
        {
@@ -108,6 +113,10 @@
    }
    return 0;
failed:
    gpiod_chip_close(s_chip);
    return rv;
}
@@ -122,12 +131,10 @@
        return ;
    }
    for(i=0; i<s_gpio->outcnt; i++)
    {
        gpiod_line_release(s_gpio->output[i].line);
    }
    for(i=0; i<s_gpio->incnt; i++)
    {
@@ -137,14 +144,16 @@
    gpiod_chip_close(s_chip);
}
void gpio_out(char *name, char *cmd)
/* Turn light ON or OFF */
void turn_light(char *name, int status)
{
    int              i;
    int              found = 0;
    int              value;
    for( i=0; i<s_gpio->outcnt; i++ )
    {
        if( !strncasecmp(s_gpio->output[i].name, name, strlen(name)))
        if( strstr(s_gpio->output[i].name, name) )
        {
            found = 1;
            break;
@@ -157,60 +166,11 @@
        return ;
    }
    if( strstr(cmd, "on") )
    {
        gpiod_line_set_value(s_gpio->output[i].line, s_gpio->output[i].active_level);
    }
    else if( strstr(cmd, "off") )
    {
        gpiod_line_set_value(s_gpio->output[i].line, !s_gpio->output[i].active_level);
    }
    log_info("Turn %s light %s\n", name, status?"on":"off");
    value = status ? s_gpio->output[i].active_level : !s_gpio->output[i].active_level;
    gpiod_line_set_value(s_gpio->output[i].line, value);
    return ;
}
void *light_on_worker(void *arg)
{
    int                      i;
    int                      found = 0;
    char                    *name = (char *)arg;
    gpio_info_t             *gpiout;
    if( !name )
    {
        log_error("Invalid input arugment\n");
        return NULL;
    }
    if( s_gpio->light_intval <= 0 )
    {
        log_error("Invalid light_intval value[%d] in configure file\n", s_gpio->light_intval);
        return NULL;
    }
    for(i=0; i<s_gpio->outcnt; i++)
    {
        if( strstr(s_gpio->output[i].name, name) )
        {
            gpiout = &(s_gpio->output[i]);
            found = 1;
        }
    }
    if( !found )
    {
        log_error("Light '%s' not found\n", name);
        return NULL;
    }
    log_info("Trun on %s for [%d] seconds\n", gpiout->name, s_gpio->light_intval);
    gpio_out(gpiout->name, "on");
    sleep(s_gpio->light_intval);
    gpio_out(gpiout->name, "off");
    return NULL;
}
/* Return value: 0(LOW): Nobody detected, !0: indoor or hallway detected */
@@ -218,14 +178,12 @@
{
    int                      i;
    int                      rv = 0;
    int                      res = 0;
    int                      result = 0;
    int                      num_lines = 0;
    struct gpiod_line_event  ev;
    struct gpiod_line_bulk   bulk, event_bulk;
    struct gpiod_line       *line;
    int                      num_lines = 0;
    gpiod_line_bulk_init(&bulk);
@@ -244,7 +202,7 @@
        return 0;
    }
    log_debug("infrared start detect event now...\n");
    log_debug("infrared start detect event(blocked) now...\n");
    rv = gpiod_line_event_wait_bulk(&bulk, NULL, &event_bulk);
    if( rv <= 0 )
    {
@@ -270,25 +228,23 @@
            {
                if( s_gpio->input[i].active_level != gpiod_line_get_value(line) )
                {
                    //log_debug("infrared '%s' detect get wrong power level\n", s_gpio->input[i].name);
                    log_debug("infrared '%s' detect get wrong power level\n", s_gpio->input[i].name);
                    continue;
                }
                if( strstr(s_gpio->input[i].name, "indoor") )
                {
                    log_debug("indoor infrared gpiod wait get event.\n", s_gpio->input[i].name);
                    res |= FLAG_INFRARED_INDOOR;
                    result |= FLAG_INFRARED_INDOOR;
                }
                else if( strstr(s_gpio->input[i].name, "hallway") )
                {
                    log_debug("hallway infrared gpiod wait get event.\n", s_gpio->input[i].name);
                    res |= FLAG_INFRARED_HALLWAY;
                    result |= FLAG_INFRARED_HALLWAY;
                }
            }
        }
    }
    return res;
    return result;
}