LingYun Studio embeded system framwork software, such as thirdparty build shell and lingyun library
guowenxue
2024-08-21 be98d13782b05e7659f601980ef695a493d6bee1
Add infrared source code
3 files modified
2 files added
388 ■■■■■ changed files
hal/api/infrared.c 307 ●●●●● patch | view | raw | blame | history
hal/api/infrared.h 60 ●●●●● patch | view | raw | blame | history
hal/api/led.h 8 ●●●●● patch | view | raw | blame | history
hal/api/relay.c 6 ●●●●● patch | view | raw | blame | history
hal/api/relay.h 7 ●●●●● patch | view | raw | blame | history
hal/api/infrared.c
New file
@@ -0,0 +1,307 @@
/*********************************************************************************
 *      Copyright:  (C) 2024 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  infrared.h
 *    Description:  This file is HC-SR501 infrared sensor code
 *
 * Pin connection:
 *               HC-SR501 Module          IGKBoard-IMX6ULL
 *                  VCC       <----->      5V
 *                  I/O       <----->      #Pin22(GPIO3_IO23)
 *                  GND       <----->      GND
 *
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <getopt.h>
#include <libgen.h>
#include "infrared.h"
int g_stop = 0;
static inline void msleep(unsigned long ms);
void sig_handler(int signum);
static void program_usage(const char *progname)
{
    printf("Usage: %s [OPTION]...\n", progname);
    printf(" This is infrared detect program. \n");
    printf(" -d[device  ]  Specify infrared device, such as 0\n");
    printf(" -h[help    ]  Display this help information\n");
    printf("\n");
    printf("%s program Version v1.0.0\n", progname);
    printf("Copyright (C) 2023 LingYun IoT System Studio.\n");
    return;
}
int main(int argc, char **argv)
{
    char           *progname=NULL;
    int             rv;
    int             which = -1;
    struct option long_options[] = {
        {"device", required_argument, NULL, 'd'},
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };
    progname = basename(argv[0]);
    /* Parser the command line parameters */
    while ((rv = getopt_long(argc, argv, "d:h", long_options, NULL)) != -1)
    {
        switch (rv)
        {
            case 'd': /*  Set infrared number, such as 0...max */
                which = atoi(optarg);
                break;
            case 'h':  /* Get help information */
                program_usage(progname);
                return 0;
            default:
                break;
        }
    }
    if( (rv=init_infrared()) < 0 )
    {
        printf("initial infrared gpio failure, rv=%d\n", rv);
        return 1;
    }
    signal(SIGINT,  sig_handler);
    signal(SIGTERM, sig_handler);
    while( !g_stop )
    {
        rv = detect_infrared(which);
        printf("Infrared[%d] monitor: %s\n", which, rv ? "Someone is closing!":"No one nearby!");
        sleep(1);
    }
    term_infrared();
    return 0;
}
/*+-------------------------------------+
 *| Infrared API based on libgpiod v2.0 |
 *+-------------------------------------+*/
static infrared_t ir_info[IR_CNT] =
{
    {"IR1",   2, 23, IR_ACTIVE_HIGH, NULL}, /* #Pin22, GPIO3_IO23 on chip2 line 23, active high */
};
/* infrareds context */
static infrareds_t infrareds =
{
    .infrareds  = ir_info,
    .count = IR_CNT,
};
int init_infrared(void)
{
    infrared_t                  *infrared;
    int                          i, rv = 0;
    char                         chip_dev[32];
    struct gpiod_chip           *chip;      /* gpio chip */
    struct gpiod_line_settings  *settings;  /* gpio direction, bias, active_low, value */
    struct gpiod_line_config    *line_cfg;  /* gpio line */
    struct gpiod_request_config *req_cfg;   /* gpio consumer, it can be NULL */
    /* defined in libgpiod-2.0/lib/line-settings.c:
        struct gpiod_line_settings {
            enum gpiod_line_direction direction;
            enum gpiod_line_edge edge_detection;
            enum gpiod_line_drive drive;
            enum gpiod_line_bias bias;
            bool active_low;
            enum gpiod_line_clock event_clock;
            long debounce_period_us;
            enum gpiod_line_value output_value;
        };
     */
    settings = gpiod_line_settings_new();
    if (!settings)
    {
        printf("unable to allocate line settings\n");
        rv = -2;
        goto cleanup;
    }
    /* defined in libgpiod-2.0/lib/line-config.c
        struct gpiod_line_config {
            struct per_line_config line_configs[LINES_MAX];
            size_t num_configs;
            enum gpiod_line_value output_values[LINES_MAX];
            size_t num_output_values;
            struct settings_node *sref_list;
        };
    */
    line_cfg = gpiod_line_config_new();
    if (!line_cfg)
    {
        printf("unable to allocate the line config structure");
        rv = -2;
        goto cleanup;
    }
    /* defined in libgpiod-2.0/lib/request-config.c:
        struct gpiod_request_config {
            char consumer[GPIO_MAX_NAME_SIZE];
            size_t event_buffer_size;
        };
     */
    req_cfg = gpiod_request_config_new();
    if (!req_cfg)
    {
        printf("unable to allocate the request config structure");
        rv = -2;
        goto cleanup;
    }
    for(i=0; i<infrareds.count; i++)
    {
        infrared = &infrareds.infrareds[i];
        snprintf(chip_dev, sizeof(chip_dev), "/dev/gpiochip%d", infrared->chip_num);
        chip = gpiod_chip_open(chip_dev);
        if( !chip )
        {
            printf("open gpiochip failure, maybe you need running as root\n");
            rv = -3;
            goto cleanup;
        }
        /* Set as input direction */
        gpiod_line_settings_reset(settings);
        gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT);
        /* set gpio line */
        gpiod_line_config_reset(line_cfg);
        gpiod_line_config_add_line_settings(line_cfg, &infrared->gpio_num, 1, settings);
        /* Can be NULL for default settings. */
        gpiod_request_config_set_consumer(req_cfg, infrared->name);
        /* Request a set of lines for exclusive usage. */
        infrared->request = gpiod_chip_request_lines(chip, req_cfg, line_cfg);
        gpiod_chip_close(chip);
        //printf("request %5s infrared[%d] for gpio output okay\n", infrared->name, infrared->gpio);
    }
cleanup:
    if( rv< 0 )
        term_infrared();
    if( line_cfg )
        gpiod_line_config_free(line_cfg);
    if( req_cfg )
        gpiod_request_config_free(req_cfg);
    if( settings )
        gpiod_line_settings_free(settings);
    return rv;
}
int term_infrared(void)
{
    infrared_t     *infrared;
    int             i;
    printf("terminate infrared gpios\n");
    for(i=0; i<infrareds.count; i++)
    {
        infrared = &infrareds.infrareds[i];
        if( infrared->request )
        {
            gpiod_line_request_release(infrared->request);
        }
    }
    return 0;
}
int detect_infrared(int which)
{
    int            rv = 0;
    infrared_t    *infrared;
    if( which<0 || which>=infrareds.count )
    {
        printf("Invalid input arguments\n");
        return 0;
    }
    infrared = &infrareds.infrareds[which];
    return gpiod_line_request_get_value(infrared->request, infrared->gpio_num)==infrared->active ? 1 : 0;
}
/*+-------------------------------+
 *|      Misc functions API       |
 *+-------------------------------+*/
static inline void msleep(unsigned long ms)
{
    struct timespec cSleep;
    unsigned long ulTmp;
    cSleep.tv_sec = ms / 1000;
    if (cSleep.tv_sec == 0)
    {
        ulTmp = ms * 10000;
        cSleep.tv_nsec = ulTmp * 100;
    }
    else
    {
        cSleep.tv_nsec = 0;
    }
    nanosleep(&cSleep, 0);
    return ;
}
void sig_handler(int signum)
{
    switch( signum )
    {
        case SIGINT:
        case SIGTERM:
            g_stop = 1;
        default:
            break;
    }
    return ;
}
hal/api/infrared.h
New file
@@ -0,0 +1,60 @@
/*********************************************************************************
 *      Copyright:  (C) 2024 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  infrared.h
 *    Description:  This file is HC-SR501 infrared sensor code
 *
 * Pin connection:
 *               HC-SR501 Module          IGKBoard-IMX6ULL
 *                  VCC       <----->      5V
 *                  I/O       <----->      #Pin37(GPIO5_IO09)
 *                  GND       <----->      GND
 *
 ********************************************************************************/
#ifndef  _INFRARED_H_
#define  _INFRARED_H_
#include "gpiod.h"
/* infrared number */
enum
{
    IR1 = 0,
    IR_CNT,
};
enum
{
    IR_ACTIVE_LOW,  /* Low level active */
    IR_ACTIVE_HIGH, /* High level active */
};
/* infrared hardware information */
typedef struct infrared_s
{
    const char               *name;      /* infrared name  */
    int                       chip_num;  /* infrared connect chip */
    int                       gpio_num;  /* infrared connect line */
    int                       active;    /* infrared active level */
    struct gpiod_line_request *request;  /* libgpiod gpio request handler */
} infrared_t;
/* infrared structure */
typedef struct infrareds_s
{
    infrared_t          *infrareds;/* infrared pointer to infrareds_info */
    int                  count; /* infrared count */
} infrareds_t;
/* initial infrareds */
int init_infrared(void);
/* terminate infrareds   */
int term_infrared(void);
/* detect infrareds */
int detect_infrared(int which);
#endif
hal/api/led.h
@@ -5,14 +5,6 @@
 *       Filename:  led.h
 *    Description:  This file is used to control RGB 3-colors LED
 *
 *
 * Pin connection:
 *               RGB Led Module           IGKBoard-IMX6ULL
 *                   R        <----->      #Pin36 (GPIO1_IO11)
 *                   G        <----->      #Pin38 (GPIO1_IO10)
 *                   B        <----->      #Pin40 (GPIO5_IO09)
 *                  GND       <----->      GND
 *
 ********************************************************************************/
#ifndef  _LED_H_
hal/api/relay.c
@@ -9,7 +9,7 @@
 * Pin connection:
 *                 Relay Module           IGKBoard-IMX6ULL
 *                  VCC       <----->      5V
 *                   I        <----->      #Pin22 (GPIO3_IO23)
 *                   I        <----->      #Pin37 (GPIO5_IO08)
 *                  GND       <----->      GND
 *
 ********************************************************************************/
@@ -92,6 +92,8 @@
    turn_relay(which, status);
    term_relay();
    return 0;
}
@@ -102,7 +104,7 @@
static relay_t relays_info[RELAY_CNT] =
{
    {"relay1",  2, 23,  ACTIVE_HIGH, 0, NULL}, /* #Pin22, GPIO3_IO23 on chip2 line 23, active high */
    {"relay1",  4, 8,  ACTIVE_HIGH, 0, NULL}, /* #Pin37, GPIO5_IO08 on chip4 line 8, active high */
};
/* relays context */
hal/api/relay.h
@@ -5,13 +5,6 @@
 *       Filename:  relay.h
 *    Description:  This file is used to control relay
 *
 *
 * Pin connection:
 *                 Relay Module           IGKBoard-IMX6ULL
 *                  VCC       <----->      5V
 *                   I        <----->      #Pin22 (GPIO3_IO23)
 *                  GND       <----->      GND
 *
 ********************************************************************************/
#ifndef  _RELAY_H_