Skip to content

Instantly share code, notes, and snippets.

@mvduin
Last active May 2, 2017 11:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mvduin/b54ad7619ec3e6363a6ad1015e5c8858 to your computer and use it in GitHub Desktop.
#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