Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
LinuxGpio.hxx
Go to the documentation of this file.
1
68#ifndef __LINUXGPIO_HXX
69#define __LINUXGPIO_HXX
70
72#include "os/Gpio.hxx"
73#include <sys/types.h>
74#include <sys/stat.h>
75#include <fcntl.h>
76#include <stdio.h>
77#include <unistd.h>
78
87template <int PIN_NUM> class LinuxGpio
88{
89public:
91 static constexpr const uint32_t PIN = PIN_NUM;
92
94 static void export_pin()
95 {
96 FILE *fp = fopen("/sys/class/gpio/export","w");
97 fprintf(fp,"%d\n",PIN);
98 fclose(fp);
99 // 50ms delay IS needed while kernel changes ownership of created GPIO directory
100 usleep(50000);
101 }
102
104 static void set_output()
105 {
106 char dirname[40];
107 snprintf(dirname,sizeof(dirname),"/sys/class/gpio/gpio%d/direction",PIN);
108 int dfd = -1;
109 while ((dfd = open(dirname,O_WRONLY)) < 0) {
110 export_pin();
111 }
112 write(dfd,"out\n",4);
113 close(dfd);
114 }
116 static void set_input()
117 {
118 char dirname[40];
119 snprintf(dirname,sizeof(dirname),"/sys/class/gpio/gpio%d/direction",PIN);
120 int dfd = -1;
121 while ((dfd = open(dirname,O_WRONLY)) < 0) {
122 export_pin();
123 }
124 write(dfd,"in\n",3);
125 close(dfd);
126 }
128 static void set_on()
129 {
130 char valname[40];
131 snprintf(valname,sizeof(valname),"/sys/class/gpio/gpio%d/value",PIN);
132 int vfd = open(valname,O_WRONLY);
133 write(vfd,"1\n",2);
134 close(vfd);
135 }
137 static void set_off()
138 {
139 char valname[40];
140 snprintf(valname,sizeof(valname),"/sys/class/gpio/gpio%d/value",PIN);
141 int vfd = open(valname,O_WRONLY);
142 write(vfd,"0\n",2);
143 close(vfd);
144 }
146 static bool get()
147 {
148 char valname[40], c;
149 snprintf(valname,sizeof(valname),"/sys/class/gpio/gpio%d/value",PIN);
150 int vfd = open(valname,O_RDONLY);
151 read(vfd,&c,1);
152 close(vfd);
153 return (c != '0');
154 }
156 static void set(bool value)
157 {
158 if (value)
159 {
160 set_on();
161 }
162 else
163 {
164 set_off();
165 }
166 }
167
169 static void toggle()
170 {
171 set(!get());
172 }
173
175 static bool is_output()
176 {
177 char dirname[40], c;
178 snprintf(dirname,sizeof(dirname),"/sys/class/gpio/gpio%d/direction",PIN);
179 int dfd = open(dirname,O_RDONLY);
180 read(dfd,&c,1);
181 close(dfd);
182 return (c == 'o');
183 }
184};
185
186
188template <class Base, bool SAFE_VALUE, bool INVERT = false>
189struct GpioOutputPin : public Base
190{
191public:
193 static void hw_init()
194 {
195 Base::export_pin();
196 Base::set_output();
197 Base::set(SAFE_VALUE);
198 }
200 static void hw_set_to_safe()
201 {
202 Base::set(SAFE_VALUE);
203 }
206 static void set(bool value)
207 {
208 if (INVERT)
209 {
210 Base::set(!value);
211 }
212 else
213 {
214 Base::set(value);
215 }
216 }
218 static constexpr const Gpio *instance()
219 {
221 }
222};
223
227template <class Defs>
228struct GpioOutputSafeLow : public GpioOutputPin<Defs, false>
229{
230};
231
236template <class Defs>
237struct GpioOutputSafeLowInvert : public GpioOutputPin<Defs, false, true>
238{
239};
240
244template <class Defs>
245struct GpioOutputSafeHigh : public GpioOutputPin<Defs, true>
246{
247};
248
253template <class Defs>
254struct GpioOutputSafeHighInvert : public GpioOutputPin<Defs, true, true>
255{
256};
258template <class Base, bool ACTIVE_HIGH = true>
259struct GpioInputPin : public Base
260{
261public:
263 static void hw_init()
264 {
265 Base::export_pin();
266 Base::set_input();
267 }
269 static void hw_set_to_safe()
270 {
271 hw_init();
272 }
274 static const Gpio *instance()
275 {
277 }
278 static bool get()
279 {
280 if (ACTIVE_HIGH)
281 {
282 return Base::get();
283 }
284 else
285 {
286 return !Base::get();
287 }
288 }
289};
290
294template <class Defs>
295struct GpioInputActiveHigh : public GpioInputPin<Defs, true>
296{
297};
298
302template <class Defs>
303struct GpioInputActiveLow : public GpioInputPin<Defs, false>
304{
305};
306
307
308
324#define GPIO_PIN(NAME, BaseClass, NUM) \
325 typedef BaseClass<LinuxGpio<NUM>> NAME##_Pin
326
327#endif // __LINUXGPIO_HXX
328
Creates an implementation of an os-independent Gpio object from a hardware-specific static Gpio struc...
OS-independent abstraction for GPIO.
Definition Gpio.hxx:43
Defines a GPIO output pin.
Definition LinuxGpio.hxx:88
static void toggle()
Toggles output pin value.
static void set(bool value)
Set output pin level.
static bool is_output()
static constexpr const uint32_t PIN
Number of the pin.
Definition LinuxGpio.hxx:91
static void export_pin()
Export pin.
Definition LinuxGpio.hxx:94
static void set_on()
Sets output to HIGH.
static void set_off()
Sets output to LOW.
static bool get()
static void set_input()
Sets pin to input.
static void set_output()
Sets pin to output.
Defines a GPIO input pin, Active High (High == true).
Defines a GPIO input pin, Active Low (Low == true).
Parametric GPIO input class.
static const Gpio * instance()
static bool get()
Get the current pin state.
static void hw_init()
Initializes the hardware pin.
static void hw_set_to_safe()
Sets the hardware pin to a safe state.
static constexpr const Gpio * instance()
Parametric GPIO output class.
static constexpr const Gpio * instance()
static void hw_init()
Initializes the hardware pin.
static void set(bool value)
Sets the output pinm.
static void hw_set_to_safe()
Sets the hardware pin to a safe value.
Defines a GPIO output pin, initialized to be an output pin with high level.
Defines a GPIO output pin, initialized to be an output pin with high level.
Defines a GPIO output pin, initialized to be an output pin with low level.
Defines a GPIO output pin, initialized to be an output pin with low level.