RaspberrPi project source code
Guo Wenxue
6 days ago f7889e2ceddbc3e15ea4b5377d831f4432169f76
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  *
8  *
9  * Pin connection:
10  *               RGB Led Module           Raspberry Pi Board
11  *                   R        <----->      #Pin33(BCM GPIO13)
12  *                   G        <----->      #Pin35(BCM GPIO19)
13  *                   B        <----->      #Pin37(BCM GPIO26)
14  *                  GND       <----->      GND
15  *
75843d 16  *               RGB Led Module           Raspberry Pi Board
GW 17  *                   R        <----->      #Pin36(BCM GPIO16)
18  *                   G        <----->      #Pin38(BCM GPIO20)
19  *                   B        <----->      #Pin40(BCM GPIO21)
20  *                  GND       <----->      GND
21  *
d6b4a7 22  * System install:
G 23  *                  sudo apt install -y libgpiod-dev gpiod
24  *
25  *
26  ********************************************************************************/
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <dirent.h>
33 #include <string.h>
34 #include <time.h>
35 #include <errno.h>
36 #include <signal.h>
37
38 #include <gpiod.h>
39
40 #define DELAY     500
41
42 #define ON        1
43 #define OFF       0
44
45 /* Three LEDs code */
46 enum
47 {
48     LED_R = 0,
49     LED_G,
50     LED_B,
51     LEDCNT,
52 };
53
54 /* Three LEDs hardware information */
55 typedef struct led_info_s
56 {
57     const char         *name;  /* RGB 3-color LED name  */
58     int                 gpio;  /* RGB 3-color LED BCM pin number */
59     int                 active;/* RGB 3-color LED active GPIO level: 0->low 1->high */
60     struct gpiod_line  *line;  /* libgpiod line */
61 } led_info_t;
62
75843d 63 #define CONFIG_PIN_333537
GW 64 //#define CONFIG_PIN_363840
65
d6b4a7 66 static led_info_t    leds_info[LEDCNT] =
G 67 {
75843d 68 #ifdef CONFIG_PIN_333537
d6b4a7 69     {"red",   13, 1, NULL },
G 70     {"green", 19, 1, NULL },
71     {"blue",  26, 1, NULL },
75843d 72 #elif (defined CONFIG_PIN_363840)
GW 73     {"red",   16, 1, NULL },
74     {"green", 20, 1, NULL },
75     {"blue",  21, 1, NULL },
76 #endif
d6b4a7 77 };
G 78
79 /* Three LEDs API context */
80 typedef struct led_ctx_s
81 {
82     struct gpiod_chip   *chip;
83     led_info_t          *leds;
84     int                  count;
85 } led_ctx_t;
86
87 int init_led(led_ctx_t *ctx);
88 int term_led(led_ctx_t *ctx);
89 int turn_led(led_ctx_t *ctx, int which, int cmd);
90 static inline void msleep(unsigned long ms);
91
92
93 int g_stop = 0;
94
95 void sig_handler(int signum)
96 {
97     switch( signum )
98     {
99         case SIGINT:
100         case SIGTERM:
101             g_stop = 1;
102
103         default:
104             break;
105     }
106
107     return ;
108 }
109
110 int main(int argc, char *argv[])
111 {
112     int                 rv;
113     led_ctx_t           led_ctx =
114     {
115         .chip  = NULL,
116         .leds  = leds_info,
117         .count = LEDCNT,
118     };
119
120     if( (rv=init_led(&led_ctx)) < 0 )
121     {
122         printf("initial leds gpio failure, rv=%d\n", rv);
123         return 1;
124     }
cbbab6 125     printf("initial RGB Led gpios okay\n");
d6b4a7 126
G 127     signal(SIGINT,  sig_handler);
128     signal(SIGTERM, sig_handler);
129
130     while( !g_stop )
131     {
132         turn_led(&led_ctx, LED_R, ON);
133         msleep(DELAY);
134         turn_led(&led_ctx, LED_R, OFF);
135         msleep(DELAY);
136
137         turn_led(&led_ctx, LED_G, ON);
138         msleep(DELAY);
139         turn_led(&led_ctx, LED_G, OFF);
140         msleep(DELAY);
141
142         turn_led(&led_ctx, LED_B, ON);
143         msleep(DELAY);
144         turn_led(&led_ctx, LED_B, OFF);
145         msleep(DELAY);
146     }
147
148     term_led(&led_ctx);
149     return 0;
150 }
151
152 int term_led(led_ctx_t *ctx)
153 {
154     int            i;
155     led_info_t    *led;
156
157     printf("terminate RGB Led gpios\n");
158
159     if( !ctx )
160     {
161         printf("Invalid input arguments\n");
162         return -1;
163     }
164
165     if( !ctx->chip )
166         return 0;
167
168     for(i=0; i<ctx->count; i++)
169     {
170         led = &ctx->leds[i];
171
172         if( led->line )
173             gpiod_line_release(led->line);
174     }
175
176     gpiod_chip_close(ctx->chip);
177     return 0;
178 }
179
180
181 int init_led(led_ctx_t *ctx)
182 {
183     int            i, rv;
184     led_info_t    *led;
185
186     if( !ctx )
187     {
188         printf("Invalid input arguments\n");
189         return -1;
190     }
191
192     ctx->chip = gpiod_chip_open_by_name("gpiochip0");
193     if( !ctx->chip )
194     {
195         printf("open gpiochip failure, maybe you need running as root\n");
196         return -2;
197     }
198
199
200     for(i=0; i<ctx->count; i++)
201     {
202         led = &ctx->leds[i];
203
204         led->line = gpiod_chip_get_line(ctx->chip, led->gpio);
205         if( !led->line )
206         {
207             printf("open gpioline for %s[%d] failed\n", led->name, led->gpio);
208             rv = -3;
209             goto failed;
210         }
211
212         rv  = gpiod_line_request_output(led->line, led->name, !led->active);
213         if( rv )
214         {
215             printf("request gpio output for %5s[%d] failed\n", led->name, led->gpio);
216             rv = -4;
217             goto failed;
218         }
219
220         //printf("request %5s led[%d] for gpio output okay\n", led->name, led->gpio);
221     }
222
223     return 0;
224
225 failed:
226     term_led(ctx);
227     return rv;
228 }
229
230 int turn_led(led_ctx_t *ctx, int which, int cmd)
231 {
232     int            rv = 0;
233     led_info_t    *led;
234
235     if( !ctx || which<0 || which>=ctx->count )
236     {
237         printf("Invalid input arguments\n");
238         return -1;
239     }
240
241     led = &ctx->leds[which];
242
243     if( OFF == cmd )
244     {
245         gpiod_line_set_value(led->line, !led->active);
246     }
247     else
248     {
249         gpiod_line_set_value(led->line, led->active);
250     }
251
252     return 0;
253 }
254
255 static inline void msleep(unsigned long ms)
256 {
257     struct timespec cSleep;
258     unsigned long ulTmp;
259
260     cSleep.tv_sec = ms / 1000;
261     if (cSleep.tv_sec == 0)
262     {
263         ulTmp = ms * 10000;
264         cSleep.tv_nsec = ulTmp * 100;
265     }
266     else
267     {
268         cSleep.tv_nsec = 0;
269     }
270
271     nanosleep(&cSleep, 0);
272
273     return ;
274 }
275