From be98d13782b05e7659f601980ef695a493d6bee1 Mon Sep 17 00:00:00 2001 From: guowenxue <guowenxue@gmail.com> Date: Wed, 21 Aug 2024 17:29:28 +0800 Subject: [PATCH] Add infrared source code --- hal/api/led.h | 8 - hal/api/infrared.h | 60 ++++++++ hal/api/relay.c | 6 hal/api/relay.h | 7 - hal/api/infrared.c | 307 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 371 insertions(+), 17 deletions(-) diff --git a/hal/api/infrared.c b/hal/api/infrared.c new file mode 100644 index 0000000..6aa2e36 --- /dev/null +++ b/hal/api/infrared.c @@ -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 ; +} + diff --git a/hal/api/infrared.h b/hal/api/infrared.h new file mode 100644 index 0000000..fb57c8e --- /dev/null +++ b/hal/api/infrared.h @@ -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 diff --git a/hal/api/led.h b/hal/api/led.h index 4f2937c..f2105ad 100644 --- a/hal/api/led.h +++ b/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_ diff --git a/hal/api/relay.c b/hal/api/relay.c index 4d14ae2..b7bb24d 100644 --- a/hal/api/relay.c +++ b/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 */ diff --git a/hal/api/relay.h b/hal/api/relay.h index c03cd9f..bf678b2 100644 --- a/hal/api/relay.h +++ b/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_ -- Gitblit v1.9.1