A new version of wiringPi. Added in more stuff and fixed it up

for kernels 4.8 onwards.

Some very old stuff might break.

Additional fixes for the ISR code and some tweaks here and
there. I've removed the checks for some operations that might
fail when using the gpiomem interface - which is now the default
way of doing things - if your program segfaults, then you
may need to use sudo on it.
This commit is contained in:
Gordon Henderson
2016-12-12 14:19:55 +00:00
parent b0a60c3302
commit b1dfc186ef
37 changed files with 1255 additions and 291 deletions

View File

@@ -129,9 +129,8 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
// that I can find )-:
//
// Updates in September 2015 - all now static variables (and apologies for the caps)
// due to the Pi v2 and the new /dev/gpiomem interface
// due to the Pi v2, v3, etc. and the new /dev/gpiomem interface
static volatile unsigned int RASPBERRY_PI_PERI_BASE ;
static volatile unsigned int GPIO_PADS ;
static volatile unsigned int GPIO_CLOCK_BASE ;
static volatile unsigned int GPIO_BASE ;
@@ -197,13 +196,23 @@ static volatile uint32_t *timer ;
static volatile uint32_t *timerIrqRaw ;
#endif
// GCC warning suppressor
#define UNU __attribute__((unused))
// Data for use with the boardId functions.
// The order of entries here to correspond with the PI_MODEL_X
// and PI_VERSION_X defines in wiringPi.h
// Only intended for the gpio command - use at your own risk!
static int piModel2 = FALSE ;
// piGpioBase:
// The base address of the GPIO memory mapped hardware IO
#define GPIO_PERI_BASE_OLD 0x20000000
#define GPIO_PERI_BASE_NEW 0x3F000000
static volatile unsigned int piGpioBase = 0 ;
const char *piModelNames [16] =
{
@@ -649,7 +658,7 @@ int wiringPiFailure (int fatal, const char *message, ...)
/*
* piBoardRev:
* piGpioLayout:
* Return a number representing the hardware revision of the board.
* This is not strictly the board revision but is used to check the
* layout of the GPIO connector - and there are 2 types that we are
@@ -666,30 +675,34 @@ int wiringPiFailure (int fatal, const char *message, ...)
* 3 GPIO pins on the (original) 26-way header - BCM_GPIO 22 was dropped and
* replaced with 27, and 0 + 1 - I2C bus 0 was changed to 2 + 3; I2C bus 1.
*
* Additionally, here we set the piModel2 flag too. This is again, nothing to
* do with the actual model, but the major version numbers - the GPIO base
* hardware address changed at model 2 and above (not the Zero though)
*
*********************************************************************************
*/
static void piBoardRevOops (const char *why)
static void piGpioLayoutOops (const char *why)
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, "Oops: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " -> %s\n", why) ;
fprintf (stderr, " -> You may want to check:\n") ;
fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
fprintf (stderr, " -> You'd best google the error to find out why.\n") ;
//fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
exit (EXIT_FAILURE) ;
}
int piBoardRev (void)
int piGpioLayout (void)
{
FILE *cpuFd ;
char line [120] ;
char *c ;
static int boardRev = -1 ;
static int gpioLayout = -1 ;
if (boardRev != -1) // No point checking twice
return boardRev ;
if (gpioLayout != -1) // No point checking twice
return gpioLayout ;
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
piBoardRevOops ("Unable to open /proc/cpuinfo") ;
piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
// Start by looking for the Architecture to make sure we're really running
// on a Pi. I'm getting fed-up with people whinging at me because
@@ -700,23 +713,23 @@ int piBoardRev (void)
break ;
if (strncmp (line, "Hardware", 8) != 0)
piBoardRevOops ("No hardware line") ;
piGpioLayoutOops ("No \"Hardware\" line") ;
if (wiringPiDebug)
printf ("piboardRev: Hardware: %s\n", line) ;
printf ("piGpioLayout: Hardware: %s\n", line) ;
// See if it's BCM2708 or BCM2709
// See if it's BCM2708 or BCM2709 or the new BCM2835.
if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point
{
piModel2 = TRUE ;
fclose (cpuFd) ;
return boardRev = 2 ;
}
else if (strstr (line, "BCM2708") == NULL)
// OK. As of Kernel 4.8, we have BCM2835 only, regardless of model.
// However I still want to check because it will trap the cheapskates and rip-
// off merchants who want to use wiringPi on non-Raspberry Pi platforms - which
// I do not support so don't email me your bleating whinges about anything
// other than a genuine Raspberry Pi.
if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835")))
{
fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ;
fprintf (stderr, " - expecting BCM2708 or BCM2709.\n") ;
fprintf (stderr, " - expecting BCM2708, BCM2709 or BCM2835.\n") ;
fprintf (stderr, "If this is a genuine Raspberry Pi then please report this\n") ;
fprintf (stderr, "to projects@drogon.net. If this is not a Raspberry Pi then you\n") ;
fprintf (stderr, "are on your own as wiringPi is designed to support the\n") ;
@@ -724,8 +737,11 @@ int piBoardRev (void)
exit (EXIT_FAILURE) ;
}
// Now do the rest of it as before - we just need to see if it's an older
// Rev 1 as anything else is rev 2.
// Right - we're Probably on a Raspberry Pi. Check the revision field for the real
// hardware type
// In-future, I ought to use the device tree as there are now Pi entries in
// /proc/device-tree/ ...
// but I'll leave that for the next revision.
// Isolate the Revision line
@@ -737,7 +753,7 @@ int piBoardRev (void)
fclose (cpuFd) ;
if (strncmp (line, "Revision", 8) != 0)
piBoardRevOops ("No \"Revision\" line") ;
piGpioLayoutOops ("No \"Revision\" line") ;
// Chomp trailing CR/NL
@@ -745,7 +761,7 @@ int piBoardRev (void)
*c = 0 ;
if (wiringPiDebug)
printf ("piboardRev: Revision string: %s\n", line) ;
printf ("piGpioLayout: Revision string: %s\n", line) ;
// Scan to the first character of the revision number
@@ -754,7 +770,7 @@ int piBoardRev (void)
break ;
if (*c != ':')
piBoardRevOops ("Bogus \"Revision\" line (no colon)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ;
// Chomp spaces
@@ -763,46 +779,46 @@ int piBoardRev (void)
++c ;
if (!isxdigit (*c))
piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
// Make sure its long enough
if (strlen (c) < 4)
piBoardRevOops ("Bogus revision line (too small)") ;
piGpioLayoutOops ("Bogus revision line (too small)") ;
// If you have overvolted the Pi, then it appears that the revision
// has 100000 added to it!
// The actual condition for it being set is:
// (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0
// This test is not correct for the new encoding scheme, so we'll remove it here as
// we don't really need it at this point.
/********************
if (wiringPiDebug)
if (strlen (c) != 4)
printf ("piboardRev: This Pi has/is (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0\n") ;
*******************/
// Isolate last 4 characters:
// Isolate last 4 characters: (in-case of overvolting or new encoding scheme)
c = c + strlen (c) - 4 ;
if (wiringPiDebug)
printf ("piboardRev: last4Chars are: \"%s\"\n", c) ;
printf ("piGpioLayout: last4Chars are: \"%s\"\n", c) ;
if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0))
boardRev = 1 ;
gpioLayout = 1 ;
else
boardRev = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2 and CM's.
gpioLayout = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2, v3, zero and CM's.
if (wiringPiDebug)
printf ("piBoardRev: Returning revision: %d\n", boardRev) ;
printf ("piGpioLayoutOops: Returning revision: %d\n", gpioLayout) ;
return boardRev ;
return gpioLayout ;
}
/***
if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point
{
piModel2 = TRUE ;
fclose (cpuFd) ;
return gpioLayout = 2 ;
}
else if (strstr (line, "BCM2708") == NULL)
{
}
***/
// Now do the rest of it as before - we just need to see if it's an older
// Rev 1 as anything else is rev 2.
/*
* piBoardId:
@@ -822,20 +838,32 @@ int piBoardRev (void)
* 0003 - Model B, Rev 1.1, 256MB, Egoman, Fuses/D14 removed.
*
* Newer Pi's with remapped GPIO:
* 0004 - Model B, Rev 2, 256MB, Sony
* 0005 - Model B, Rev 2, 256MB, Qisda
* 0006 - Model B, Rev 2, 256MB, Egoman
* 0007 - Model A, Rev 2, 256MB, Egoman
* 0008 - Model A, Rev 2, 256MB, Sony
* 0009 - Model A, Rev 2, 256MB, Qisda
* 000d - Model B, Rev 2, 512MB, Egoman (Red Pi, Blue Pi?)
* 000e - Model B, Rev 2, 512MB, Sony
* 000f - Model B, Rev 2, 512MB, Qisda
* 0004 - Model B, Rev 1.2, 256MB, Sony
* 0005 - Model B, Rev 1.2, 256MB, Egoman
* 0006 - Model B, Rev 1.2, 256MB, Egoman
*
* 0007 - Model A, Rev 1.2, 256MB, Egoman
* 0008 - Model A, Rev 1.2, 256MB, Sony
* 0009 - Model A, Rev 1.2, 256MB, Egoman
*
* 000d - Model B, Rev 1.2, 512MB, Egoman (Red Pi, Blue Pi?)
* 000e - Model B, Rev 1.2, 512MB, Sony
* 000f - Model B, Rev 1.2, 512MB, Egoman
*
* 0010 - Model B+, Rev 1.2, 512MB, Sony
* 0011 - Pi CM, Rev 1.2, 512MB, Sony
* 0012 - Model A+ Rev 1.2, 256MB, Sony
* 0014 - Pi CM, Rev 1.1, 512MB, Sony (Actual Revision might be different)
* 0015 - Model A+ Rev 1.1, 256MB, Sony
* 0013 - Model B+ Rev 1.2, 512MB, Embest
* 0016 - Model B+ Rev 1.2, 512MB, Sony
* 0019 - Model B+ Rev 1.2, 512MB, Egoman
*
* 0011 - Pi CM, Rev 1.1, 512MB, Sony
* 0014 - Pi CM, Rev 1.1, 512MB, Embest
* 0017 - Pi CM, Rev 1.1, 512MB, Sony
* 001a - Pi CM, Rev 1.1, 512MB, Egoman
*
* 0012 - Model A+ Rev 1.1, 256MB, Sony
* 0015 - Model A+ Rev 1.1, 512MB, Embest
* 0018 - Model A+ Rev 1.1, 256MB, Sony
* 001b - Model A+ Rev 1.1, 256MB, Egoman
*
* A small thorn is the olde style overvolting - that will add in
* 1000000
@@ -870,10 +898,10 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
// Will deal with the properly later on - for now, lets just get it going...
// unsigned int modelNum ;
(void)piBoardRev () ; // Call this first to make sure all's OK. Don't care about the result.
(void)piGpioLayout () ; // Call this first to make sure all's OK. Don't care about the result.
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
piBoardRevOops ("Unable to open /proc/cpuinfo") ;
piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
while (fgets (line, 120, cpuFd) != NULL)
if (strncmp (line, "Revision", 8) == 0)
@@ -882,7 +910,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
fclose (cpuFd) ;
if (strncmp (line, "Revision", 8) != 0)
piBoardRevOops ("No \"Revision\" line") ;
piGpioLayoutOops ("No \"Revision\" line") ;
// Chomp trailing CR/NL
@@ -901,7 +929,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
break ;
if (*c != ':')
piBoardRevOops ("Bogus \"Revision\" line (no colon)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ;
// Chomp spaces
@@ -910,7 +938,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
++c ;
if (!isxdigit (*c))
piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ;
revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x
@@ -944,12 +972,12 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
printf ("piBoardId: Old Way: revision is: %s\n", c) ;
if (!isdigit (*c))
piBoardRevOops ("Bogus \"Revision\" line (no digit at start of revision)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (no digit at start of revision)") ;
// Make sure its long enough
if (strlen (c) < 4)
piBoardRevOops ("Bogus \"Revision\" line (not long enough)") ;
piGpioLayoutOops ("Bogus \"Revision\" line (not long enough)") ;
// If longer than 4, we'll assume it's been overvolted
@@ -963,21 +991,34 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
/**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; }
else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; }
else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; }
else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; }
else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; }
else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; }
else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; }
else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; }
else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; }
}
}
@@ -1022,9 +1063,6 @@ void setPadDrive (int group, int value)
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
if ((group < 0) || (group > 2))
return ;
@@ -1098,9 +1136,6 @@ void pwmSetRange (unsigned int range)
{
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
*(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
}
@@ -1122,9 +1157,6 @@ void pwmSetClock (int divisor)
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
if (wiringPiDebug)
printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
@@ -1177,9 +1209,6 @@ void gpioClockSet (int pin, int freq)
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
divi = 19200000 / freq ;
divr = 19200000 % freq ;
divf = (int)((double)divr * 4096.0 / 19200000.0) ;
@@ -1222,13 +1251,13 @@ struct wiringPiNodeStruct *wiringPiFindNode (int pin)
*********************************************************************************
*/
static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; }
static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; }
static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; }
static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; }
static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; }
static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; }
static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; }
static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; }
static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
{
@@ -1352,17 +1381,11 @@ void pinMode (int pin, int mode)
softToneCreate (origPin) ;
else if (mode == PWM_TONE_OUTPUT)
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode
pwmSetMode (PWM_MODE_MS) ;
}
else if (mode == PWM_OUTPUT)
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
return ;
@@ -1377,9 +1400,6 @@ void pinMode (int pin, int mode)
}
else if (mode == GPIO_CLOCK)
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
return ;
@@ -1534,9 +1554,6 @@ void pwmWrite (int pin, int value)
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
/**/ if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
@@ -1603,9 +1620,6 @@ void pwmToneWrite (int pin, int freq)
{
int range ;
if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now
return ;
if (freq == 0)
pwmWrite (pin, 0) ; // Off
else
@@ -1630,7 +1644,7 @@ void pwmToneWrite (int pin, int freq)
* Reading is just bit fiddling.
* These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers
* 17, 18, 22, 23, 24, 24, 4 on a Pi v1 rev 0-3
* 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, zero
* 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, 3, zero
*********************************************************************************
*/
@@ -1720,8 +1734,8 @@ void digitalWriteByte2 (const int value)
}
else
{
*(gpio + gpioToGPCLR [0]) = 0x0FF00000 ;
*(gpio + gpioToGPSET [0]) = (value & 0xFF) << 20 ;
*(gpio + gpioToGPCLR [0]) = (~value & 0xFF) << 20 ; // 0x0FF00000; ILJ > CHANGE: Old causes glitch
*(gpio + gpioToGPSET [0]) = ( value & 0xFF) << 20 ;
}
}
@@ -1772,18 +1786,20 @@ int waitForInterrupt (int pin, int mS)
// Setup poll structure
polls.fd = fd ;
polls.events = POLLPRI ; // Urgent data!
polls.events = POLLPRI | POLLERR ;
// Wait for it ...
x = poll (&polls, 1, mS) ;
// Do a dummy read to clear the interrupt
// If no error, do a dummy read to clear the interrupt
// A one character read appars to be enough.
// Followed by a seek to reset it.
(void)read (fd, &c, 1) ;
lseek (fd, 0, SEEK_SET) ;
if (x > 0)
{
lseek (fd, 0, SEEK_SET) ; // Rewind
(void)read (fd, &c, 1) ; // Read & clear
}
return x ;
}
@@ -1797,7 +1813,7 @@ int waitForInterrupt (int pin, int mS)
*********************************************************************************
*/
static void *interruptHandler (void *arg)
static void *interruptHandler (UNU void *arg)
{
int myPin ;
@@ -2047,18 +2063,17 @@ unsigned int micros (void)
int wiringPiSetup (void)
{
int fd ;
int boardRev ;
int model, rev, mem, maker, overVolted ;
static int alreadyCalled = FALSE ;
static int alreadyDoneThis = FALSE ;
// This is here to trap the unwary - those who's program appears to work then fails some
// time later with a weird error message because you run out of file-handles.
// It's actually a fatal error to call any of the wiringPiSetup routines more than once,
// (you run out of file handles!) but I'm fed-up with the useless twats who email
// me bleating that there is a bug in my code, so screw-em.
if (alreadyCalled)
(void)wiringPiFailure (WPI_FATAL, "wiringPiSetup*: You must only call this once per program run. This is a fatal error. Please fix your code.\n") ;
alreadyCalled = TRUE ;
if (alreadyDoneThis)
return 0 ;
alreadyDoneThis = TRUE ;
if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;
@@ -2066,101 +2081,99 @@ int wiringPiSetup (void)
if (getenv (ENV_CODES) != NULL)
wiringPiReturnCodes = TRUE ;
if (getenv (ENV_GPIOMEM) != NULL)
wiringPiTryGpioMem = TRUE ;
if (wiringPiDebug)
{
printf ("wiringPi: wiringPiSetup called\n") ;
if (wiringPiTryGpioMem)
printf ("wiringPi: Using /dev/gpiomem\n") ;
}
boardRev = piBoardRev () ;
// Get the board ID information. We're not really using the information here,
// but it will give us information like the GPIO layout scheme (2 variants
// on the older 26-pin Pi's) and the GPIO peripheral base address.
// and if we're running on a compute module, then wiringPi pin numbers
// don't really many anything, so force native BCM mode anyway.
/**/ if (boardRev == 1) // A, B, Rev 1, 1.1
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
if (model == PI_MODEL_CM)
wiringPiMode = WPI_MODE_GPIO ;
else
wiringPiMode = WPI_MODE_PINS ;
/**/ if (piGpioLayout () == 1) // A, B, Rev 1, 1.1
{
pinToGpio = pinToGpioR1 ;
physToGpio = physToGpioR1 ;
}
else // A, B, Rev 2, B+, CM, Pi2, Zero
else // A2, B2, A+, B+, CM, Pi2, Pi3, Zero
{
pinToGpio = pinToGpioR2 ;
physToGpio = physToGpioR2 ;
}
// Note that a Zero is a model 1
// ...
if (piModel2)
RASPBERRY_PI_PERI_BASE = 0x3F000000 ;
else
RASPBERRY_PI_PERI_BASE = 0x20000000 ;
// Open the master /dev/ memory control device
// See if /dev/gpiomem exists and we can open it...
if (wiringPiTryGpioMem)
switch (model)
{
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", strerror (errno)) ;
RASPBERRY_PI_PERI_BASE = 0 ;
case PI_MODEL_A: case PI_MODEL_B:
case PI_MODEL_AP: case PI_MODEL_BP:
case PI_ALPHA: case PI_MODEL_CM: case PI_MODEL_ZERO:
piGpioBase = GPIO_PERI_BASE_OLD ;
break ;
default:
piGpioBase = GPIO_PERI_BASE_NEW ;
break ;
}
// ... otherwise fall back to the original /dev/mem which requires root level access
// Open the master /dev/ memory control device
// Device strategy: December 2016:
// Try /dev/mem. If that fails, then
// try /dev/gpiomem. If that fails then game over.
else
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
{
// This check is here because people are too stupid to check for themselves or read
// error messages.
if (geteuid () != 0)
(void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n Try running with sudo?\n", strerror (errno)) ;
piGpioBase = 0 ;
}
// Set the offsets into the memory interface.
GPIO_PADS = RASPBERRY_PI_PERI_BASE + 0x00100000 ;
GPIO_CLOCK_BASE = RASPBERRY_PI_PERI_BASE + 0x00101000 ;
GPIO_BASE = RASPBERRY_PI_PERI_BASE + 0x00200000 ;
GPIO_TIMER = RASPBERRY_PI_PERI_BASE + 0x0000B000 ;
GPIO_PWM = RASPBERRY_PI_PERI_BASE + 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:
gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
if ((int32_t)gpio == -1)
if (gpio == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
// PWM
pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
if ((int32_t)pwm == -1)
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 ((int32_t)clk == -1)
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) ;
if ((int32_t)pads == -1)
if (pads == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
#ifdef USE_TIMER
// The system timer
timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
if ((int32_t)timer == -1)
if (timer == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;
// Set the timer to free-running, 1MHz.
@@ -2174,14 +2187,6 @@ int wiringPiSetup (void)
initialiseEpoch () ;
// If we're running on a compute module, then wiringPi pin numbers don't really many anything...
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
if (model == PI_MODEL_CM)
wiringPiMode = WPI_MODE_GPIO ;
else
wiringPiMode = WPI_MODE_PINS ;
return 0 ;
}
@@ -2241,18 +2246,19 @@ int wiringPiSetupPhys (void)
int wiringPiSetupSys (void)
{
int boardRev ;
int pin ;
char fName [128] ;
static int alreadyCalled = FALSE ;
// This is here to trap the unwary - those who's program appears to work then fails some
// time later with a weird error message because you run out of file-handles.
static int alreadyDoneThis = FALSE ;
if (alreadyCalled)
(void)wiringPiFailure (WPI_FATAL, "wiringPiSetupSys: You must only call this once per program run. This is a fatal error. Please fix your code.\n") ;
// It's actually a fatal error to call any of the wiringPiSetup routines more than once,
// (you run out of file handles!) but I'm fed-up with the useless twats who email
// me bleating that there is a bug in my code, so screw-em.
alreadyCalled = TRUE ;
if (alreadyDoneThis)
return 0 ;
alreadyDoneThis = TRUE ;
if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;
@@ -2263,9 +2269,7 @@ int wiringPiSetupSys (void)
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;
boardRev = piBoardRev () ;
if (boardRev == 1)
if (piGpioLayout () == 1)
{
pinToGpio = pinToGpioR1 ;
physToGpio = physToGpioR1 ;