A tiny library for the BCM2835
git clone git://soophie.de/libbcm2835
1
default: build3
build:4
cc -o libbcm2835.so -shared -fPIC -Wall -Wextra -Werror -pedantic src/libbcm2835.c1
default: install3
install:7
cc -o libbcm2835.so -shared -fPIC src/libbcm2835.c8
sudo cp src/libbcm2835.h /usr/local/include/libbcm2835.h9
sudo cp libbcm2835.so /usr/local/lib/libbcm2835.so10
sudo ldconfig11
rm libbcm2835.so4
sudo cp src/libbcm2835.h /usr/local/include/6
uninstall:7
sudo rm /usr/local/include/libbcm2835.h15
sudo rm /usr/local/lib/libbcm2835.so17
clean:18
rm libbcm2835.so
1
#include <stdio.h>2
#include <fcntl.h>3
#include <unistd.h>4
#include <sys/mman.h>6
#include "libbcm2835.h"8
static volatile u32_t *reg = MAP_FAILED;10
u32_t __bcm_bank(u32_t pin) {11
return (pin >> 5);12
}14
int bcm_init(void) {15
int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);16
if (fd < 0) {17
fprintf(stderr, "Failed to open() /dev/gpiomem!\n");18
return -1;19
}20
reg = (u32_t *) mmap(NULL, 0xB4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);21
close(fd);22
if (reg == MAP_FAILED) {23
fprintf(stderr, "Bad, mmap() failed!\n");24
return -1;25
}26
return 0;27
}29
void bcm_fsel(u32_t pin, bcm_fsel_e fsel) {30
int idx = BCM_FSEL0 + (pin / 10);31
int shift = 3 * (pin % 10);32
reg[idx] = (reg[idx] & ~(7 << shift)) | (fsel << shift);33
}35
void bcm_set(u32_t pin) {36
int idx = BCM_SET0 + __bcm_bank(pin);37
reg[idx] = (1 << (pin & 0x1F));38
}40
void bcm_clr(u32_t pin) {41
int idx = BCM_CLR0 + __bcm_bank(pin);42
reg[idx] = (1 << (pin & 0x1F));43
}45
int bcm_lev(u32_t pin) {46
int idx = BCM_LEV0 + __bcm_bank(pin);47
return (reg[idx] & (1 << (pin & 0x1F))) != 0;48
}50
void bcm_pud(u32_t pin, bcm_pud_e pud) {51
reg[BCM_PUD] = pud;52
usleep(20);53
reg[BCM_PUDCLK0 + __bcm_bank(pin)] = (1 << (pin & 0x1F));54
usleep(20);55
reg[BCM_PUD] = PUD_OFF;56
reg[BCM_PUDCLK0 + __bcm_bank(pin)] = 0x00;57
}59
void bcm_write(u32_t pin, int level) {60
level == HIGH61
? bcm_set(pin)62
: bcm_clr(pin);63
}65
int bcm_read(u32_t pin) {66
return bcm_lev(pin);67
}69
void bcm_pulse(u32_t pin, int level, u32_t sleep) {70
level == HIGH71
? bcm_set(pin)72
: bcm_clr(pin);73
usleep(sleep);74
level != HIGH75
? bcm_set(pin)76
: bcm_clr(pin);77
}
51
--------------------- --------------------- ---------------------52
*/54
#ifndef BCM_2835_H55
#define BCM_2835_H54
#ifndef LIB_BCM2835_H55
#define LIB_BCM2835_H57
#define BCM_FSEL0 058
#define BCM_FSEL1 1
118
int bcm_read(u32_t pin);119
void bcm_pulse(u32_t pin, int level, u32_t sleep);121
#endif121
#ifdef LIB_BCM2835_IMPL123
#include <stdio.h>124
#include <fcntl.h>125
#include <unistd.h>126
#include <sys/mman.h>128
static volatile u32_t *reg = MAP_FAILED;130
u32_t __bcm_bank(u32_t pin) {131
return (pin >> 5);132
}134
int bcm_init(void) {135
int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);136
if (fd < 0) {137
fprintf(stderr, "Failed to open() /dev/gpiomem!\n");138
return -1;139
}140
reg = (u32_t *) mmap(NULL, 0xB4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);141
close(fd);142
if (reg == MAP_FAILED) {143
fprintf(stderr, "Bad, mmap() failed!\n");144
return -1;145
}146
return 0;147
}149
void bcm_fsel(u32_t pin, bcm_fsel_e fsel) {150
int idx = BCM_FSEL0 + (pin / 10);151
int shift = 3 * (pin % 10);152
reg[idx] = (reg[idx] & ~(7 << shift)) | (fsel << shift);153
}155
void bcm_set(u32_t pin) {156
int idx = BCM_SET0 + __bcm_bank(pin);157
reg[idx] = (1 << (pin & 0x1F));158
}160
void bcm_clr(u32_t pin) {161
int idx = BCM_CLR0 + __bcm_bank(pin);162
reg[idx] = (1 << (pin & 0x1F));163
}165
int bcm_lev(u32_t pin) {166
int idx = BCM_LEV0 + __bcm_bank(pin);167
return (reg[idx] & (1 << (pin & 0x1F))) != 0;168
}170
void bcm_pud(u32_t pin, bcm_pud_e pud) {171
reg[BCM_PUD] = pud;172
usleep(20);173
reg[BCM_PUDCLK0 + __bcm_bank(pin)] = (1 << (pin & 0x1F));174
usleep(20);175
reg[BCM_PUD] = PUD_OFF;176
reg[BCM_PUDCLK0 + __bcm_bank(pin)] = 0x00;177
}179
void bcm_write(u32_t pin, int level) {180
level == HIGH181
? bcm_set(pin)182
: bcm_clr(pin);183
}185
int bcm_read(u32_t pin) {186
return bcm_lev(pin);187
}189
void bcm_pulse(u32_t pin, int level, u32_t sleep) {190
level == HIGH191
? bcm_set(pin)192
: bcm_clr(pin);193
usleep(sleep);194
level != HIGH195
? bcm_set(pin)196
: bcm_clr(pin);197
}199
#endif /* LIB_BCM2835_IMPL */200
#endif /* LIB_BCM2835_H */