Skip to content

Instantly share code, notes, and snippets.

@mvduin
Last active May 2, 2017
Embed
What would you like to do?
#pragma once
#include "die.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
struct Gpio {
int fd = -1;
char *path = NULL;
Gpio() = delete;
Gpio( Gpio const & ) = delete;
protected:
Gpio( uint n, int mode )
{
if( asprintf( &path, "/sys/class/gpio/gpio%u/value", n ) < 0 ) {
path = NULL;
die( "asprintf: %m" );
}
fd = open( path, mode | O_CLOEXEC );
if( fd < 0 )
die( "open %s: %m", path );
}
public:
~Gpio()
{
free( path );
if( fd >= 0 )
close( fd );
}
operator bool () const
{
char c;
ssize_t res = pread( fd, &c, 1, 0 );
if( res < 0 )
die( "pread %s: %m", path );
if( res == 0 )
die( "pread %s: no data", path );
return c & 1;
}
};
struct GpIn : Gpio {
GpIn( uint n ) : Gpio( n, O_RDONLY ) {}
};
// assumes direction has already been set
struct GpOut : Gpio {
GpOut( uint n ) : Gpio( n, O_RDWR ) {}
bool operator = ( bool value )
{
char c = '0' + value;
ssize_t res = pwrite( fd, &c, 1, 0 );
if( res < 0 )
die( "pwrite %s: %m", path );
return value;
}
};
@mvduin
Copy link
Author

mvduin commented May 2, 2017

We actually declare our GPIOs in Device Tree hence don't need to export or initialize them at runtime, which is why those steps are being skipped here. We also use udev to setup ownership/permissions for the gpios and create symlinks in /dev/gpio/ with sensible names, which is why revision 1 of this gist identified the gpios using names instead of gpio numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment