RaspberrPi project source code
Guo Wenxue
2024-12-29 8517494b239d652ea9a24457faa13f88f55979b9
commit | author | age
d6b4a7 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2021 LingYun IoT System Studio
3  *                  All rights reserved.
4  *
5  *       Filename:  led.c
6  *    Description:  This file is used to control RGB 3-colors LED
7  *                  compatible with libgpiod-1.x.x, not compatible with 2.x.x
8  *
9  *
10  * Pin connection:
11  *               RGB Led Module           Raspberry Pi Board
12  *                   R        <----->      #Pin33(BCM GPIO13)
13  *                   G        <----->      #Pin35(BCM GPIO19)
14  *                   B        <----->      #Pin37(BCM GPIO26)
15  *                  GND       <----->      GND
16  *
17  * System install:
18  *                  sudo apt install -y libgpiod-dev gpiod
19  *
20  *
21  ********************************************************************************/
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <dirent.h>
28 #include <string.h>
29 #include <time.h>
30 #include <errno.h>
31 #include <signal.h>
32
33 #include <gpiod.h>
34 #include "logger.h"
35 #include "leds.h"
36
37 #define DELAY     500
38
39 static led_info_t    leds_info[LED_CNT] =
40 {
41     {"red",   13, 1, NULL },
42     {"green", 19, 1, NULL },
43     {"blue",  26, 1, NULL },
44 };
45
46 int init_led(led_ctx_t *ctx, int which)
47 {
48     int            i, rv;
49     led_info_t    *led;
50
51     if( !ctx )
52     {
53         log_error("Invalid input arguments\n");
54         return -1;
55     }
56
57     ctx->leds = leds_info;
58     ctx->count = LED_CNT;
59
60     ctx->chip = gpiod_chip_open_by_name("gpiochip0");
61     if( !ctx->chip )
62     {
63         log_error("open gpiochip failure, maybe you need running as root\n");
64         return -2;
65     }
66
67     for(i=0; i<ctx->count; i++)
68     {
69         if( which == i )
70         {
71             led = &ctx->leds[i];
72
73             led->line = gpiod_chip_get_line(ctx->chip, led->gpio);
74             if( !led->line )
75             {
76                 log_error("open gpioline for %s[%d] failed\n", led->name, led->gpio);
77                 rv = -3;
78                 goto failed;
79             }
80
81             rv  = gpiod_line_request_output(led->line, led->name, !led->active);
82             if( rv )
83             {
84                 log_error("request gpio output for %5s[%d] failed: %s\n", led->name, led->gpio, strerror(errno));
85                 rv = -4;
86                 goto failed;
87             }
88
89             log_debug("request %5s led[%d] for gpio output okay\n", led->name, led->gpio);
90         }
91     }
92
93     return 0;
94
95 failed:
96     term_led(ctx, which);
97     return rv;
98 }
99
100 int term_led(led_ctx_t *ctx, int which)
101 {
102     int            i;
103     led_info_t    *led;
104
105     log_warn("terminate RGB Led gpios\n");
106
107     if( !ctx )
108     {
109         log_error("Invalid input arguments\n");
110         return -1;
111     }
112
113     if( !ctx->chip )
114         return 0;
115
116     for(i=0; i<ctx->count; i++)
117     {
118         if( which == i )
119         {
120             led = &ctx->leds[i];
121
122             if( led->line )
123                 gpiod_line_release(led->line);
124         }
125     }
126
127     gpiod_chip_close(ctx->chip);
128     return 0;
129 }
130
131 int turn_led(int which, int cmd)
132 {
133     int            rv = 0;
134     led_ctx_t      ctx;
135     led_info_t    *led;
136
137     if( which<0 || which>=LED_CNT )
138     {
139         log_error("Invalid input arguments\n");
140         return -1;
141     }
142
143     if( (rv=init_led(&ctx, which)) < 0 )
144     {
145         log_error("Initial RGB leds failure, rv=%d\n", rv);
146         return -2;
147     }
148
149     led = &ctx.leds[which];
150
151     if( OFF == cmd )
152     {
153         gpiod_line_set_value(led->line, !led->active);
154     }
155     else
156     {
157         gpiod_line_set_value(led->line, led->active);
158     }
159
160     term_led(&ctx, which);
161     return 0;
162 }