From 19874871deba9b5387f0c38f8c9d3e65601da45b Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Jan 2024 16:33:04 +0100 Subject: [PATCH 01/15] #16 --- gpio/gpio.c | 70 ++++++++++++++++++++++++++++++++++------------------- wiringPi/wiringPi.c | 63 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 99 insertions(+), 34 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 46b36df..378e24f 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -88,6 +88,15 @@ char *usage = "Usage: gpio -v\n" " gpio gbw " ; // No trailing newline needed here. +int GPIOToSysFS_ExitonFail (const int pin) { + int pinFS = GPIOToSysFS(pin); + if (pinFS<0) { + fprintf (stderr, "%s: invalid sysfs pin of bcm pin %d\n", argv [0], pin) ; + exit (1) ; + } + return pinFS; +} + #ifdef NOT_FOR_NOW /* * decodePin: @@ -391,16 +400,19 @@ static void doI2Cdetect (UNU int argc, char *argv []) static void doExports (UNU int argc, UNU char *argv []) { int fd ; - int i, l, first ; + int pin, l, first ; char fName [128] ; char buf [16] ; - for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective + for (first = 0, pin = 0 ; pin < 64 ; ++pin) // Crude, but effective { // Try to read the direction - - sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ; + int pinFS = GPIOToSysFS(pin); + if (pinFS<0) { + continue; + } + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; if ((fd = open (fName, O_RDONLY)) == -1) continue ; @@ -410,7 +422,11 @@ static void doExports (UNU int argc, UNU char *argv []) printf ("GPIO Pins exported:\n") ; } - printf ("%4d: ", i) ; + if(pinFS==pin) { + printf ("%4d: ", pin) ; + } else { + printf ("%4d (%4d): ", pin, pinFS) ; + } if ((l = read (fd, buf, 16)) == 0) sprintf (buf, "%s", "?") ; @@ -425,7 +441,7 @@ static void doExports (UNU int argc, UNU char *argv []) // Try to Read the value - sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ; + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; if ((fd = open (fName, O_RDONLY)) == -1) { printf ("No Value file (huh?)\n") ; @@ -443,7 +459,7 @@ static void doExports (UNU int argc, UNU char *argv []) // Read any edge trigger file - sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; if ((fd = open (fName, O_RDONLY)) == -1) { printf ("\n") ; @@ -485,7 +501,7 @@ void doExport (int argc, char *argv []) } pin = atoi (argv [2]) ; - + int pinFS = GPIOToSysFS_ExitonFail(pin); mode = argv [3] ; if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) @@ -494,10 +510,9 @@ void doExport (int argc, char *argv []) exit (1) ; } - fprintf (fd, "%d\n", pin) ; + fprintf (fd, "%d\n", pinFS) ; fclose (fd) ; - - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -522,10 +537,10 @@ void doExport (int argc, char *argv []) // Change ownership so the current user can actually use it - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; changeOwner (argv [0], fName) ; - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; changeOwner (argv [0], fName) ; } @@ -599,6 +614,7 @@ void doEdge (int argc, char *argv []) } pin = atoi (argv [2]) ; + int pinFS = GPIOToSysFS_ExitonFail(pin); mode = argv [3] ; // Export the pin and set direction to input @@ -609,10 +625,10 @@ void doEdge (int argc, char *argv []) exit (1) ; } - fprintf (fd, "%d\n", pin) ; + fprintf (fd, "%d\n", pinFS) ; fclose (fd) ; - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ; if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -622,7 +638,7 @@ void doEdge (int argc, char *argv []) fprintf (fd, "in\n") ; fclose (fd) ; - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -641,10 +657,10 @@ void doEdge (int argc, char *argv []) // Change ownership of the value and edge files, so the current user can actually use it! - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; changeOwner (argv [0], fName) ; - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ; changeOwner (argv [0], fName) ; fclose (fd) ; @@ -670,6 +686,7 @@ void doUnexport (int argc, char *argv []) } pin = atoi (argv [2]) ; + int pinFS = GPIOToSysFS_ExitonFail(pin); if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) { @@ -677,7 +694,7 @@ void doUnexport (int argc, char *argv []) exit (1) ; } - fprintf (fd, "%d\n", pin) ; + fprintf (fd, "%d\n", pinFS) ; fclose (fd) ; } @@ -697,13 +714,16 @@ void doUnexportall (char *progName) for (pin = 0 ; pin < 63 ; ++pin) { - if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) - { - fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; - exit (1) ; + int pinFS = GPIOToSysFS(pin); + if (pinFS>=0) { + if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; + exit (1) ; + } + fprintf (fd, "%d\n", pinFS) ; + fclose (fd) ; } - fprintf (fd, "%d\n", pin) ; - fclose (fd) ; } } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 7e59b0d..bc9b01c 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -464,7 +464,53 @@ static int physToGpioR2 [64] = -1, -1, } ; +const int _5v=-1; +const int _0v=-1; +const int _3v=-1; + + +static int physToSysGPIOPi5 [41] = +{ + -1, // 0 + _3v, _5v, // 1, 2 + 401, _5v, + 402, _0v, + 403, 413, + _0v, 414, + 416, 417, + 426, _0v, + 421, 422, + _3v, 423, + 409, _0v, + 408, 424, + 410, 407, + _0v, 406, + 399, 400, + 404, _0v, + 405, 411, + 412, _0v, + 418, 415, + 425, 419, + _0v, 420, //39, 40 +} ; + +static int GPIOToSysFS(const int pin) { + int sysfspin = pin; + 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) { + sysfspin = pin + 399; + if (pin>426) { // only 399-426 supported + sysfspin = -1; + } + } + if (wiringPiDebug) + printf ("GPIOToSysFS: translate bcm gpio %d to sysfs gpio %d\n", pin, sysfspin) ; + return sysfspin; +} // gpioToGPFSEL: // Map a BCM_GPIO pin to it's Function Selection @@ -2075,8 +2121,9 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) if (sysFds [bcmGpioPin] == -1) { - sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; - if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) + pinFS = GPIOToSysFS(bcmGpioPin); + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; + if (pinFS>=0 && (sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; } @@ -2525,18 +2572,16 @@ int wiringPiSetupSys (void) physToGpio = physToGpioR2 ; } - if (PI_MODEL_5 == model) { - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Raspberry Pi 5 not supported.\n" - " Unable to continue. Keep an eye of new version at https://github.com/GrazerComputerClub/WiringPi\n") ; - } - // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later for (pin = 0 ; pin < 64 ; ++pin) { - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - sysFds [pin] = open (fName, O_RDWR) ; + pinFS = GPIOToSysFS(pin); + if (pinFS>=0) { + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; + sysFds [pin] = open (fName, O_RDWR) ; + } } initialiseEpoch () ; From eae109e6f8dc5a322d5b9c35d6cbed9f30c20711 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Jan 2024 16:36:03 +0100 Subject: [PATCH 02/15] #16 --- wiringPi/wiringPi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index bc9b01c..a902083 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2121,7 +2121,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) if (sysFds [bcmGpioPin] == -1) { - pinFS = GPIOToSysFS(bcmGpioPin); + int pinFS = GPIOToSysFS(bcmGpioPin); sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; if (pinFS>=0 && (sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; @@ -2577,7 +2577,7 @@ int wiringPiSetupSys (void) for (pin = 0 ; pin < 64 ; ++pin) { - pinFS = GPIOToSysFS(pin); + int pinFS = GPIOToSysFS(pin); if (pinFS>=0) { sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ; sysFds [pin] = open (fName, O_RDWR) ; From d1df517fa3723b4f397b57cf14ffc52bafa844d5 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Jan 2024 16:38:26 +0100 Subject: [PATCH 03/15] #16 --- gpio/gpio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index 378e24f..a4574a1 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -88,10 +88,10 @@ char *usage = "Usage: gpio -v\n" " gpio gbw " ; // No trailing newline needed here. -int GPIOToSysFS_ExitonFail (const int pin) { +int GPIOToSysFS_ExitonFail (const int pin, const char* name) { int pinFS = GPIOToSysFS(pin); if (pinFS<0) { - fprintf (stderr, "%s: invalid sysfs pin of bcm pin %d\n", argv [0], pin) ; + fprintf (stderr, "%s: invalid sysfs pin of bcm pin %d\n", name, pin) ; exit (1) ; } return pinFS; @@ -501,7 +501,7 @@ void doExport (int argc, char *argv []) } pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin); + int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); mode = argv [3] ; if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) @@ -614,7 +614,7 @@ void doEdge (int argc, char *argv []) } pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin); + int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); mode = argv [3] ; // Export the pin and set direction to input @@ -686,7 +686,7 @@ void doUnexport (int argc, char *argv []) } pin = atoi (argv [2]) ; - int pinFS = GPIOToSysFS_ExitonFail(pin); + int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]); if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) { From bde772c4b01927fbb78b1daecce72999bd8aaccf Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Jan 2024 16:41:46 +0100 Subject: [PATCH 04/15] #16 --- wiringPi/wiringPi.c | 2 +- wiringPi/wiringPi.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index a902083..25c957c 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -494,7 +494,7 @@ static int physToSysGPIOPi5 [41] = _0v, 420, //39, 40 } ; -static int GPIOToSysFS(const int pin) { +int GPIOToSysFS(const int pin) { int sysfspin = pin; if (RaspberryPiModel<0) { //need to detect pi model int model, rev, mem, maker, overVolted ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index ff088ca..0f5cd1c 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -203,6 +203,8 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; +extern int GPIOToSysFS(const int pin) ; + extern void wiringPiVersion (int *major, int *minor) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; From 888d88ef6e1806d500ab1293d88f31276638f21a Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sat, 27 Jan 2024 19:24:43 +0100 Subject: [PATCH 05/15] #16 --- wiringPi/wiringPi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 25c957c..5fec7c2 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -502,7 +502,7 @@ int GPIOToSysFS(const int pin) { } if (PI_MODEL_5 == RaspberryPiModel) { sysfspin = pin + 399; - if (pin>426) { // only 399-426 supported + if (sysfspin<399 || sysfspin>426) { // only 399-426 supported, 40-pin GPIO header sysfspin = -1; } } From 3094b8daaa7b3f5c5e851d610cf37743ee5a9cf9 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 4 Feb 2024 14:09:54 +0100 Subject: [PATCH 06/15] Version 2.72 for Pi 5 sysfs support --- VERSION | 2 +- debian-template/wiringPi/DEBIAN/control | 2 +- version.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index b93b4f2..80bf4d0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.71 +2.72 diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control index 31697b8..40262ba 100644 --- a/debian-template/wiringPi/DEBIAN/control +++ b/debian-template/wiringPi/DEBIAN/control @@ -1,5 +1,5 @@ Package: wiringpi -Version: 2.71 +Version: 2.72 Section: libraries Priority: optional Architecture: armhf diff --git a/version.h b/version.h index e54f1d3..d2d73a4 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "2.71" +#define VERSION "2.72" #define VERSION_MAJOR 2 -#define VERSION_MINOR 71 +#define VERSION_MINOR 72 From 76fb93fb43da5326bf58cc8d74140569c9e58e9d Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 11 Feb 2024 14:10:22 +0100 Subject: [PATCH 07/15] #17 --- wiringPi/wiringPi.c | 311 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 228 insertions(+), 83 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 5fec7c2..6b99cc4 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -123,6 +123,42 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; #define FSEL_ALT4 0b011 #define FSEL_ALT5 0b010 +//RP1 chip (@Pi5) - 3.1.1. Function select +#define RP1_FSEL_ALT0 0x00 +#define RP1_FSEL_GPIO 0x05 //SYS_RIO +#define RP1_FSEL_NONE 0x09 +#define RP1_FSEL_NONE_HW 0x1f //default, mask + +//RP1 chip (@Pi5) RIO address +const unsigned int RP1_RIO_OUT = 0x0000; +const unsigned int RP1_RIO_OE = (0x0004/4); +const unsigned int RP1_RIO_IN = (0x0008/4); + +//RP1 chip (@Pi5) RIO offset for set/clear value +const unsigned int RP1_SET_OFFSET = (0x2000/4): +const unsigned int RP1_CLR_OFFSET = (0x3000/4); + +//RP1 chip (@Pi5) PDE/PDU pull-up/-down enable +const unsigned int RP1_PUD_UP = (1<<3); +const unsigned int RP1_PUD_DOWN = (1<<2); +const unsigned int RP1_INV_PUD_MASK = ~(RP1_PUD_UP | RP1_PUD_DOWN); //~0x0C + +//RP1 chip (@Pi5) pin level, status register +const unsigned int RP1_STATUS_LEVEL_LOW = 0x00400000; +const unsigned int RP1_STATUS_LEVEL_HIGH = 0x00800000; +const unsigned int RP1_STATUS_LEVEL_MASK = 0x00C00000; + +const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4; +const unsigned int RP1_DEBOUNCE_MASK = 0x7f; +const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5); + +//RP1 chip (@Pi5) address +const unsigned long long RP1_BASE_Addr = 0x1f000d0000; +const unsigned int RP1_IO0_Addr = 0x400d0000; +const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000; +const unsigned int RP1_PADS0_Addr = 0x400f0000; + + // Access from ARM Running Linux // Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: @@ -130,6 +166,11 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // Updates in September 2015 - all now static variables (and apologies for the caps) // due to the Pi v2, v3, etc. and the new /dev/gpiomem interface +const char* gpiomem_global = "/dev/mem"; +const char* gpiomem_BCM = "/dev/gpiomem" +const char* gpiomem_RP1 = "/dev/gpiomem0"; +const int gpiomem_RP1_Size = 0x00030000; + static volatile unsigned int GPIO_PADS ; static volatile unsigned int GPIO_CLOCK_BASE ; static volatile unsigned int GPIO_BASE ; @@ -194,6 +235,7 @@ static volatile unsigned int *clk ; static volatile unsigned int *pads ; static volatile unsigned int *timer ; static volatile unsigned int *timerIrqRaw ; +static volatile unsigned int *rio ; // Export variables for the hardware pointers @@ -203,7 +245,7 @@ volatile unsigned int *_wiringPiClk ; volatile unsigned int *_wiringPiPads ; volatile unsigned int *_wiringPiTimer ; volatile unsigned int *_wiringPiTimerIrqRaw ; - +volatile unsigned int *_wiringPiRio ; // Data for use with the boardId functions. // The order of entries here to correspond with the PI_MODEL_X @@ -216,6 +258,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ; #define GPIO_PERI_BASE_OLD 0x20000000 #define GPIO_PERI_BASE_2835 0x3F000000 #define GPIO_PERI_BASE_2711 0xFE000000 +#define GPIO_PERI_BASE_2712 0x00 //unknown - 32-bit mapped global mem access not supported for now static volatile unsigned int piGpioBase = 0 ; @@ -512,6 +555,20 @@ int GPIOToSysFS(const int pin) { return sysfspin; } +int GetMaxPin() { + return PI_MODEL_5 == RaspberryPiModel ? 27 : 63; +} + + +#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } + +void FailOnModel5() { + if (PI_MODEL_5 == RaspberryPiModel) { + return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" + " Unable to continue. Keep an eye of new versions at https://github.com/GrazerComputerClub/WiringPi\n") ; + } +} + // gpioToGPFSEL: // Map a BCM_GPIO pin to it's Function Selection // control port. (GPFSEL 0-5) @@ -1191,6 +1248,7 @@ void setPadDrive (int group, int value) { uint32_t wrVal ; + RETURN_ON_MODEL5 if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if ((group < 0) || (group > 2)) @@ -1228,11 +1286,14 @@ int getAlt (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return 0 ; - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; - - alt = (*(gpio + fSel) >> shift) & 7 ; + if (PI_MODEL_5 == RaspberryPiModel) { + alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function, 5-11 debounce time + } else { + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + alt = (*(gpio + fSel) >> shift) & 7 ; + } return alt ; } @@ -1247,6 +1308,7 @@ void pwmSetMode (int mode) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { + FailOnModel5(); if (mode == PWM_MODE_MS) *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; else @@ -1284,6 +1346,7 @@ void pwmSetClock (int divisor) { uint32_t pwm_control ; + FailOnModel5(); if (piGpioBase == GPIO_PERI_BASE_2711) { divisor = 540*divisor/192; @@ -1335,6 +1398,7 @@ void gpioClockSet (int pin, int freq) { int divi, divr, divf ; + FailOnModel5(); pin &= 63 ; /**/ if (wiringPiMode == WPI_MODE_PINS) @@ -1466,6 +1530,7 @@ void pinModeAlt (int pin, int mode) { int fSel, shift ; + RETURN_ON_MODEL5 setupCheck ("pinModeAlt") ; if ((pin & PI_GPIO_MASK) == 0) // On-board pin @@ -1477,10 +1542,25 @@ void pinModeAlt (int pin, int mode) else if (wiringPiMode != WPI_MODE_GPIO) return ; - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; + if (PI_MODEL_5 == RaspberryPiModel) { + + //confusion! diffrent to to BCM! this is taking directly the value for the register + /* + "alt0" 0b100 + "alt1" 0b101 + "alt2" 0b110 + "alt3" 0b111 + "alt4" 0b011 + "alt5" 0b010 + */ + gpio[2*pin+1] = (mode & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time + } else { + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; + } - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; } } @@ -1514,21 +1594,30 @@ void pinMode (int pin, int mode) fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == SOFT_PWM_OUTPUT) + if (mode == INPUT) { + if (PI_MODEL_5 == RaspberryPiModel) { + rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<>4); - int pullshift = (pin & 0xf) << 1; - unsigned int pullbits; - unsigned int pull; - - switch (pud) - { - case PUD_OFF: pull = 0; break; - case PUD_UP: pull = 1; break; - case PUD_DOWN: pull = 2; break; + unsigned int pull; + if (PI_MODEL_5 == RaspberryPiModel) { + unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits + switch (pud){ + case PUD_OFF: break; + case PUD_UP: pads[1+pin] = pullbits | RP1_PUD_UP; break; //set bit + case PUD_DOWN: pads[1+pin] = pullbits | RP1_PUD_DOWN; break; default: return ; /* An illegal value */ } + } else { + if (piGpioPupOffset == GPPUPPDN0) + { + // Pi 4B pull up/down method + int pullreg = GPPUPPDN0 + (pin>>4); + int pullshift = (pin & 0xf) << 1; + unsigned int pullbits; + unsigned int pull; + + switch (pud) + { + case PUD_OFF: pull = 0; break; + case PUD_UP: pull = 1; break; + case PUD_DOWN: pull = 2; break; + default: return ; /* An illegal value */ + } + + pullbits = *(gpio + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio + pullreg) = pullbits; + } + else + { + // legacy pull up/down method + *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; - pullbits = *(gpio + pullreg); - pullbits &= ~(3 << pullshift); - pullbits |= (pull << pullshift); - *(gpio + pullreg) = pullbits; - } - else - { - // legacy pull up/down method - *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; - - *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + } } } else // Extension module @@ -1655,10 +1757,18 @@ int digitalRead (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return LOW ; - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; + if (PI_MODEL_5 == RaspberryPiModel) { + switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) { + default: // 11 or 00 not allowed, give LOW! + case RP1_STATUS_LEVEL_LOW: return LOW ; + case RP1_STATUS_LEVEL_HIGH: return HIGH ; + } + } else { + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) + return HIGH ; + else + return LOW ; + } } else { @@ -1704,12 +1814,12 @@ void digitalWrite (int pin, int value) { /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode { - if (sysFds [pin] != -1) + if (sysFds [pin] != -1) { - if (value == LOW) - write (sysFds [pin], "0\n", 2) ; - else - write (sysFds [pin], "1\n", 2) ; + if (value == LOW) + write (sysFds [pin], "0\n", 2) ; + else + write (sysFds [pin], "1\n", 2) ; } return ; } @@ -1719,11 +1829,20 @@ void digitalWrite (int pin, int value) pin = physToGpio [pin] ; else if (wiringPiMode != WPI_MODE_GPIO) return ; - - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; - else - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; + if (PI_MODEL_5 == RaspberryPiModel) { + if (value == LOW) + //printf("Set pin %d >>0x%08x<< to low\n", pin, 1<>0x%08x<< to high\n", pin, 1< 63)) - return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; + if (pin < 0 || pin > maxpin) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-%d (%d)\n", maxpin, pin) ; /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED) return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; @@ -2384,6 +2513,11 @@ int wiringPiSetup (void) piGpioPupOffset = GPPUPPDN0 ; break ; + case PI_MODEL_5: + piGpioBase = GPIO_PERI_BASE_2712 ; + piGpioPupOffset = 0 ; + break ; + default: piGpioBase = GPIO_PERI_BASE_2835 ; piGpioPupOffset = GPPUD ; @@ -2395,37 +2529,43 @@ int wiringPiSetup (void) // Try /dev/mem. If that fails, then // try /dev/gpiomem. If that fails then game over. + const char* gpiomemGlobal = gpiomem_global; + const char* gpiomemModule = gpiomem_BCM; + if (PI_MODEL_5 == model) { - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Raspberry Pi 5 not supported.\n" - " Unable to continue. Keep an eye of new versions at https://github.com/GrazerComputerClub/WiringPi\n") ; + gpiomemGlobal = NULL; // now supported as long as i don't know the RP1 32-bit mapped global address + gpiomemModule = gpiomem_RP1; } - if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) + if (gpiomemGlobal==NULL || (fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) < 0) { - if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem + + if (gpiomemModule && (fd = open (gpiomemModule, O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem { piGpioBase = 0 ; usingGpioMem = TRUE ; } else - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n" + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or %s: %s.\n" " Aborting your program because if it can not access the GPIO\n" " hardware then it most certianly won't work\n" - " Try running with sudo?\n", strerror (errno)) ; + " Try running with sudo?\n", gpiomemModule, strerror (errno)) ; } - //Set the offsets into the memory interface. +// GPIO: + if (PI_MODEL_5 != model) { + //Set the offsets into the memory interface. - GPIO_PADS = piGpioBase + 0x00100000 ; - GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ; - GPIO_BASE = piGpioBase + 0x00200000 ; - GPIO_TIMER = piGpioBase + 0x0000B000 ; - GPIO_PWM = piGpioBase + 0x0020C000 ; + GPIO_PADS = piGpioBase + 0x00100000 ; + GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ; + GPIO_BASE = piGpioBase + 0x00200000 ; + GPIO_TIMER = piGpioBase + 0x0000B000 ; + GPIO_PWM = piGpioBase + 0x0020C000 ; // Map the individual hardware components -// GPIO: - if (PI_MODEL_5 != model) { + // GPIO: + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; if (gpio == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; @@ -2462,23 +2602,29 @@ int wiringPiSetup (void) *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; + // Export the base addresses for any external software that might need them _wiringPiGpio = gpio ; _wiringPiPwm = pwm ; _wiringPiClk = clk ; _wiringPiPads = pads ; _wiringPiTimer = timer ; + _wiringPiRio = NULL ; } else { - _wiringPiGpio = NULL ; + //map hole RP1 memory block from beginning, gobal mem not supported + gpio = (unsigned int *)mmap(0, gpiomem_RP1_Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x00000000) ; + if (gpio == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + pads = &gpio[(RP1_PADS0_Addr-RP1_IO0_Addr)/4]; // Start adress of map memory for pads + rio = &gpio[(RP1_SYS_RIO0_Addr-RP1_IO0_Addr)/4]; // Start adress of map memory for rio + + // Export the base addresses for any external software that might need them + _wiringPiGpio = gpio ; _wiringPiPwm = NULL ; _wiringPiClk = NULL ; - _wiringPiPads = NULL ; + _wiringPiPads = pads ; _wiringPiTimer = NULL ; + _wiringPiRio = rio ; } - - -// Export the base addresses for any external software that might need them - - initialiseEpoch () ; @@ -2541,7 +2687,6 @@ int wiringPiSetupPhys (void) int wiringPiSetupSys (void) { - int pin ; char fName [128] ; if (wiringPiSetuped) @@ -2575,7 +2720,7 @@ int wiringPiSetupSys (void) // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later - for (pin = 0 ; pin < 64 ; ++pin) + for (int pin = 0, maxpin=GetMaxPin() ; pin <= maxpin ; ++pin) { int pinFS = GPIOToSysFS(pin); if (pinFS>=0) { From 6d0c68b75dbd5d1d0ceac6959837f833c277c839 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 11 Feb 2024 17:06:30 +0100 Subject: [PATCH 08/15] #17 --- gpio/readall.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gpio/readall.c b/gpio/readall.c index 932f8e1..bff8566 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -315,6 +315,8 @@ static void plus2header (int model) printf (" +-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+\n") ; else if (model == PI_MODEL_400) printf (" +-----+-----+---------+------+---+---Pi 400-+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_5) + printf (" +-----+-----+---------+------+---+---Pi 5---+---+------+---------+-----+-----+\n") ; else printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; } @@ -363,7 +365,8 @@ void doReadall (void) (model == PI_MODEL_3AP) || (model == PI_MODEL_3B) || (model == PI_MODEL_3BP) || (model == PI_MODEL_4B) || (model == PI_MODEL_400) || (model == PI_MODEL_CM4) || - (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W) || (model == PI_MODEL_ZERO_2W)) + (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W) || (model == PI_MODEL_ZERO_2W) || + (model == PI_MODEL_5) ) piPlusReadall (model) ; else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || (model == PI_MODEL_CM3P) ) allReadall () ; From af5baeac328a48e84b758596366878e77dbc60aa Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 11 Feb 2024 20:22:00 +0100 Subject: [PATCH 09/15] #17 --- VERSION | 2 +- debian-template/wiringPi/DEBIAN/control | 2 +- gpio/readall.c | 26 +++++++++++++++------ newVersion | 0 version.h | 4 ++-- wiringPi/wiringPi.c | 40 ++++++++++++++++++++++++++++----- 6 files changed, 57 insertions(+), 17 deletions(-) mode change 100644 => 100755 newVersion diff --git a/VERSION b/VERSION index 80bf4d0..21d5b2e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.72 +2.73 diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control index 40262ba..4797516 100644 --- a/debian-template/wiringPi/DEBIAN/control +++ b/debian-template/wiringPi/DEBIAN/control @@ -1,5 +1,5 @@ Package: wiringpi -Version: 2.72 +Version: 2.73 Section: libraries Priority: optional Architecture: armhf diff --git a/gpio/readall.c b/gpio/readall.c index bff8566..6da28b7 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -75,11 +75,23 @@ static void doReadallExternal (void) ********************************************************************************* */ -static char *alts [] = +static const char unknown_alt[] = " - "; +static const char *alts [] = { - "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" + "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3", "ALT6", "ALT7", "ALT8", "ALT9" } ; + +static const char* GetAltString(int alt) { + + if (alt>=0 && alt<=11) { + return alts[alt]; + } + + return unknown_alt; +} + + static int physToWpi [64] = { -1, // 0 @@ -177,7 +189,7 @@ static void readallPhys (int physPin) else pin = physToWpi [physPin] ; - printf (" | %4s", alts [getAlt (pin)]) ; + printf (" | %4s", GetAltString(getAlt (pin))) ; printf (" | %d", digitalRead (pin)) ; } @@ -201,7 +213,7 @@ static void readallPhys (int physPin) pin = physToWpi [physPin] ; printf (" | %d", digitalRead (pin)) ; - printf (" | %-4s", alts [getAlt (pin)]) ; + printf (" | %-4s", GetAltString(getAlt (pin))) ; } printf (" | %-5s", physNames [physPin]) ; @@ -233,11 +245,11 @@ static void allReadall (void) for (pin = 0 ; pin < 27 ; ++pin) { printf ("| %3d ", pin) ; - printf ("| %-4s ", alts [getAlt (pin)]) ; + printf ("| %-4s ", GetAltString(getAlt (pin))) ; printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ; printf ("| ") ; printf ("| %3d ", pin + 27) ; - printf ("| %-4s ", alts [getAlt (pin + 27)]) ; + printf ("| %-4s ", GetAltString(getAlt (pin + 27))) ; printf ("| %s ", digitalRead (pin + 27) == HIGH ? "High" : "Low ") ; printf ("|\n") ; } @@ -404,5 +416,5 @@ void doQmode (int argc, char *argv []) } pin = atoi (argv [2]) ; - printf ("%s\n", alts [getAlt (pin)]) ; + printf ("%s\n", GetAltString(getAlt (pin))) ; } diff --git a/newVersion b/newVersion old mode 100644 new mode 100755 diff --git a/version.h b/version.h index d2d73a4..2dec082 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "2.72" +#define VERSION "2.73" #define VERSION_MAJOR 2 -#define VERSION_MINOR 72 +#define VERSION_MINOR 73 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 6b99cc4..b6a613b 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -135,7 +135,7 @@ const unsigned int RP1_RIO_OE = (0x0004/4); const unsigned int RP1_RIO_IN = (0x0008/4); //RP1 chip (@Pi5) RIO offset for set/clear value -const unsigned int RP1_SET_OFFSET = (0x2000/4): +const unsigned int RP1_SET_OFFSET = (0x2000/4); const unsigned int RP1_CLR_OFFSET = (0x3000/4); //RP1 chip (@Pi5) PDE/PDU pull-up/-down enable @@ -167,7 +167,7 @@ const unsigned int RP1_PADS0_Addr = 0x400f0000; // due to the Pi v2, v3, etc. and the new /dev/gpiomem interface const char* gpiomem_global = "/dev/mem"; -const char* gpiomem_BCM = "/dev/gpiomem" +const char* gpiomem_BCM = "/dev/gpiomem"; const char* gpiomem_RP1 = "/dev/gpiomem0"; const int gpiomem_RP1_Size = 0x00030000; @@ -562,11 +562,12 @@ int GetMaxPin() { #define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } -void FailOnModel5() { +int FailOnModel5() { if (PI_MODEL_5 == RaspberryPiModel) { return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" " Unable to continue. Keep an eye of new versions at https://github.com/GrazerComputerClub/WiringPi\n") ; } + return 0; } // gpioToGPFSEL: @@ -1287,7 +1288,35 @@ int getAlt (int pin) return 0 ; if (PI_MODEL_5 == RaspberryPiModel) { - alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function, 5-11 debounce time + alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function + + /* BCM definiton + 000 = GPIO Pin 9 is an input + 001 = GPIO Pin 9 is an output + 100 = GPIO Pin 9 takes alternate function 0 + 101 = GPIO Pin 9 takes alternate function 1 + 110 = GPIO Pin 9 takes alternate function 2 + 111 = GPIO Pin 9 takes alternate function 3 + 011 = GPIO Pin 9 takes alternate function 4 + 010 = GPIO Pin 9 takes alternate function 5 + */ + switch(alt) { + case 0: return 4; + case 1: return 5; + case 2: return 6; + case 3: return 7; + case 4: return 3; + case RP1_FSEL_GPIO: { + unsigned int outputmask = gpio[2*pin] & 0x3000; //Bit13-OETOPAD + Bit12-OEFROMPERI + return (outputmask==0x3000) ? 1 : 0; //1=OUT 0=IN + } + case 6: return 8; + case 7: return 9; + case 8: return 10; + case 9: return 11; + default:return alt; + } + } else { fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; @@ -1678,7 +1707,6 @@ void pullUpDnControl (int pin, int pud) else if (wiringPiMode != WPI_MODE_GPIO) return ; - unsigned int pull; if (PI_MODEL_5 == RaspberryPiModel) { unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits switch (pud){ @@ -1830,7 +1858,7 @@ void digitalWrite (int pin, int value) else if (wiringPiMode != WPI_MODE_GPIO) return ; if (PI_MODEL_5 == RaspberryPiModel) { - if (value == LOW) + if (value == LOW) { //printf("Set pin %d >>0x%08x<< to low\n", pin, 1< Date: Mon, 12 Feb 2024 21:01:39 +0100 Subject: [PATCH 10/15] #17 --- wiringPi/wiringPi.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index b6a613b..82d5392 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -151,6 +151,7 @@ const unsigned int RP1_STATUS_LEVEL_MASK = 0x00C00000; const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4; const unsigned int RP1_DEBOUNCE_MASK = 0x7f; const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5); +const unsigned int RP1_PAD_DEFAULT = 0x5a; //RP1 chip (@Pi5) address const unsigned long long RP1_BASE_Addr = 0x1f000d0000; @@ -826,6 +827,7 @@ static void usingGpioMemCheck (const char *what) fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ; exit (EXIT_FAILURE) ; } + } @@ -1600,12 +1602,21 @@ void pinModeAlt (int pin, int mode) ********************************************************************************* */ +//Default: rp1_set_pad(pin, 0, 1, 0, 1, 1, 1, 0); +void rp1_set_pad(int pin, int slewfast, int schmitt, int pulldown, int pullup, int drive, int inputenable, int outputdisable) { + + pads[1+pin] = (slewfast != 0) | ((schmitt != 0) << 1) | ((pulldown != 0) << 2) | ((pullup != 0) << 3) | ((drive & 0x3) << 4) | ((inputenable != 0) << 6) | ((outputdisable != 0) << 7); +} + void pinMode (int pin, int mode) { int fSel, shift, alt ; struct wiringPiNodeStruct *node = wiringPiNodes ; int origPin = pin ; + if (wiringPiDebug) + printf ("pinMode: pin:%d mode:%d\n", pin, mode) ; + setupCheck ("pinMode") ; if ((pin & PI_GPIO_MASK) == 0) // On-board pin @@ -1617,6 +1628,9 @@ void pinMode (int pin, int mode) else if (wiringPiMode != WPI_MODE_GPIO) return ; + if (wiringPiDebug) + printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ; + softPwmStop (origPin) ; softToneStop (origPin) ; @@ -1625,13 +1639,17 @@ void pinMode (int pin, int mode) if (mode == INPUT) { if (PI_MODEL_5 == RaspberryPiModel) { - rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1< Date: Fri, 16 Feb 2024 18:29:26 +0100 Subject: [PATCH 11/15] #17 setPadDrive --- gpio/gpio.c | 4 +-- wiringPi/wiringPi.c | 80 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index a4574a1..d029877 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -807,13 +807,13 @@ static void doPadDrive (int argc, char *argv []) group = atoi (argv [2]) ; val = atoi (argv [3]) ; - if ((group < 0) || (group > 2)) + if ((group < -1) || (group > 2)) //-1 hidden feature for read value of all { fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ; exit (1) ; } - if ((val < 0) || (val > 7)) + if ((val < -1) || (val > 7)) { fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ; exit (1) ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 82d5392..a30d453 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -152,6 +152,8 @@ const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4; const unsigned int RP1_DEBOUNCE_MASK = 0x7f; const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5); const unsigned int RP1_PAD_DEFAULT = 0x5a; +const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030; +const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK); //RP1 chip (@Pi5) address const unsigned long long RP1_BASE_Addr = 0x1f000d0000; @@ -1249,21 +1251,57 @@ int physPinToGpio (int physPin) void setPadDrive (int group, int value) { - uint32_t wrVal ; + uint32_t wrVal, rdVal; - RETURN_ON_MODEL5 if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if ((group < 0) || (group > 2)) - return ; + value = value & 7; // 0-7 supported + if (PI_MODEL_5 == RaspberryPiModel) { + if (-1==group) { + printf ("Pad register:\n"); + for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { + unsigned int drive = (pads[1+pin] & RP1_PAD_DRIVE_MASK)>>4; + printf (" Pin %2d: 0x%08X drive: 0x%d = %2dmA\n", pin, pads[1+pin], drive, 0==drive ? 2 : drive*4) ; + } + } + if (group !=0) { // only GPIO range @RP1 + return ; + } + switch(value) { + default: + /* bcm*/ // RP1 + case 0: /* 2mA*/ value=0; break; // 2mA + case 1: /* 4mA*/ + case 2: /* 6mA*/ value=1; break; // 4mA + case 3: /* 8mA*/ + case 4: /*10mA*/ value=2; break; // 8mA + case 5: /*12mA*/ + case 6: /*14mA*/ + case 7: /*16mA*/ value=3; break; //12mA + } + wrVal = (value << 4); //Drive strength 0-3 + //set for all pins even when it's avaiable for each pin separately + for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { + pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal; + } + rdVal = pads[1+17]; // only pin 17 readback, for logging + } else { + if (-1==group) { + printf ("Pad register: Group 0: 0x%08X, Group 1: 0x%08X, Group 2: 0x%08X\n", *(pads + 0 + 11), *(pads + 1 + 11), *(pads + 2 + 11)) ; + } - wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; - *(pads + group + 11) = wrVal ; + if ((group < 0) || (group > 2)) + return ; + + wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7 + *(pads + group + 11) = wrVal ; + rdVal = *(pads + group + 11); + } if (wiringPiDebug) { printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; - printf ("Read : %08X\n", *(pads + group + 11)) ; + printf ("Read : %08X\n", rdVal) ; } } } @@ -1292,15 +1330,21 @@ int getAlt (int pin) if (PI_MODEL_5 == RaspberryPiModel) { alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function - /* BCM definiton - 000 = GPIO Pin 9 is an input - 001 = GPIO Pin 9 is an output - 100 = GPIO Pin 9 takes alternate function 0 - 101 = GPIO Pin 9 takes alternate function 1 - 110 = GPIO Pin 9 takes alternate function 2 - 111 = GPIO Pin 9 takes alternate function 3 - 011 = GPIO Pin 9 takes alternate function 4 - 010 = GPIO Pin 9 takes alternate function 5 + /* + BCM: + 000b = GPIO Pin 9 is an input + 001b = GPIO Pin 9 is an output + 100b = GPIO Pin 9 takes alternate function 0 + 101b = GPIO Pin 9 takes alternate function 1 + 110b = GPIO Pin 9 takes alternate function 2 + 111b = GPIO Pin 9 takes alternate function 3 + 011b = GPIO Pin 9 takes alternate function 4 + 010b = GPIO Pin 9 takes alternate function 5 + RP1: + 8 = alternate function 6 + 9 = alternate function 7 + 10 = alternate function 8 + 11 = alternate function 9 */ switch(alt) { case 0: return 4; @@ -1728,8 +1772,8 @@ void pullUpDnControl (int pin, int pud) if (PI_MODEL_5 == RaspberryPiModel) { unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits switch (pud){ - case PUD_OFF: break; - case PUD_UP: pads[1+pin] = pullbits | RP1_PUD_UP; break; //set bit + case PUD_OFF: pads[1+pin] = pullbits; break; + case PUD_UP: pads[1+pin] = pullbits | RP1_PUD_UP; break; case PUD_DOWN: pads[1+pin] = pullbits | RP1_PUD_DOWN; break; default: return ; /* An illegal value */ } From 107b9ee4c28674f531045832d203684d8b543d0a Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Fri, 16 Feb 2024 21:16:20 +0100 Subject: [PATCH 12/15] #17 PinDrive --- gpio/gpio.c | 30 ++++++++++++++++++++++++++++-- wiringPi/wiringPi.c | 24 ++++++++++++++++++++---- wiringPi/wiringPi.h | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/gpio/gpio.c b/gpio/gpio.c index d029877..7c448a5 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -794,6 +794,31 @@ void doMode (int argc, char *argv []) ********************************************************************************* */ +static void doPadDrivePin (int argc, char *argv []) +{ + + if (argc != 4) { + fprintf (stderr, "Usage: %s drivepin pin value\n", argv [0]) ; + exit (1) ; + } + + int pin = atoi (argv [2]) ; + int val = atoi (argv [3]) ; + + if ((pin < 0) || (pin > 27)) { + fprintf (stderr, "%s: drive pin not 0-27: %d\n", argv [0], pin) ; + exit (1) ; + } + + if ((val < 0) || (val > 3)) { + fprintf (stderr, "%s: drive value not 0-3: %d\n", argv [0], val) ; + exit (1) ; + } + + setPadDrivePin (pin, val) ; +} + + static void doPadDrive (int argc, char *argv []) { int group, val ; @@ -807,13 +832,13 @@ static void doPadDrive (int argc, char *argv []) group = atoi (argv [2]) ; val = atoi (argv [3]) ; - if ((group < -1) || (group > 2)) //-1 hidden feature for read value of all + if ((group < -1) || (group > 2)) //-1 hidden feature for read and print values { fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ; exit (1) ; } - if ((val < -1) || (val > 7)) + if ((val < 0) || (val > 7)) { fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ; exit (1) ; @@ -1536,6 +1561,7 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ; else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ; else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; + else if (strcasecmp (argv [1], "drivepin" ) == 0) doPadDrivePin(argc, argv) ; else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index a30d453..baf5d86 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -151,7 +151,10 @@ const unsigned int RP1_STATUS_LEVEL_MASK = 0x00C00000; const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4; const unsigned int RP1_DEBOUNCE_MASK = 0x7f; const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5); -const unsigned int RP1_PAD_DEFAULT = 0x5a; + +const unsigned int RP1_PAD_DEFAULT_0TO8 = (0x0B | 0x70); //Slewfast, Schmitt, PullUp, | 12mA, Input enable +const unsigned int RP1_PAD_DEFAULT_FROM9 = (0x07 | 0x70); //Slewfast, Schmitt, PullDown, | 12mA, Input enable + const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030; const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK); @@ -1248,6 +1251,19 @@ int physPinToGpio (int physPin) * Set the PAD driver value ********************************************************************************* */ +void setPadDrivePin (int pin, int value) { + if (PI_MODEL_5 != RaspberryPiModel) return; + if (pin < 0 || pin > GetMaxPin()) return ; + + uint32_t wrVal; + value = value & 3; // 0-3 supported + wrVal = (value << 4); //Drive strength 0-3 + pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal; + if (wiringPiDebug) { + printf ("setPadDrivePin: pin: %d, value: %d (%08X)\n", pin, value, pads[1+pin]) ; + } +} + void setPadDrive (int group, int value) { @@ -1682,8 +1698,8 @@ void pinMode (int pin, int mode) shift = gpioToShift [pin] ; if (mode == INPUT) { - if (PI_MODEL_5 == RaspberryPiModel) { - pads[1+pin] = RP1_PAD_DEFAULT; + if (PI_MODEL_5 == RaspberryPiModel) { + pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1< Date: Sat, 17 Feb 2024 13:40:29 +0100 Subject: [PATCH 13/15] #17 --- wiringPi/wiringPi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index baf5d86..d181944 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1417,6 +1417,7 @@ void pwmSetMode (int mode) void pwmSetRange (unsigned int range) { + FailOnModel5(); if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; From e0abd481fa5c01de9555a07e04d82647503ee504 Mon Sep 17 00:00:00 2001 From: mstroh76 Date: Sun, 25 Feb 2024 10:16:33 +0100 Subject: [PATCH 14/15] #22 --- wiringPi/wiringPi.c | 65 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index d181944..23d32c0 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -159,7 +159,9 @@ const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030; const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK); //RP1 chip (@Pi5) address -const unsigned long long RP1_BASE_Addr = 0x1f000d0000; +const unsigned long long RP1_64_BASE_Addr = 0x1f000d0000; +const unsigned int RP1_BASE_Addr = 0x40000000; +const unsigned int RP1_PWM0_Addr = 0x40098000; // Adress is not mapped to gpiomem device! const unsigned int RP1_IO0_Addr = 0x400d0000; const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000; const unsigned int RP1_PADS0_Addr = 0x400f0000; @@ -176,12 +178,20 @@ const char* gpiomem_global = "/dev/mem"; const char* gpiomem_BCM = "/dev/gpiomem"; const char* gpiomem_RP1 = "/dev/gpiomem0"; const int gpiomem_RP1_Size = 0x00030000; +// PCIe Memory access, static define - maybe needed to detect in future +//dmesg: rp1 0000:01:00.0: bar1 len 0x400000, start 0x1f00000000, end 0x1f003fffff, flags, 0x40200 +const char* pciemem_RP1_path = "/sys/bus/pci/devices/0000:01:00.0"; +const char* pciemem_RP1 = "/sys/bus/pci/devices/0000:01:00.0/resource1"; +const int pciemem_RP1_Size = 0x00400000; +const unsigned short pciemem_RP1_Ventor= 0x1de4; +const unsigned short pciemem_RP1_Device= 0x0001; static volatile unsigned int GPIO_PADS ; static volatile unsigned int GPIO_CLOCK_BASE ; static volatile unsigned int GPIO_BASE ; static volatile unsigned int GPIO_TIMER ; static volatile unsigned int GPIO_PWM ; +static volatile unsigned int GPIO_RIO ; #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) @@ -235,6 +245,7 @@ static int wiringPiSetuped = FALSE ; // Locals to hold pointers to the hardware +static volatile unsigned int *base ; static volatile unsigned int *gpio ; static volatile unsigned int *pwm ; static volatile unsigned int *clk ; @@ -245,6 +256,7 @@ static volatile unsigned int *rio ; // Export variables for the hardware pointers +volatile unsigned int *_wiringPiBase ; volatile unsigned int *_wiringPiGpio ; volatile unsigned int *_wiringPiPwm ; volatile unsigned int *_wiringPiClk ; @@ -2640,7 +2652,7 @@ int wiringPiSetup (void) const char* gpiomemModule = gpiomem_BCM; if (PI_MODEL_5 == model) { - gpiomemGlobal = NULL; // now supported as long as i don't know the RP1 32-bit mapped global address + gpiomemGlobal = pciemem_RP1; gpiomemModule = gpiomem_RP1; } @@ -2653,12 +2665,14 @@ int wiringPiSetup (void) usingGpioMem = TRUE ; } else - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or %s: %s.\n" + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open %s or %s: %s.\n" " Aborting your program because if it can not access the GPIO\n" " hardware then it most certianly won't work\n" - " Try running with sudo?\n", gpiomemModule, strerror (errno)) ; + " Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ; + } + if (wiringPiDebug) { + printf ("wiringPi: access to %s succeded\n", usingGpioMem ? gpiomemModule : gpiomemGlobal) ; } - // GPIO: if (PI_MODEL_5 != model) { //Set the offsets into the memory interface. @@ -2668,11 +2682,12 @@ int wiringPiSetup (void) GPIO_BASE = piGpioBase + 0x00200000 ; GPIO_TIMER = piGpioBase + 0x0000B000 ; GPIO_PWM = piGpioBase + 0x0020C000 ; + GPIO_RIO = 0x00 ; // Map the individual hardware components // GPIO: - + base = NULL; gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; if (gpio == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; @@ -2710,6 +2725,7 @@ int wiringPiSetup (void) timerIrqRaw = timer + TIMER_IRQ_RAW ; // Export the base addresses for any external software that might need them + _wiringPiBase = base ; _wiringPiGpio = gpio ; _wiringPiPwm = pwm ; _wiringPiClk = clk ; @@ -2717,21 +2733,46 @@ int wiringPiSetup (void) _wiringPiTimer = timer ; _wiringPiRio = NULL ; } else { - //map hole RP1 memory block from beginning, gobal mem not supported - gpio = (unsigned int *)mmap(0, gpiomem_RP1_Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x00000000) ; - if (gpio == MAP_FAILED) + unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; + + GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; + GPIO_CLOCK_BASE = 0x00; + GPIO_BASE = (RP1_IO0_Addr-RP1_BASE_Addr) ; + GPIO_TIMER = 0x00; + GPIO_PWM = RP1_PWM0_Addr-RP1_BASE_Addr; + GPIO_RIO = (RP1_SYS_RIO0_Addr-RP1_IO0_Addr) ; + + //map hole RP1 memory block from beginning, + base = (unsigned int *)mmap(0, MMAP_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x00000000) ; + if (base == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; - pads = &gpio[(RP1_PADS0_Addr-RP1_IO0_Addr)/4]; // Start adress of map memory for pads - rio = &gpio[(RP1_SYS_RIO0_Addr-RP1_IO0_Addr)/4]; // Start adress of map memory for rio + if (usingGpioMem) { + gpio = base; // RP1 start adress of map memory for gpio (same as module memory) + } else { + gpio = &base[GPIO_BASE/4];// RP1 start adress of map memory for gpio + } + pads = &gpio[GPIO_PADS/4]; // RP1 start adress of map memory for pads + rio = &gpio[GPIO_RIO/4]; // RP1 start adress of map memory for rio + GPIO_PADS += GPIO_BASE; + GPIO_RIO += GPIO_BASE; // Export the base addresses for any external software that might need them + _wiringPiBase = base ; _wiringPiGpio = gpio ; _wiringPiPwm = NULL ; _wiringPiClk = NULL ; _wiringPiPads = pads ; _wiringPiTimer = NULL ; _wiringPiRio = rio ; - } + } + if (wiringPiDebug) { + printf ("wiringPi: memory map gpio 0x%x %s\n", GPIO_BASE , _wiringPiGpio ? "valid" : "invalid"); + printf ("wiringPi: memory map pads 0x%x %s\n", GPIO_PADS , _wiringPiPads ? "valid" : "invalid"); + printf ("wiringPi: memory map rio 0x%x %s\n", GPIO_RIO , _wiringPiRio ? "valid" : "invalid"); + printf ("wiringPi: memory map pwm 0x%x %s\n", GPIO_PWM , _wiringPiPwm ? "valid" : "invalid"); + printf ("wiringPi: memory map clk 0x%x %s\n", GPIO_CLOCK_BASE, _wiringPiClk ? "valid" : "invalid"); + printf ("wiringPi: memory map timer 0x%x %s\n", GPIO_TIMER,_wiringPiTimer ? "valid" : "invalid"); + } initialiseEpoch () ; From 272f08b2c7365c1456f7adacd67c16c671ea9ea6 Mon Sep 17 00:00:00 2001 From: Manfred Wallner Date: Sun, 25 Feb 2024 19:58:02 +0100 Subject: [PATCH 15/15] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0954f11..ce0565d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ - -:warning: This library was deprecated by its author in August 2019. Until 31st October 2023 it was maintaining at https://github.com/WiringPi/WiringPi/ but later set to read only because there was no interest in properly maintaining it. -In 2024 GC2 fork the project to maintaining it and to keep the best GPIO Library for Raspberry Pi running. We do our best, but we have limited resources and can not give support. +ℹ️ Since 2024, [GC2](https://github.com/GrazerComputerClub) has taken over maintenance of the project, supporting new OS versions as well as current hardware generations. We are dedicated to keeping the arguably best-performing GPIO Library for Raspberry Pi running smoothly. We strive to do our best, but please note that this is a community effort, and we cannot provide any guarantees or take responsibility for implementing specific features you may need. WiringPi (Unofficial Mirror/Fork) ================================= @@ -35,9 +33,10 @@ wiringPi has been wrapped for multiple languages: Support ------- -Please do not email Gordon if you have issues, he will not be able to help. -Dont' email @Gadgetoid. -Don't email GC2, use issue system of github to report errors. +Please use the [issue system](https://github.com/WiringPi/WiringPi/issues) of GitHub. +Please do not email Gordon if you have issues. +Dont' email @Gadgetoid. +Please don't email GC2 for reporting issues, you might [contact us](wiringpi@gc2.at) for anything that's not for the public eye. Debug -------