commit 4068f5468d8eb1a972b060aa2948c6ab63eb7e04
Author: typable <contact@typable.dev>
Date: Mon, 10 Jun 2024 11:40:37 +0200
Initial commit
Diffstat:
A | Makefile | | | 18 | ++++++++++++++++++ |
A | README.md | | | 3 | +++ |
A | src/libbcm2835.c | | | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/libbcm2835.h | | | 121 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 219 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,18 @@
+default: build
+
+build:
+ cc -o libbcm2835.so -shared -fPIC -Wall -Wextra -Werror -pedantic src/libbcm2835.c
+
+install:
+ cc -o libbcm2835.so -shared -fPIC src/libbcm2835.c
+ sudo cp src/libbcm2835.h /usr/local/include/libbcm2835.h
+ sudo cp libbcm2835.so /usr/local/lib/libbcm2835.so
+ sudo ldconfig
+ rm libbcm2835.so
+
+uninstall:
+ sudo rm /usr/local/include/libbcm2835.h
+ sudo rm /usr/local/lib/libbcm2835.so
+
+clean:
+ rm libbcm2835.so
diff --git a/README.md b/README.md
@@ -0,0 +1,3 @@
+# libbcm2835
+
+A tiny library for the BCM2835
diff --git a/src/libbcm2835.c b/src/libbcm2835.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "libbcm2835.h"
+
+static volatile u32_t *reg = MAP_FAILED;
+
+u32_t __bcm_bank(u32_t pin) {
+ return (pin >> 5);
+}
+
+int bcm_init(void) {
+ int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
+ if (fd < 0) {
+ fprintf(stderr, "Failed to open() /dev/gpiomem!\n");
+ return -1;
+ }
+ reg = (u32_t *) mmap(NULL, 0xB4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ close(fd);
+ if (reg == MAP_FAILED) {
+ fprintf(stderr, "Bad, mmap() failed!\n");
+ return -1;
+ }
+ return 0;
+}
+
+void bcm_fsel(u32_t pin, bcm_fsel_e fsel) {
+ int idx = BCM_FSEL0 + (pin / 10);
+ int shift = 3 * (pin % 10);
+ reg[idx] = (reg[idx] & ~(7 << shift)) | (fsel << shift);
+}
+
+void bcm_set(u32_t pin) {
+ int idx = BCM_SET0 + __bcm_bank(pin);
+ reg[idx] = (1 << (pin & 0x1F));
+}
+
+void bcm_clr(u32_t pin) {
+ int idx = BCM_CLR0 + __bcm_bank(pin);
+ reg[idx] = (1 << (pin & 0x1F));
+}
+
+int bcm_lev(u32_t pin) {
+ int idx = BCM_LEV0 + __bcm_bank(pin);
+ return (reg[idx] & (1 << (pin & 0x1F))) != 0;
+}
+
+void bcm_pud(u32_t pin, bcm_pud_e pud) {
+ reg[BCM_PUD] = pud;
+ usleep(20);
+ reg[BCM_PUDCLK0 + __bcm_bank(pin)] = (1 << (pin & 0x1F));
+ usleep(20);
+ reg[BCM_PUD] = PUD_OFF;
+ reg[BCM_PUDCLK0 + __bcm_bank(pin)] = 0x00;
+}
+
+void bcm_write(u32_t pin, int level) {
+ level == HIGH
+ ? bcm_set(pin)
+ : bcm_clr(pin);
+}
+
+int bcm_read(u32_t pin) {
+ return bcm_lev(pin);
+}
+
+void bcm_pulse(u32_t pin, int level, u32_t sleep) {
+ level == HIGH
+ ? bcm_set(pin)
+ : bcm_clr(pin);
+ usleep(sleep);
+ level != HIGH
+ ? bcm_set(pin)
+ : bcm_clr(pin);
+}
diff --git a/src/libbcm2835.h b/src/libbcm2835.h
@@ -0,0 +1,121 @@
+/*
+BCM2835 ARM Peripherals
+
+Datasheet:
+https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
+
+
+ 3V3 Power *---[ 01 | 02 ]---* 5V Power
+ GPIO2 (SDA) *---[ 03 | 04 ]---* 5V Power
+ GPIO3 (SCL) *---[ 05 | 06 ]---* Ground
+ GPIO4 (GPCLK0) *---[ 07 | 08 ]---* GPIO14 (TXD)
+ Ground *---[ 09 | 10 ]---* GPIO15 (RXD)
+ GPIO17 *---[ 11 | 12 ]---* GPIO18 (PCM_CLK)
+ GPIO27 *---[ 13 | 14 ]---* Ground
+ GPIO22 *---[ 15 | 16 ]---* GPIO23
+ 3V3 Power *---[ 17 | 18 ]---* GPIO24
+ GPIO10 (MOSI) *---[ 19 | 20 ]---* Ground
+ GPIO9 (MISO) *---[ 21 | 22 ]---* GPIO25
+ GPIO11 (SCLK) *---[ 23 | 24 ]---* GPIO8 (CE0)
+ Ground *---[ 25 | 26 ]---* GPIO7 (CE1)
+ GPIO0 (ID_SD) *---[ 27 | 28 ]---* GPIO1 (ID_SC)
+ GPIO5 *---[ 29 | 30 ]---* Ground
+ GPIO6 *---[ 31 | 32 ]---* GPIO12 (PWM0)
+ GPIO13 (PWM1) *---[ 33 | 34 ]---* Ground
+GPIO19 (PCM_FS) *---[ 35 | 36 ]---* GPIO16
+ GPIO26 *---[ 37 | 38 ]---* GPIO20 (PCM_DIN)
+ Ground *---[ 39 | 40 ]---* GPIO21 (PCM_DOUT)
+
+
+gpiochip0 - 54 lines:
+
+--------------------- --------------------- ---------------------
+line 00: ID_SDA line 18: GPIO18 line 36: SD1_DATA0
+line 01: ID_SCL line 19: GPIO19 line 37: SD1_DATA1
+line 02: GPIO2 line 20: GPIO20 line 38: SD1_DATA2
+line 03: GPIO3 line 21: GPIO21 line 39: SD1_DATA3
+line 04: GPIO4 line 22: GPIO22 line 40: PWM0_OUT
+line 05: GPIO5 line 23: GPIO23 line 41: PWM1_OUT
+line 06: GPIO6 line 24: GPIO24 line 42: ETH_CLK
+line 07: GPIO7 line 25: GPIO25 line 43: WIFI_CLK
+line 08: GPIO8 line 26: GPIO26 line 44: SDA0
+line 09: GPIO9 line 27: GPIO27 line 45: SCL0
+line 10: GPIO10 line 28: NC line 46: SMPS_SCL
+line 11: GPIO11 line 29: LAN_RUN_BOOT line 47: SMPS_SDA
+line 12: GPIO12 line 30: CTS0 line 48: SD_CLK_R
+line 13: GPIO13 line 31: RTS0 line 49: SD_CMD_R
+line 14: GPIO14 line 32: TXD0 line 50: SD_DATA0_R
+line 15: GPIO15 line 33: RXD0 line 51: SD_DATA1_R
+line 16: GPIO16 line 34: SD1_CLK line 52: SD_DATA2_R
+line 17: GPIO17 line 35: SD1_CMD line 53: SD_DATA3_R
+--------------------- --------------------- ---------------------
+*/
+
+#ifndef BCM_2835_H
+#define BCM_2835_H
+
+#define BCM_FSEL0 0
+#define BCM_FSEL1 1
+#define BCM_FSEL2 2
+#define BCM_FSEL3 3
+#define BCM_FSEL4 4
+#define BCM_FSEL5 5
+#define BCM_SET0 7
+#define BCM_SET1 8
+#define BCM_CLR0 10
+#define BCM_CLR1 11
+#define BCM_LEV0 13
+#define BCM_LEV1 14
+#define BCM_EDS0 16
+#define BCM_EDS1 17
+#define BCM_REN0 19
+#define BCM_REN1 20
+#define BCM_FEN0 22
+#define BCM_FEN1 23
+#define BCM_HEN0 25
+#define BCM_HEN1 26
+#define BCM_LEN0 28
+#define BCM_LEN1 29
+#define BCM_AREN0 31
+#define BCM_AREN1 32
+#define BCM_AFEN0 34
+#define BCM_AFEN1 35
+#define BCM_PUD 37
+#define BCM_PUDCLK0 38
+#define BCM_PUDCLK1 39
+
+#define LOW 0
+#define HIGH 1
+
+typedef unsigned char u8_t;
+typedef unsigned int u32_t;
+
+typedef enum {
+ FSEL_IN = 0x00,
+ FSEL_OUT = 0x01,
+ FSEL_ALT0 = 0x04,
+ FSEL_ALT1 = 0x05,
+ FSEL_ALT2 = 0x06,
+ FSEL_ALT3 = 0x07,
+ FSEL_ALT4 = 0x03,
+ FSEL_ALT5 = 0x02,
+} bcm_fsel_e;
+
+typedef enum {
+ PUD_OFF = 0x00,
+ PUD_DOWN = 0x01,
+ PUD_UP = 0x02,
+} bcm_pud_e;
+
+int bcm_init(void);
+void bcm_fsel(u32_t pin, bcm_fsel_e fsel);
+void bcm_set(u32_t pin);
+void bcm_clr(u32_t pin);
+int bcm_lev(u32_t pin);
+void bcm_pud(u32_t pin, bcm_pud_e pud);
+
+void bcm_write(u32_t pin, int level);
+int bcm_read(u32_t pin);
+void bcm_pulse(u32_t pin, int level, u32_t sleep);
+
+#endif