/********************************************************************************* * Copyright: (C) 2019 LingYun IoT System Studio * All rights reserved. * * Filename: hal.c * Description: This file is RPi HAL(Hardware Abstract Layer) initial functions * * Version: 1.0.0(2019年06月24日) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "2019年06月24日 23时46分47秒" * ********************************************************************************/ #include "lylib/logger.h" #include "hal.h" #define RPI_GPIONAME "gpiochip0" static struct gpiod_chip *s_chip; static struct gpiod_line *s_light_lines[LIGHT_MAX]; /* relay GPIO lines */ static struct gpiod_line *s_infrared_lines; /* infrared GPIO lines */ static int s_light_cnt; int hal_init(hal_ctx_t *ctx) { int i; if(!ctx) { log_err("Invalid input arguments\n"); return -1; } /* current configure light counts */ s_light_cnt = ctx->light_cnt; /* gpiod open chip */ s_chip = gpiod_chip_open_by_name(RPI_GPIONAME); if( !s_chip ) { log_err("gpiod open chip failure, maybe you need running as root\n"); return -2; } log_nrml("gpiod initialise open chip ok\n"); /* gpiod get gpio lines and request relay pin as output */ for(i=0; ilight_cnt; i++) { s_light_lines[i] = gpiod_chip_get_line(s_chip, ctx->light_pins[i]); if( !s_light_lines[i] ) { log_err("gpiod get line for pin[%d] failure\n", ctx->light_pins[i]); return -2; } gpiod_line_request_output(s_light_lines[i], "lightd", RELAY_INACTVLEVEL); } log_nrml("gpiod initialise request relay pins output ok\n"); /* gpiod get gpio lines and request infrared pin as input */ if( ctx->infrared_pin ) { s_infrared_lines = gpiod_chip_get_line(s_chip, ctx->infrared_pin); gpiod_line_request_rising_edge_events(s_infrared_lines, "infrared"); } return 0; } void hal_term(hal_ctx_t *ctx) { int i; if(!ctx) { log_err("Invalid input arguments\n"); return ; } for(i=0; ilight_cnt; i++) { gpiod_line_release(s_light_lines[i]); } gpiod_line_release(s_infrared_lines); gpiod_chip_close(s_chip); return ; } void turn_light(int which, int cmd) { if( which >= s_light_cnt ) { log_err("light[%d] not support in configure file\n", which); return ; } if( OFF == cmd ) { gpiod_line_set_value(s_light_lines[which], RELAY_INACTVLEVEL); } else { gpiod_line_set_value(s_light_lines[which], RELAY_ACTVLEVEL); } return ; } /* Return value: 1(HIGH): Sombody detected 0(LOW): Nobody detected */ int infrared_detect(void) { struct gpiod_line_event event; /* This function will block, must call it to setup */ if( gpiod_line_event_wait(s_infrared_lines, NULL) < 0 ) { //log_err("infrared gpiod line wait event failure!\n"); return 0; } /* This function will block, must read to clear the event */ if (gpiod_line_event_read(s_infrared_lines, &event) < 0) { log_err("gpiod line event read failure!\n"); return 0; } if (event.event_type == GPIOD_LINE_EVENT_RISING_EDGE) return 1; else return 0; }