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) ;