It was a minor change to my Pi revision code to get processor and thus determine correct gpiochip which I include for the benefit of others encountering problems.
The code to determine gpiochip is independent of any other libraries so could easily be included in any program requiring it.
Below I have listed c & python versions of my revision code and examples of a modification to a couple of simple lgpio examples
#! /usr/bin/env python3
"""
Raspberry Pi Processor & Type
"""
import sys
# 2024-07-13
def get_revision():
"""
Returns Raspberry Pi Revision Code
"""
with open("/proc/device-tree/system/linux,revision", "rb") as fp:
return int.from_bytes(fp.read(4), 'big')
def processor():
"""
Raspberry Pi SOC
returns
0: BCM2835
1: BCM2836
2: BCM2837
3: BCM2711
4: BCM2712
"""
return int((get_revision()>>12)&7)
def type():
"""
Raspberry Pi Type
returns
0: A
1: B
2: A+
3: B+
4: 2B
6: CM1
8: 3B
9: Zero
a: CM3
c: Zero W
d: 3B+
e: 3A+
10: CM3+
11: 4B
12: Zero 2 W
13: 400
14: CM4
15: CM4S
17: 5
"""
return int((get_revision()>>4)&0xff)
def main():
print(f"{get_revision():08x}")
print(f"{processor()}")
print(f"{type():02x}")
if name == 'main':
main()
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
// Raspberry Pi Revision, Processor & Type
// 2024-07-13
unsigned get_revision(void) {
FILE *fp;
uint32_t n = 0;
if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
if (fread(&n, sizeof(n), 1, fp) != 1) {
fclose(fp);
return 0;
}
}
fclose(fp);
return ntohl(n);
}
unsigned processor(void) {
return (get_revision()>>12)&7;
}
unsigned type(void) {
return (get_revision()>>4)&0xff;
}
int main(int argc, char *argv[]) {
printf("Version =\t%08x\n", get_revision());
printf("Processor =\t%d\n", processor());
printf("Type =\t\t%02x\n", type());
return 0;
}
#! /usr/bin/env python3
"""
This program toggles a GPIO pin and measures rate.
Using lgpio Python Interface
"""
# 2024-04-02
# 2024-04-24 commas in number
# 2024-07-13 modified for Pi5/BCBM2712
import lgpio
import time
gpiochip = 0
SigOUT = 12
LOOPS = 20000
def get_revision():
"""
Returns Raspberry Pi Revision Code
"""
with open("/proc/device-tree/system/linux,revision", "rb") as fp:
return int.from_bytes(fp.read(4), 'big')
def processor():
"""
Raspberry Pi SOC
returns
0: BCM2835
1: BCM2836
2: BCM2837
3: BCM2711
4: BCM2712
"""
return int((get_revision()>>12)&7)
if(processor()==4):
gpiochip = 4
h = lgpio.gpiochip_open(gpiochip)
if h < 0:
print('open error')
lgpio.gpio_claim_output(h, SigOUT)
t0 = time.time()
for i in range(LOOPS):
lgpio.gpio_write(h, SigOUT, 1)
lgpio.gpio_write(h, SigOUT, 0)
t1 = time.time()
nloops = (1.0 * LOOPS) / (t1 - t0)
print(f"lgpio Python\t{nloops:10,.0f} toggles per second")
lgpio.gpio_free(h, SigOUT)
/*
bench.c
This program toggles a GPIO pin and measures rate.
Using lgpio C API
gcc -Wall -o bench-lgpio bench-lgpio.c -llgpio
*/
// 2024-04-24 commas in number
// 2024-07-13 Support for Pi5
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <lgpio.h>
#define LFLAGS 0
#define SigOUT 12
#define LOOPS 20000
unsigned get_revision(void) {
FILE *fp;
uint32_t n = 0;
if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
if (fread(&n, sizeof(n), 1, fp) != 1) {
fclose(fp);
return 0;
}
}
fclose(fp);
return ntohl(n);
}
unsigned processor(void) {
return (get_revision()>>12)&7;
}
int main(int argc, char *argv[]) {
int h;
int i;
double t0, t1;
int status;
if(processor()==4)
h = lgGpiochipOpen(4);
else
h = lgGpiochipOpen(0);
if (h >= 0) {
if ((status = lgGpioClaimOutput(h, LFLAGS, SigOUT, 0)) == LG_OKAY) {
t0 = lguTime();
for (i = 0; i < LOOPS; i++) {
lgGpioWrite(h, SigOUT, 0);
lgGpioWrite(h, SigOUT, 1);
}
t1 = lguTime();
int nloops = (1.0 * LOOPS) / (t1 - t0);
setlocale(LC_ALL,"");
printf("lgpio\tC\t%'10d toggles per second\n", nloops);
} else {
printf("lgGpioClaimSigOUTput FAILED on Pin %d\n", SigOUT);
lgLineInfo_t lInfo;
status = lgGpioGetLineInfo(h, SigOUT, &lInfo);
if (status == LG_OKAY) {
if (lInfo.lFlags & 1) {
printf("GPIO in use by the kernel ");
printf("name=%s user=%s\n", lInfo.name, lInfo.user);
}
}
}
lgGpioFree(h, SigOUT);
lgGpiochipClose(h);
} else
printf("Unable to open gpiochip 0\n");
}