Skip to content

Instantly share code, notes, and snippets.

@jarikomppa
Created September 10, 2023 18:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarikomppa/28d37ec1520b00c9ee30e2d271cdf064 to your computer and use it in GitHub Desktop.
Save jarikomppa/28d37ec1520b00c9ee30e2d271cdf064 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h> // mmap
#include <fcntl.h> // open
static unsigned int *gpio_mmap = 0;
int init_gpio()
{
int gpio_file = -1;
gpio_file = open("/dev/gpiomem", O_RDWR | O_SYNC);
if (gpio_file < 0)
{
printf("gpio open failed\n");
return 1;
}
gpio_mmap = mmap(
NULL, // Address offset, docs say to use null =)
4*1024, // Map Length
PROT_READ|PROT_WRITE, // Enable Read and Write
MAP_SHARED, // The map can be used by other processes
gpio_file, // The file opened for the map
0 // Offset - none required
);
// mmap done, don't need file anymore
close(gpio_file);
if (gpio_mmap == MAP_FAILED)
{
printf("gpio mmap failed\n");
gpio_mmap = 0;
return 1;
};
return 0;
}
void gpio_deinit()
{
if (gpio_mmap)
{
munmap(gpio_mmap, 4*1024);
}
gpio_mmap = 0;
}
void set_gpio_io(int pin, int output)
{
if (!gpio_mmap) return;
// input or output state is set as 3 bits per pin, stored as 10 pins per dword
// 000 = input, 001 = output, (010 = special peripheral whatever)
int block = pin / 10;
int pinofs = (pin % 10) * 3;
// mask out the 3 bits and set the one bit as requested
*(gpio_mmap + block) = (*(gpio_mmap + block) & ~(7 << pinofs)) | (output << pinofs);
}
void set_gpio_val(int pin, int val)
{
if (!gpio_mmap) return;
int block = (val ? 7 : 10); // SET and CLEAR register offsets
*(gpio_mmap + block) = 1 << pin;
}
int get_gpio_val(int pin)
{
if (!gpio_mmap) return 0;
int block = 13; // LEVEL register offset
return !!(*(gpio_mmap + block) & (1 << pin));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment