diff -ruN wiringPi/wiringPi.c wiringPi/wiringPi.c
--- wiringPi/wiringPi.c
+++ wiringPi/wiringPi.c
@@ -215,6 +215,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ;
#define GPIO_PERI_BASE_OLD 0x20000000
#define GPIO_PERI_BASE_NEW 0x3F000000
+#define GPIO_PERI_BASE_RP4 0xFE000000
static volatile unsigned int piGpioBase = 0 ;
@@ -547,6 +548,10 @@ static uint8_t gpioToPUDCLK [] =
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
} ;
+#define PULLUPDN_OFFSET_2711_0 57
+#define PULLUPDN_OFFSET_2711_1 58
+#define PULLUPDN_OFFSET_2711_2 59
+#define PULLUPDN_OFFSET_2711_3 60
// gpioToPwmALT
// the ALT value to put a GPIO pin into PWM mode
@@ -814,7 +819,7 @@ int piGpioLayout (void)
for (c = &line [strlen (line) - 1] ; (c == '\n') || (c == '\r') ; --c)
*c = 0 ;
- if (wiringPiDebug)
printf ("piGpioLayout: Revision string: %s\n", line) ;
@@ -883,7 +888,7 @@ int piBoardRev (void)
- So the distinction between boards that I can see is:
0000 - Error
@@ -955,6 +960,30 @@ void piBoardId (int model, int rev, int mem, int maker, int *warranty)
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
- char buffer[12] ;
- const char *ranges_file = "/proc/device-tree/soc/ranges" ;
- int info_fd = open(ranges_file, O_RDONLY) ;
- if (info_fd < 0) {
- fprintf(stderr, "cannot open: %s", ranges_file) ;
- exit (EXIT_FAILURE) ;
- }
- ssize_t n = read(info_fd, buffer, sizeof(buffer)) ;
- close(info_fd) ;
- if (n < 8) {
- fprintf(stderr, "cannot read base address: %s", ranges_file) ;
- exit (EXIT_FAILURE) ;
- }
- uint32_t gpio_base = (buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7] << 0) ;
- if (!gpio_base)
- {
- gpio_base = (buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11] << 0) ;
- }
- while (fgets (line, 120, cpuFd) != NULL)
if (strncmp (line, "Revision", 8) == 0)
break ;
@@ -968,7 +997,7 @@ void piBoardId (int model, int rev, int mem, int maker, int *warranty)
for (c = &line [strlen (line) - 1] ; (c == '\n') || (c == '\r') ; --c)
*c = 0 ;
- if (wiringPiDebug)
printf ("piBoardId: Revision string: %s\n", line) ;
@@ -1007,7 +1036,7 @@ void piBoardId (int model, int rev, int mem, int maker, int *warranty)
bMfg = (revision & (0x0F << 16)) >> 16 ;
bMem = (revision & (0x07 << 20)) >> 20 ;
bWarranty = (revision & (0x03 << 24)) != 0 ;
- model = bType ;
rev = bRev ;
*mem = bMem ;
@@ -1034,7 +1063,7 @@ void piBoardId (int model, int rev, int mem, int maker, int *warranty)
// If longer than 4, we'll assume it's been overvolted
*warranty = strlen (c) > 4 ;
// Extract last 4 characters:
c = c + strlen (c) - 4 ;
@@ -1073,8 +1102,11 @@ void piBoardId (int model, int rev, int mem, int maker, int *warranty)
else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; }
}
- if (gpio_base == GPIO_PERI_BASE_RP4) {
- *model = PI_MODEL_4;
- }
}
/*
@@ -1205,6 +1237,10 @@ void pwmSetRange (unsigned int range)
void pwmSetClock (int divisor)
{
uint32_t pwm_control ;
if(piGpioBase == GPIO_PERI_BASE_RP4) {
divisor = 540*divisor/192;
}
divisor &= 4095 ;
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
@@ -1260,7 +1296,7 @@ void gpioClockSet (int pin, int freq)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
- divi = 19200000 / freq ;
divr = 19200000 % freq ;
divf = (int)((double)divr * 4096.0 / 19200000.0) ;
@@ -1504,11 +1540,31 @@ void pullUpDnControl (int pin, int pud)
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
- *(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) ;
- // Check GPIO register
- int is2711 = *(gpio + PULLUPDN_OFFSET_2711_3) != 0x6770696f;
- if(is2711) {
// Pi 4 Pull-up/down method
int pullreg = PULLUPDN_OFFSET_2711_0 + (pin >> 4);
int pullshift = (pin & 0xf) << 1;
unsigned int pullbits;
unsigned int pull = 0; // Turn PUD off by default
if (pud == PUD_UP) {
pull = 1;
} else if (pud == PUD_DOWN) {
pull = 2;
}
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) ;
- }
}
else // Extension module
{
@@ -1680,7 +1736,7 @@ void pwmWrite (int pin, int value)
/*
- Read the analog value of a given Pin.
- Read the analog value of a given Pin.
- There is no on-board Pi analog hardware,
- so this needs to go to a new node.
@@ -1699,7 +1755,7 @@ int analogRead (int pin)
/*
- Write the analog value to the given Pin.
- Write the analog value to the given Pin.
- There is no on-board Pi analog hardware,
- so this needs to go to a new node.
@@ -1748,7 +1804,7 @@ void pwmToneWrite (int pin, int freq)
- Write an 8-bit byte to the first 8 GPIO pins - try to do it as
- fast as possible.
- However it still needs 2 operations to set the bits, so any external
- hardware must not rely on seeing a change as there will be a change
- hardware must not rely on seeing a change as there will be a change
- to set the outputs bits to zero, then another change to set the 1's
- Reading is just bit fiddling.
- These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers
@@ -1804,7 +1860,7 @@ unsigned int digitalReadByte (void)
data = (data << 1) | x ;
}
}
- else
{
raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins
for (pin = 0 ; pin < 8 ; ++pin)
@@ -1861,7 +1917,7 @@ unsigned int digitalReadByte2 (void)
data = (data << 1) | x ;
}
}
@@ -2265,6 +2321,9 @@ int wiringPiSetup (void)
case PI_MODEL_ZERO: case PI_MODEL_ZERO_W:
piGpioBase = GPIO_PERI_BASE_OLD ;
break ;
@@ -2273,7 +2332,7 @@ int wiringPiSetup (void)
// Open the master /dev/ memory control device
// Device strategy: December 2016:
-// Try /dev/mem. If that fails, then
+// Try /dev/mem. If that fails, then
// try /dev/gpiomem. If that fails then game over.
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
@@ -2311,13 +2370,13 @@ int wiringPiSetup (void)
pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
if (pwm == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
// Clock control (needed for PWM)
clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ;
if (clk == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
// The drive pads
pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
@@ -2437,7 +2496,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)
{
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
diff -ruN wiringPi/wiringPi.h wiringPi/wiringPi.h
--- wiringPi/wiringPi.h
+++ wiringPi/wiringPi.h
@@ -100,6 +100,7 @@
#define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12
#define PI_MODEL_3P 13
+#define PI_MODEL_4 14
#define PI_VERSION_1 0
#define PI_VERSION_1_1 1