SSD1306 OLED display driver  1.5.6
This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
gpio.c
1 /*
2  MIT License
3 
4  Copyright (c) 2018, Alexey Dynda
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  SOFTWARE.
23 */
24 
25 #if (defined(__linux__) && !defined(__MINGW32__)) && !defined(ARDUINO)
26 
27 #include "io.h"
28 
29 #ifndef __KERNEL__
30 
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 
39 #define MAX_GPIO_COUNT 256
40 
41 #ifdef IN
42 #undef IN
43 #endif
44 #define IN 0
45 
46 #ifdef OUT
47 #undef OUT
48 #endif
49 #define OUT 1
50 
51 int gpio_export(int pin)
52 {
53  char buffer[4];
54  ssize_t bytes_written;
55  int fd;
56  char path[64];
57 
58  snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d", pin);
59 
60  if (access(path, F_OK) == 0)
61  {
62  return 0;
63  }
64 
65  fd = open("/sys/class/gpio/export", O_WRONLY);
66  if (-1 == fd)
67  {
68  fprintf(stderr, "Failed to allocate gpio pin resources[%d]: %s!\n", pin, strerror (errno));
69  return(-1);
70  }
71 
72  bytes_written = snprintf(buffer, sizeof(buffer), "%d", pin);
73  if (write(fd, buffer, bytes_written) < 0)
74  {
75  fprintf(stderr, "Failed to allocate gpio pin resources[%d]: %s!\n", pin, strerror (errno));
76  close(fd);
77  return -1;
78  }
79  close(fd);
80  return(0);
81 }
82 
83 int gpio_unexport(int pin)
84 {
85  char buffer[4];
86  ssize_t bytes_written;
87  int fd;
88 
89  fd = open("/sys/class/gpio/unexport", O_WRONLY);
90  if (-1 == fd)
91  {
92  fprintf(stderr, "Failed to free gpio pin resources!\n");
93  return(-1);
94  }
95 
96  bytes_written = snprintf(buffer, sizeof(buffer), "%d", pin);
97  if (write(fd, buffer, bytes_written) < 0)
98  {
99  fprintf(stderr, "Failed to free gpio pin resources!\n");
100  }
101  close(fd);
102  return(0);
103 }
104 
105 int gpio_direction(int pin, int dir)
106 {
107  static const char s_directions_str[] = "in\0out";
108 
109  char path[64];
110  int fd;
111 
112  snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
113  fd = open(path, O_WRONLY);
114  if (-1 == fd)
115  {
116  fprintf(stderr, "Failed to set gpio pin direction1[%d]: %s!\n", pin, strerror(errno));
117  return(-1);
118  }
119 
120  if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3))
121  {
122  fprintf(stderr, "Failed to set gpio pin direction2[%d]: %s!\n", pin, strerror(errno));
123  return(-1);
124  }
125 
126  close(fd);
127  return(0);
128 }
129 
130 int gpio_read(int pin)
131 {
132  char path[32];
133  char value_str[3];
134  int fd;
135 
136  snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
137  fd = open(path, O_RDONLY);
138  if (-1 == fd)
139  {
140  fprintf(stderr, "Failed to read gpio pin value!\n");
141  return(-1);
142  }
143 
144  if (-1 == read(fd, value_str, 3))
145  {
146  fprintf(stderr, "Failed to read gpio pin value!\n");
147  return(-1);
148  }
149 
150  close(fd);
151 
152  return(atoi(value_str));
153 }
154 
155 int gpio_write(int pin, int value)
156 {
157  static const char s_values_str[] = "01";
158 
159  char path[64];
160  int fd;
161 
162  snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
163  fd = open(path, O_WRONLY);
164  if (-1 == fd)
165  {
166  fprintf(stderr, "Failed to set gpio pin value[%d]: %s!\n", pin, strerror(errno));
167  return(-1);
168  }
169 
170  if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1))
171  {
172  fprintf(stderr, "Failed to set gpio pin value[%d]: %s!\n", pin, strerror (errno));
173  return(-1);
174  }
175 
176  close(fd);
177  return(0);
178 }
179 
180 #if !defined(SDL_EMULATION)
181 
182 static uint8_t s_exported_pin[MAX_GPIO_COUNT] = {0};
183 static uint8_t s_pin_mode[MAX_GPIO_COUNT] = {0};
184 
185 void pinMode(int pin, int mode)
186 {
187  if (!s_exported_pin[pin])
188  {
189  if ( gpio_export(pin)<0 )
190  {
191  return;
192  }
193  s_exported_pin[pin] = 1;
194  }
195  if (mode == OUTPUT)
196  {
197  gpio_direction(pin, OUT);
198  s_pin_mode[pin] = 1;
199  }
200  if (mode == INPUT)
201  {
202  gpio_direction(pin, IN);
203  s_pin_mode[pin] = 0;
204  }
205 }
206 
207 void digitalWrite(int pin, int level)
208 {
209  if (!s_exported_pin[pin])
210  {
211  if ( gpio_export(pin)<0 )
212  {
213  return;
214  }
215  s_exported_pin[pin] = 1;
216  }
217  if (!s_pin_mode[pin])
218  {
219  pinMode(pin, OUTPUT);
220  }
221  gpio_write( pin, level );
222 }
223 
224 #endif
225 
226 #endif
227 
228 #endif