From e7726a4f0aee36d75ba2ff10a8819c19b60b8af5 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 14 Apr 2024 11:51:38 +0200 Subject: [PATCH 1/2] #221 --- gpio/gpio.c | 18 +++++++++++---- wiringPi/wiringPi.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-- wiringPi/wiringPi.h | 1 + 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 36d1fc1..8754f12 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1377,10 +1377,20 @@ static void doVersion (char *argv []) } } - if (wiringPiUserLevelAccess()) // User level GPIO is GO - printf (" * This Raspberry Pi supports user-level GPIO access.\n") ; - else - printf (" * Root or sudo required for GPIO access.\n") ; + int bGlobalAccess = wiringPiGlobalMemoryAccess(); // User level GPIO is GO + switch(bGlobalAccess) { + case 1: + printf (" * This system supports basic user-level GPIO access via /dev/mem.\n") ; + break; + case 2: + printf (" * This system supports full user-level GPIO access via /dev/mem.\n") ; + break; + } + if (wiringPiUserLevelAccess()) { + printf (" * This system supports basic user-level GPIO access via /dev/gpiomem.\n") ; + } else if(0==bGlobalAccess) { + printf (" * This system may require root or sudo for GPIO access.\n") ; + } } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 5c6a0f6..b3d8b43 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2522,6 +2522,10 @@ int wiringPiUserLevelAccess(void) struct stat statBuf ; const char* gpiomemModule = gpiomem_BCM; + if (RaspberryPiModel<0) { //need to detect pi model + int model, rev, mem, maker, overVolted ; + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + } if (PI_MODEL_5 == RaspberryPiModel) { gpiomemModule = gpiomem_RP1; } @@ -2530,6 +2534,61 @@ int wiringPiUserLevelAccess(void) } +int wiringPiGlobalMemoryAccess(void) +{ + const char* gpiomemGlobal; + int fd=-1; + unsigned int MMAP_size; + unsigned int BaseAddr, PWMAddr; + + if (RaspberryPiModel<0) { //need to detect pi model + int model, rev, mem, maker, overVolted ; + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + } + if (PI_MODEL_5 == RaspberryPiModel) { + gpiomemGlobal = pciemem_RP1; + MMAP_size = pciemem_RP1_Size; + BaseAddr = (RP1_IO0_Addr-RP1_BASE_Addr) ; + PWMAddr = RP1_PWM0_Addr-RP1_BASE_Addr; + } else { + gpiomemGlobal = gpiomem_global; + MMAP_size = BLOCK_SIZE; + BaseAddr = piGpioBase + 0x00200000 ; + PWMAddr = piGpioBase + 0x0020C000 ; + } + + if ((fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) >0) { + int returnvalue = 1; // OK + + uint32_t * lgpio = (uint32_t *)mmap(0, MMAP_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, BaseAddr) ; + if (lgpio == MAP_FAILED) { + returnvalue = 0; + if (wiringPiDebug) + fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (GPIO) failed: %s\n", strerror (errno)) ; + } else { + munmap(lgpio, MMAP_size); + if (PI_MODEL_5 == RaspberryPiModel) { + returnvalue = 2; // GPIO & PWM accessible (same area, nothing to mmap) + } else { + //check PWM area + uint32_t* lpwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PWMAddr) ; + if (lpwm == MAP_FAILED) { + returnvalue = 1; // only GPIO accessible + if (wiringPiDebug) + fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (PWM) failed: %s\n", strerror (errno)) ; + } else { + returnvalue = 2; // GPIO & PWM accessible + munmap(lpwm, BLOCK_SIZE); + } + } + } + + close(fd); + return returnvalue; + } + return 0; // Failed! +} + /* * wiringPiSetup: * Must be called once at the start of your program execution. @@ -2633,9 +2692,12 @@ int wiringPiSetup (void) gpiomemModule = gpiomem_RP1; } + usingGpioMem = FALSE; if (gpiomemGlobal==NULL || (fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) < 0) { - + if (wiringPiDebug) { + printf ("wiringPi: no access to %s try %s\n", gpiomemGlobal, gpiomemModule) ; + } if (gpiomemModule && (fd = open (gpiomemModule, O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem { piGpioBase = 0 ; @@ -2648,7 +2710,7 @@ int wiringPiSetup (void) " Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ; } if (wiringPiDebug) { - printf ("wiringPi: access to %s succeded\n", usingGpioMem ? gpiomemModule : gpiomemGlobal) ; + printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ; } // GPIO: if (PI_MODEL_5 != model) { diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index d6ee11a..3f19ee8 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -208,6 +208,7 @@ extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; extern int GPIOToSysFS(const int pin) ; extern void wiringPiVersion (int *major, int *minor) ; +extern int wiringPiGlobalMemoryAccess(void); //Interface 3.3 extern int wiringPiUserLevelAccess (void) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; From 34b0f368a789c9a8b1496b1f1b9a1a38b2c2bfe0 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Mon, 15 Apr 2024 12:49:38 +0200 Subject: [PATCH 2/2] #221 --- gpio/gpio.c | 28 +++++++++++++++++----------- wiringPi/wiringPi.c | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 8754f12..1e7ec59 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1358,38 +1358,44 @@ static void doVersion (char *argv []) printf ("\n") ; piBoardId (&model, &rev, &mem, &maker, &warranty) ; - printf ("Raspberry Pi Details:\n") ; + printf ("Hardware details:\n") ; printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; // Check for device tree - - if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... - printf (" * Device tree is enabled.\n") ; - + printf ("System details:\n") ; + if (stat ("/proc/device-tree", &statBuf) == 0) { // We're on a devtree system ... + printf (" * Device tree present.\n") ; + } if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type { if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) { fgets (name, 80, fd) ; fclose (fd) ; - printf (" *--> %s\n", name) ; + printf (" Model: %s\n", name) ; } } int bGlobalAccess = wiringPiGlobalMemoryAccess(); // User level GPIO is GO switch(bGlobalAccess) { + case 0: + printf (" * Does not support basic user-level GPIO access via memory.\n") ; + break; case 1: - printf (" * This system supports basic user-level GPIO access via /dev/mem.\n") ; + printf (" * Supports basic user-level GPIO access via /dev/mem.\n") ; break; case 2: - printf (" * This system supports full user-level GPIO access via /dev/mem.\n") ; + printf (" * Supports full user-level GPIO access via memory.\n") ; break; } if (wiringPiUserLevelAccess()) { - printf (" * This system supports basic user-level GPIO access via /dev/gpiomem.\n") ; - } else if(0==bGlobalAccess) { - printf (" * This system may require root or sudo for GPIO access.\n") ; + printf (" * Supports basic user-level GPIO access via /dev/gpiomem.\n") ; + } else { + printf (" * Does not support basic user-level GPIO access via /dev/gpiomem.\n") ; + if(0==bGlobalAccess) { + printf (" * root or sudo may be required for GPIO access.\n") ; + } } } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index b3d8b43..7f685b9 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2548,8 +2548,8 @@ int wiringPiGlobalMemoryAccess(void) if (PI_MODEL_5 == RaspberryPiModel) { gpiomemGlobal = pciemem_RP1; MMAP_size = pciemem_RP1_Size; - BaseAddr = (RP1_IO0_Addr-RP1_BASE_Addr) ; - PWMAddr = RP1_PWM0_Addr-RP1_BASE_Addr; + BaseAddr = 0x00000000; + PWMAddr = 0x00000000; //not supported so far } else { gpiomemGlobal = gpiomem_global; MMAP_size = BLOCK_SIZE;