Browse Source

Merge pull request #235 from WiringPi/unittest33

Release 3.4
pull/236/head
Manfred Wallner 6 months ago
committed by GitHub
parent
commit
8960cc91b9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
23 changed files with 1252 additions and 657 deletions
  1. +1
    -1
      VERSION
  2. +9
    -2
      examples/speed.c
  3. +6
    -66
      gpio/gpio.1
  4. +98
    -295
      gpio/gpio.c
  5. +2
    -2
      version.h
  6. +13
    -8
      wiringPi/mcp3422.c
  7. +5
    -1
      wiringPi/pcf8591.c
  8. +45
    -31
      wiringPi/pseudoPins.c
  9. +38
    -0
      wiringPi/test/Makefile
  10. +57
    -0
      wiringPi/test/wiringpi_test1_sysfs.c
  11. +54
    -0
      wiringPi/test/wiringpi_test2_sysfs.c
  12. +54
    -0
      wiringPi/test/wiringpi_test3_device_wpi.c
  13. +54
    -0
      wiringPi/test/wiringpi_test4_device_phys.c
  14. +57
    -0
      wiringPi/test/wiringpi_test5_default.c
  15. +170
    -0
      wiringPi/test/wiringpi_test6_isr.c
  16. +11
    -0
      wiringPi/test/wiringpi_test7_version.c
  17. +48
    -0
      wiringPi/test/wpi_test.h
  18. +457
    -176
      wiringPi/wiringPi.c
  19. +19
    -7
      wiringPi/wiringPi.h
  20. +37
    -1
      wiringPi/wiringPiI2C.c
  21. +6
    -0
      wiringPi/wiringPiI2C.h
  22. +0
    -63
      wiringPi/wiringPiLegacy.c
  23. +11
    -4
      wiringPi/wiringSerial.c

+ 1
- 1
VERSION View File

@@ -1 +1 @@
3.2
3.4

+ 9
- 2
examples/speed.c View File

@@ -84,12 +84,19 @@ int main (void)
pinMode (11, OUTPUT) ;
speedTest (11, FAST_COUNT) ;

// Switch to SYS mode:
// Switch to SYS mode: -> character device ABI

system ("/usr/local/bin/gpio export 17 out") ;
printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
wiringPiSetupSys () ;
speedTest (17, SLOW_COUNT) ;

// character device ABI

printf ("\ncharacter device ABI method: (%8d iterations)\n", SLOW_COUNT) ;
wiringPiSetupGpioDevice () ;
pinMode (17, OUTPUT) ;
speedTest (17, SLOW_COUNT) ;


return 0 ;
}

+ 6
- 66
gpio/gpio.1 View File

@@ -29,13 +29,6 @@ gpio \- Command-line access to Raspberry Pi's GPIO
.B readall
.PP
.B gpio
.B unexportall/exports
.PP
.B gpio
.B export/edge/unexport
.B ...
.PP
.B gpio
.B wfi
.B ...
.PP
@@ -77,10 +70,6 @@ somewhat slow control of the GPIO pins.
It can also control the IO's on the PiFace IO board and load the SPI and I2C
kernel modules if required.

Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR
system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR
interface without needing to be run as root.

.SH OPTIONS

.TP
@@ -90,15 +79,14 @@ Output the current version including the board revision of the Raspberry Pi.
.TP
.B \-g
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
\fINote:\fR The BCM_GPIO pin numbers are always used with the
export and edge commands.
.\" \fINote:\fR The BCM_GPIO pin numbers are always used with character device ABI.

.TP
.B \-1
Use the physical pin numbers rather than wiringPi pin numbers.
\fINote:\fR that this applies to the P1 connector only. It is not possible to
use pins on the Revision 2 P5 connector this way, and as with \-g the
BCM_GPIO pin numbers are always used with the export and edge commands.
.\" BCM_GPIO pin numbers are always used with character device ABI.

.TP
.B \-x extension
@@ -191,47 +179,6 @@ pull-up, pull-down or tristate (off) controls.
The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR.

.TP
.B unexportall
Un-Export all the GPIO pins in the /sys/class/gpio directory.

.TP
.B exports
Print a list (if any) of all the exported GPIO pins and their current values.

.TP
.B export
Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the
mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and
\fRlow\fR are supported at this time. Note that the pin number is the
\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and
\fIlow\fR commands pre-set the output value at the same time as the
export to output mode.

Once a GPIO pin has been exported, the \fBgpio\fR program changes the
ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in
later kernels, the \fI/sys/class/gpio/gpioX/edge\fR pseudo files to
that of the user running the \fBgpio\fR program. This means that you
can have a small script of gpio exports to setup the gpio pins as your
program requires without the need to run anything as root, or with the
sudo command.

.TP
.B edge
This exports a GPIO pin in the \fI/sys/class/gpio\fR directory, set
the direction to input and set the edge interrupt method to \fInone\fR,
\fIrising\fR, \fIfalling\fR or \fIboth\fR. Use like the export command
above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin
numbering.

Like the export commands above, ownership is set to that of the
calling user, allowing subsequent access from user programs without
requiring root/sudo.

.TP
.B unexport
Un-Export a GPIO pin in the /sys/class/gpio directory.

.TP
.B wfi <pin> <mode>
This set the given pin to the supplied interrupt mode: rising, falling
or both then waits for the interrupt to happen. It's a non-busy wait,
@@ -299,18 +246,10 @@ gpio mode 1 pwm # Set pin 1 to PWM mode
.PP
gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness
.PP
gpio export 17 out # Set GPIO Pin 17 to output
.PP
gpio export 0 in # Set GPIO Pin 0 (SDA0) to input.
.PP
gpio -g read 0 # Read GPIO Pin 0 (SDA0)

.SH "NOTES"

When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the
pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi
pin numbers.

As of kernels 4.1.7, a user-level GPIO access mechanism is available,
however wiringPi will not use this by default - because at this time
there appears to be issues when trying to program the PWM or clock output
@@ -326,13 +265,13 @@ in future releases once the /dev/gpiomem interface is fully operational.
.SH "SEE ALSO"

.LP
WiringPi's home page
WiringPi's development
.IP
https://github.com/WiringPi/WiringPi/

.SH AUTHOR

Gordon Henderson
Gordon Henderson and contributors

.SH "REPORTING BUGS"

@@ -340,7 +279,8 @@ Please report bugs to https://github.com/WiringPi/WiringPi/issues

.SH COPYRIGHT

Copyright (c) 2012-2018 Gordon Henderson
Copyright (c) 2012-2024 Gordon Henderson and contributors
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



+ 98
- 295
gpio/gpio.c View File

@@ -72,8 +72,8 @@ char *usage = "Usage: gpio -v\n"
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
" gpio <toggle/blink> <pin>\n"
" gpio readall\n"
" gpio unexportall/exports\n"
" gpio export/edge/unexport ...\n"
// " gpio unexportall/exports\n"
// " gpio export/edge/unexport ...\n"
" gpio wfi <pin> <mode>\n"
" gpio drive <group> <value>\n"
" gpio pwm-bal/pwm-ms \n"
@@ -89,15 +89,6 @@ char *usage = "Usage: gpio -v\n"
" gpio gbw <channel> <value>" ; // No trailing newline needed here.


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", name, pin) ;
exit (1) ;
}
return pinFS;
}

#ifdef NOT_FOR_NOW
/*
* decodePin:
@@ -290,13 +281,33 @@ static void doLoad (int argc, char *argv [])
if (!moduleLoaded (module1))
{
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
system (cmd) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (!moduleLoaded (module2))
{
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
system (cmd) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (!moduleLoaded (module2))
@@ -350,13 +361,33 @@ static void doUnLoad (int argc, char *argv [])
if (moduleLoaded (module1))
{
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
system (cmd) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (moduleLoaded (module2))
{
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
system (cmd) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}
}

@@ -392,160 +423,23 @@ static void doI2Cdetect (UNU int argc, char *argv [])
}


void SYSFS_DEPRECATED(const char *progName) {
fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName);
}

/*
* doExports:
* doExports: -> deprecated, removed
* List all GPIO exports
*********************************************************************************
*/

static void doExports (UNU int argc, UNU char *argv [])
{
int fd ;
int pin, l, first ;
char fName [128] ;
char buf [16] ;

for (first = 0, pin = 0 ; pin < 64 ; ++pin) // Crude, but effective
{

// Try to read the direction
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 ;

if (first == 0)
{
++first ;
printf ("GPIO Pins exported:\n") ;
}

if(pinFS==pin) {
printf ("%4d: ", pin) ;
} else {
printf ("%4d (%4d): ", pin, pinFS) ;
}

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;
buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf ("%-3s", buf) ;

close (fd) ;

// Try to Read the value

sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
if ((fd = open (fName, O_RDONLY)) == -1)
{
printf ("No Value file (huh?)\n") ;
continue ;
}

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;

buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf (" %s", buf) ;

// Read any edge trigger file

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
if ((fd = open (fName, O_RDONLY)) == -1)
{
printf ("\n") ;
continue ;
}

if ((l = read (fd, buf, 16)) == 0)
sprintf (buf, "%s", "?") ;

buf [l] = 0 ;
if ((buf [strlen (buf) - 1]) == '\n')
buf [strlen (buf) - 1] = 0 ;

printf (" %-8s\n", buf) ;

close (fd) ;
}
}


/*
* doExport:
* doExport: -> deprecated, removed
* gpio export pin mode
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doExport (int argc, char *argv [])
{
FILE *fd ;
int pin ;
char *mode ;
char fName [128] ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);
mode = argv [3] ;

if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
exit (1) ;
}

fprintf (fd, "%d\n", pinFS) ;
fclose (fd) ;
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)) ;
exit (1) ;
}

/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
fprintf (fd, "in\n") ;
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
fprintf (fd, "out\n") ;
else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
fprintf (fd, "high\n") ;
else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
fprintf (fd, "low\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
exit (1) ;
}

fclose (fd) ;

// Change ownership so the current user can actually use it

sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
changeOwner (argv [0], fName) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
changeOwner (argv [0], fName) ;

}


/*
* doWfi:
@@ -562,15 +456,14 @@ static volatile int globalCounter ;

void printgpioflush(const char* text) {
if (gpioDebug) {
printf(text);
printf("%s", text);
fflush(stdout);
}
}

void printgpio(const char* text) {
if (gpioDebug) {
printf(text);
fflush(stdout);
printf("%s", text);
}
}

@@ -620,7 +513,7 @@ void doWfi (int argc, char *argv [])
exit (1) ;
}

printgpio("wait for interrupt function call \n");
printgpio("wait for interrupt function call\n");
for (int Sec=0; Sec<timeoutSec; ++Sec) {
printgpioflush(".");
delay (999);
@@ -630,142 +523,29 @@ void doWfi (int argc, char *argv [])
}



/*
* doEdge:
* doEdge: -> deprecated, removed
* gpio edge pin mode
* Easy access to changing the edge trigger on a GPIO pin
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doEdge (int argc, char *argv [])
{
FILE *fd ;
int pin ;
char *mode ;
char fName [128] ;

if (argc != 4)
{
fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);
mode = argv [3] ;

// Export the pin and set direction to input

if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
exit (1) ;
}

fprintf (fd, "%d\n", pinFS) ;
fclose (fd) ;

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)) ;
exit (1) ;
}

fprintf (fd, "in\n") ;
fclose (fd) ;

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)) ;
exit (1) ;
}

/**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
exit (1) ;
}

// Change ownership of the value and edge files, so the current user can actually use it!

sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
changeOwner (argv [0], fName) ;

sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
changeOwner (argv [0], fName) ;

fclose (fd) ;
}


/*
* doUnexport:
* doUnexport: -> deprecated, removed
* gpio unexport pin
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doUnexport (int argc, char *argv [])
{
FILE *fd ;
int pin ;

if (argc != 3)
{
fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
exit (1) ;
}

pin = atoi (argv [2]) ;
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);

if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
exit (1) ;
}

fprintf (fd, "%d\n", pinFS) ;
fclose (fd) ;
}


/*
* doUnexportAll:
* doUnexportAll: -> deprecated, removed
* gpio unexportall
* Un-Export all the GPIO pins.
* This uses the /sys/class/gpio device interface.
*********************************************************************************
*/

void doUnexportall (char *progName)
{
FILE *fd ;
int pin ;

for (pin = 0 ; pin < 63 ; ++pin)
{
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) ;
}
}
}


/*
* doReset:
@@ -1358,29 +1138,52 @@ static void doVersion (char *argv [])
printf ("\n") ;
piBoardId (&model, &rev, &mem, &maker, &warranty) ;

printf ("Raspberry Pi Details:\n") ;
printf ("Hardware details:\n") ;
printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;

// Check for device tree
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
printf (" * Device tree is enabled.\n") ;
printf ("\nSystem details:\n") ;
if (stat ("/proc/device-tree", &statBuf) == 0) { // We're on a devtree system ...
printf (" * Device tree present.\n") ;
}
if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
{
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
{
fgets (name, 80, fd) ;
if (fgets(name, sizeof(name), fd) == NULL) {
// Handle error or end of file condition
perror("Error reading /proc/device-tree/model");
}
fclose (fd) ;
printf (" *--> %s\n", name) ;
printf (" Model: %s\n", name) ;
}
}

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 0:
printf (" * Does not support basic user-level GPIO access via memory.\n") ;
break;
case 1:
printf (" * Supports basic user-level GPIO access via /dev/mem.\n") ;
break;
case 2:
printf (" * Supports full user-level GPIO access via memory.\n") ;
break;
}
if (wiringPiUserLevelAccess()) {
printf (" * Supports basic user-level GPIO access via /dev/gpiomem.\n") ;
} else {
printf (" * Does not support basic user-level GPIO access via /dev/gpiomem.\n") ;
if(0==bGlobalAccess) {
printf (" * root or sudo may be required for direct GPIO access.\n") ;
}
}
if (wiringPiGpioDeviceGetFd()>0) {
printf (" * Supports basic user-level GPIO access via /dev/gpiochip (slow).\n") ;
}

}


@@ -1466,13 +1269,13 @@ int main (int argc, char *argv [])
exit (EXIT_FAILURE) ;
}

// Initial test for /sys/class/gpio operations:
// Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there

/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }

// Check for load command:



+ 2
- 2
version.h View File

@@ -1,3 +1,3 @@
#define VERSION "3.2"
#define VERSION "3.4"
#define VERSION_MAJOR 3
#define VERSION_MINOR 2
#define VERSION_MINOR 4

+ 13
- 8
wiringPi/mcp3422.c View File

@@ -43,15 +43,20 @@
*********************************************************************************
*/

void waitForConversion (int fd, unsigned char *buffer, int n)
void waitForConversion(int fd, unsigned char *buffer, int n)
{
for (;;)
{
read (fd, buffer, n) ;
if ((buffer [n-1] & 0x80) == 0)
break ;
delay (1) ;
}
for (;;) {
ssize_t bytes_read = read(fd, buffer, n);
if (bytes_read != n) {
perror("Error reading from file descriptor");
return;
}
if ((buffer[n - 1] & 0x80) == 0)
break;
delay(1);
}
}

/*


+ 5
- 1
wiringPi/pcf8591.c View File

@@ -24,6 +24,7 @@
*/

#include <unistd.h>
#include <stdio.h>

#include "wiringPi.h"
#include "wiringPiI2C.h"
@@ -41,7 +42,10 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int val
unsigned char b [2] ;
b [0] = 0x40 ;
b [1] = value & 0xFF ;
write (node->fd, b, 2) ;
ssize_t bytes_written = write(node->fd, b, 2);
if (bytes_written != 2) {
perror("Error writing to file descriptor");
}
}




+ 45
- 31
wiringPi/pseudoPins.c View File

@@ -35,9 +35,12 @@
#define SHARED_NAME "wiringPiPseudoPins"
#define PSEUDO_PINS 64

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>

@@ -45,21 +48,20 @@

#include "pseudoPins.h"

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
static int myAnalogRead(struct wiringPiNodeStruct *node, int pin)
{
int *ptr = (int *)node->data0 ;
int myPin = pin - node->pinBase ;
int *ptr = (int *)(intptr_t)node->data0; // Cast to intptr_t to handle pointer-to-integer conversion
int myPin = pin - node->pinBase;

return *(ptr + myPin) ;
return *(ptr + myPin);
}


static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
static void myAnalogWrite(struct wiringPiNodeStruct *node, int pin, int value)
{
int *ptr = (int *)node->data0 ;
int myPin = pin - node->pinBase ;
int *ptr = (int *)(intptr_t)node->data0;
int myPin = pin - node->pinBase;

*(ptr + myPin) = value ;
*(ptr + myPin) = value;
}


@@ -69,27 +71,39 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
*********************************************************************************
*/

int pseudoPinsSetup (const int pinBase)
{
struct wiringPiNodeStruct *node ;
void *ptr ;

node = wiringPiNewNode (pinBase, PSEUDO_PINS) ;

node->fd = shm_open (SHARED_NAME, O_CREAT | O_RDWR, 0666) ;

if (node->fd < 0)
return FALSE ;

if (ftruncate (node->fd, PSEUDO_PINS * sizeof (int)) < 0)
return FALSE ;

ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ;

node->data0 = (unsigned int)ptr ;

node->analogRead = myAnalogRead ;
node->analogWrite = myAnalogWrite ;

return TRUE ;
int pseudoPinsSetup(const int pinBase)
{
struct wiringPiNodeStruct *node;
void *ptr;

node = wiringPiNewNode(pinBase, PSEUDO_PINS);
if (node == NULL) {
fprintf(stderr, "Error creating new wiringPi node");
return FALSE;
}

node->fd = shm_open(SHARED_NAME, O_CREAT | O_RDWR, 0666);
if (node->fd < 0) {
perror("Error opening shared memory");
return FALSE;
}

if (ftruncate(node->fd, PSEUDO_PINS * sizeof(int)) < 0) {
perror("Error resizing shared memory");
return FALSE;
}

ptr = mmap(NULL, PSEUDO_PINS * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0);
if (ptr == MAP_FAILED) {
perror("Error mapping shared memory");
return FALSE;
}

node->data0 = (unsigned int)(uintptr_t)ptr;

node->analogRead = myAnalogRead;
node->analogWrite = myAnalogWrite;

return TRUE;
}

+ 38
- 0
wiringPi/test/Makefile View File

@@ -0,0 +1,38 @@
CC = gcc
CFLAGS = -Wall
LDFLAGS =

tests = wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_version

all: $(tests)

wiringpi_test1_sysfs:
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi

wiringpi_test2_sysfs:
${CC} ${CFLAGS} wiringpi_test2_sysfs.c -o wiringpi_test2_sysfs -lwiringPi

wiringpi_test3_device_wpi:
${CC} ${CFLAGS} wiringpi_test3_device_wpi.c -o wiringpi_test3_device_wpi -lwiringPi

wiringpi_test4_device_phys:
${CC} ${CFLAGS} wiringpi_test4_device_phys.c -o wiringpi_test4_device_phys -lwiringPi

wiringpi_test5_default:
${CC} ${CFLAGS} wiringpi_test5_default.c -o wiringpi_test5_default -lwiringPi

wiringpi_test6_isr:
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi

wiringpi_test7_version:
${CC} ${CFLAGS} wiringpi_test7_version.c -o wiringpi_test7_version -lwiringPi

test:
for t in $(tests) ; do \
echo === unit test: $${t} === ; \
time ./$${t} ; \
echo ; echo ; \
done

clean:
for t in $(tests) ; do rm -fv $${t} ; done

+ 57
- 0
wiringPi/test/wiringpi_test1_sysfs.c View File

@@ -0,0 +1,57 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>


const int GPIO = 19;
const int GPIOIN = 26;
const int ToggleValue = 4;


int main (void) {

printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
printf(" testing digitalWrite, digitalRead and pullUpDnControl\n");

if (wiringPiSetupSys() == -1) {
printf("wiringPiSetupSys failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

printf("toggle %d times ...\n", ToggleValue);
for (int loop=1; loop<ToggleValue; loop++) {
digitalWriteEx(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);
digitalWriteEx(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);
}

digitalWrite(GPIO, LOW);

printf("\nWiringPi GPIO test program (using GPIO%d (input pull up/down) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, INPUT);
delayMicroseconds(3000000);
pullUpDnControl (GPIOIN, PUD_OFF);

for (int loop=1; loop<ToggleValue; loop++) {
pullUpDnControlEx (GPIO, GPIOIN, PUD_DOWN);
delayMicroseconds(600000);
pullUpDnControlEx (GPIO, GPIOIN, PUD_UP);
delayMicroseconds(600000);
}

//Error wrong direction - only for fun
digitalWrite(GPIO, LOW);

return(EXIT_SUCCESS);
}


+ 54
- 0
wiringPi/test/wiringpi_test2_sysfs.c View File

@@ -0,0 +1,54 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test2_device.c -o wiringpi_test2_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>


const int GPIO = 19;
const int GPIOIN = 26;
const int ToggleValue = 4;


int main (void) {

printf("WiringPi GPIO test program 2 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
printf(" testing pullUpDnControl and pinMode PM_OFF\n");

if (wiringPiSetupSys() == -1) {
printf("wiringPiSetupSys failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

printf("\nTest output\n");
digitalWriteEx(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);
digitalWriteEx(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

printf("\nTest output off with pull up\n");
pinMode(GPIO, OUTPUT);
digitalWriteEx(GPIO, GPIOIN, LOW);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);

printf("\nTest output off with pull down\n");
pullUpDnControl (GPIO, PUD_DOWN);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
}

+ 54
- 0
wiringPi/test/wiringpi_test3_device_wpi.c View File

@@ -0,0 +1,54 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test3_device.c -o wiringpi_test3_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>


const int GPIO = 24; //BCM 19
const int GPIOIN = 25; //BCM 26;
const int ToggleValue = 4;


int main (void) {

printf("WiringPi GPIO test program 2 (using WiringPi GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN);
printf(" testing pullUpDnControl and pinMode PM_OFF\n");

if (wiringPiSetupGpioDevice(WPI_PIN_WPI) == -1) {
printf("wiringPiSetupGpioDevice failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

printf("\nTest output\n");
digitalWriteEx(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);
digitalWriteEx(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

printf("\nTest output off with pull up\n");
pinMode(GPIO, OUTPUT);
digitalWriteEx(GPIO, GPIOIN, LOW);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);

printf("\nTest output off with pull down\n");
pullUpDnControl (GPIO, PUD_DOWN);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
}

+ 54
- 0
wiringPi/test/wiringpi_test4_device_phys.c View File

@@ -0,0 +1,54 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test4_device.c -o wiringpi_test4_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>


const int GPIO = 35; //BCM 19
const int GPIOIN = 37; //BCM 26;
const int ToggleValue = 4;


int main (void) {

printf("WiringPi GPIO test program 2 (using physical GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN);
printf(" testing pullUpDnControl and pinMode PM_OFF\n");

if (wiringPiSetupGpioDevice(WPI_PIN_PHYS) == -1) {
printf("wiringPiSetupGpioDevice failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

printf("\nTest output\n");
digitalWriteEx(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);
digitalWriteEx(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

printf("\nTest output off with pull up\n");
pinMode(GPIO, OUTPUT);
digitalWriteEx(GPIO, GPIOIN, LOW);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);

printf("\nTest output off with pull down\n");
pullUpDnControl (GPIO, PUD_DOWN);
pinMode(GPIO, PM_OFF);
delayMicroseconds(600000);
printf("out = off ");
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
}

+ 57
- 0
wiringPi/test/wiringpi_test5_default.c View File

@@ -0,0 +1,57 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>


const int GPIO = 19;
const int GPIOIN = 26;
const int ToggleValue = 4;


int main (void) {

printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
printf(" testing digitalWrite, digitalRead and pullUpDnControl\n");

if (wiringPiSetupGpio() == -1) {
printf("wiringPiSetupGpio failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

printf("toggle %d times ...\n", ToggleValue);
for (int loop=1; loop<ToggleValue; loop++) {
digitalWriteEx(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);
digitalWriteEx(GPIO, GPIOIN, HIGH);
delayMicroseconds(600000);
}

digitalWrite(GPIO, LOW);

printf("\nWiringPi GPIO test program (using GPIO%d (input pull up/down) and GPIO%d (input))\n", GPIO, GPIOIN);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, INPUT);
delayMicroseconds(3000000);
pullUpDnControl (GPIOIN, PUD_OFF);

for (int loop=1; loop<ToggleValue; loop++) {
pullUpDnControlEx (GPIO, GPIOIN, PUD_DOWN);
delayMicroseconds(600000);
pullUpDnControlEx (GPIO, GPIOIN, PUD_UP);
delayMicroseconds(600000);
}

//Error wrong direction - only for fun
digitalWrite(GPIO, LOW);

return(EXIT_SUCCESS);
}


+ 170
- 0
wiringPi/test/wiringpi_test6_isr.c View File

@@ -0,0 +1,170 @@
// WiringPi test program: Kernel char device interface / sysfs successor
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi

#include "wpi_test.h"
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>


const int GPIO = 19;
const int GPIOIN = 26;
const int ToggleValue = 4;


static volatile int globalCounter;
volatile long long gStartTime, gEndTime;


static void wfi (void) {
struct timeval now;

gettimeofday(&now, 0);
if (0==gStartTime) {
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
} else {
gEndTime = now.tv_sec*1000000LL + now.tv_usec;
}
globalCounter++;
}


double StartSequence (int Enge, int OUTpin) {
int expected;
double timeExpected;

gStartTime = 0;
gEndTime = 0;
globalCounter = 0;
printf("Start\n");
digitalWrite(OUTpin, HIGH);
delay(200);
digitalWrite(OUTpin, LOW);
delay(100);
digitalWrite(OUTpin, HIGH);
delay(200);
digitalWrite(OUTpin, LOW);
delay(100);
printf("Stop\n");
int globalCounterCopy = globalCounter;

if (INT_EDGE_BOTH == Enge) {
expected = 4;
timeExpected = 500;
} else {
expected = 2;
timeExpected = 300;
}

if (globalCounter==expected) {
double fTime = (gEndTime - gStartTime) / 1000000.0;
printf("IRQ worked %g sec (~%gs expected)", fTime, timeExpected/1000.0);
double diff = fTime-(timeExpected/1000.0);
if(diff<0.05 && diff>0) {
printf(" -> %spassed%s\n", COLORGRN, COLORDEF);
} else {
printf(" -> %sfailed%s\n", COLORRED, COLORDEF);
}

return fTime;
} else {
printf("IRQ not worked got %d iterations (%d exprected)\n\n", globalCounterCopy, expected);
return 0;
}
}


double DurationTime(int Enge, int OUTpin, int IRQpin) {
struct timeval now;
double fTime = 0.0;

gStartTime = 0;
gEndTime = 0;
globalCounter = 0;
printf("Start\n");

if (INT_EDGE_RISING == Enge) {
digitalWrite(OUTpin, LOW);
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
sleep(1);
gettimeofday(&now, 0);
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
digitalWrite(OUTpin, HIGH);
delay(20);
digitalWrite(OUTpin, LOW);
} else if (INT_EDGE_FALLING == Enge) {
digitalWrite(OUTpin, HIGH);
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
sleep(1);
gettimeofday(&now, 0);
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
digitalWrite(OUTpin, LOW);
}

sleep(1);
fTime = (gEndTime - gStartTime);
printf("IRQ detect time %g usec", fTime);
if (fTime<2000 && fTime>0) {
printf(" -> %spassed%s\n", COLORGRN, COLORDEF);
} else {
printf(" -> %sfailed%s\n", COLORRED, COLORDEF);
}
wiringPiISRStop (IRQpin) ;

return fTime;
}

int main (void) {
const int IRQpin = GPIOIN ;
const int OUTpin = GPIO ;
int major, minor;

wiringPiVersion(&major, &minor);

printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
printf(" testing irq\n");

printf("\nISR test (WiringPi %d.%d)\n", major, minor);

wiringPiSetupGpio() ;

pinMode(IRQpin, INPUT);
pinMode(OUTpin, OUTPUT);
digitalWrite (OUTpin, LOW) ;


printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
sleep(1);
StartSequence (INT_EDGE_RISING, OUTpin);
printf("Testing close\n");
wiringPiISRStop (IRQpin) ;

printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
sleep(1);
StartSequence (INT_EDGE_FALLING, OUTpin);
printf("Testing close\n");
wiringPiISRStop (IRQpin) ;

printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin);
wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi) ;
sleep(1);
StartSequence (INT_EDGE_BOTH, OUTpin);
printf("Testing close\n");
wiringPiISRStop (IRQpin) ;

for (int count=0; count<2; count++) {
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
DurationTime(INT_EDGE_RISING, OUTpin, IRQpin);

printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin);
}
pinMode(OUTpin, INPUT);

return 0 ;
}

+ 11
- 0
wiringPi/test/wiringpi_test7_version.c View File

@@ -0,0 +1,11 @@
#include "wpi_test.h"
#include "../../version.h"

int main (void) {
int major, minor;

wiringPiVersion(&major, &minor);

CheckSame("version major", major, VERSION_MAJOR);
CheckSame("version minor", minor, VERSION_MINOR);
}

+ 48
- 0
wiringPi/test/wpi_test.h View File

@@ -0,0 +1,48 @@

#include <wiringPi.h>
#include <stdio.h>

#define COLORDEF "\x1B[0m"
#define COLORRED "\x1B[31m"
#define COLORGRN "\x1B[32m"

void CheckGPIO(int GPIO, int GPIOIN, int out) {
int in = digitalRead(GPIOIN);
int read = digitalRead(GPIO);

int pass = 0;
if (out==in && in==read) {
pass = 1;
}
if (pass) {
printf("GPIO%d = %d (GPIO%d = %d) -> %spassed%s\n", GPIOIN, in, GPIO, read, COLORGRN, COLORDEF );
} else {
printf("GPIO%d = %d (GPIO%d = %d) -> %sfailed%s\n", GPIOIN, in, GPIO, read, COLORRED, COLORDEF );
}
}


void digitalWriteEx(int GPIO, int GPIOIN, int mode) {
digitalWrite(GPIO, mode);
printf("out = %d ", mode);
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, mode);
}


void pullUpDnControlEx (int GPIO, int GPIOIN, int mode) {
pullUpDnControl (GPIO, mode);
int out = mode==PUD_UP ? 1:0;
printf("in = %4s ", mode==PUD_UP ? "up":"down");
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, out);
}


void CheckSame(const char* msg, int value, int expect) {
if (value==expect) {
printf("%s -> %spassed%s\n", msg, COLORGRN, COLORDEF );
} else {
printf("%s -> %sfailed%s\n", msg, COLORRED, COLORDEF );
}
}

+ 457
- 176
wiringPi/wiringPi.c View File

@@ -395,10 +395,23 @@ int wiringPiReturnCodes = FALSE ;

int wiringPiTryGpioMem = FALSE ;

// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value
static unsigned int lineFlags [64] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
} ;

static int lineFds [64] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
} ;

static int sysFds [64] =
static int isrFds [64] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -531,52 +544,13 @@ 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
} ;

int GPIOToSysFS(const int pin) {
int sysfspin = pin;
int piBoard() {
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 (sysfspin<399 || sysfspin>426) { // only 399-426 supported, 40-pin GPIO header
sysfspin = -1;
}
int model, rev, mem, maker, overVolted;
piBoardId (&model, &rev, &mem, &maker, &overVolted);
}
if (wiringPiDebug)
printf ("GPIOToSysFS: translate bcm gpio %d to sysfs gpio %d\n", pin, sysfspin) ;

return sysfspin;
return RaspberryPiModel<0 ? 0 : 1;
}

int GetMaxPin() {
@@ -584,8 +558,8 @@ int GetMaxPin() {
}


#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
int FailOnModel5() {
if (PI_MODEL_5 == RaspberryPiModel) {
return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n"
@@ -857,12 +831,12 @@ static void usingGpioMemCheck (const char *what)
void PrintSystemStdErr () {
struct utsname sys_info;
if (uname(&sys_info) == 0) {
fprintf (stderr, " wiringpi = %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
fprintf (stderr, " system name = %s\n", sys_info.sysname);
//fprintf (stderr, " node name = %s\n", sys_info.nodename);
fprintf (stderr, " release = %s\n", sys_info.release);
fprintf (stderr, " version = %s\n", sys_info.version);
fprintf (stderr, " machine = %s\n", sys_info.machine);
fprintf (stderr, " WiringPi : %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
fprintf (stderr, " system name : %s\n", sys_info.sysname);
//fprintf (stderr, " node name : %s\n", sys_info.nodename);
fprintf (stderr, " release : %s\n", sys_info.release);
fprintf (stderr, " version : %s\n", sys_info.version);
fprintf (stderr, " machine : %s\n", sys_info.machine);
if (strstr(sys_info.machine, "arm") == NULL && strstr(sys_info.machine, "aarch")==NULL) {
fprintf (stderr, " -> This is not an ARM architecture; it cannot be a Raspberry Pi.\n") ;
}
@@ -884,6 +858,10 @@ void piFunctionOops (const char *function, const char* suggestion, const char* u
exit (EXIT_FAILURE) ;
}

void ReportDeviceError(const char *function, int pin, const char *mode, int ret) {
fprintf(stderr, "wiringPi: ERROR: ioctl %s of %d (%s) returned error '%s' (%d)\n", function, pin, mode, strerror(errno), ret);
}


/*
* piGpioLayout:
@@ -923,10 +901,7 @@ void piGpioLayoutOops (const char *why)

int piGpioLayout (void)
{
if (-1==RaspberryPiLayout) {
int model, rev, mem, maker, overVolted ;
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
}
piBoard();
return RaspberryPiLayout;
}

@@ -1135,6 +1110,37 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
}

RaspberryPiModel = *model;

switch (RaspberryPiModel){
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:
case PI_MODEL_ZERO_W:
piGpioBase = GPIO_PERI_BASE_OLD ;
piGpioPupOffset = GPPUD ;
break ;

case PI_MODEL_4B:
case PI_MODEL_400:
case PI_MODEL_CM4:
piGpioBase = GPIO_PERI_BASE_2711 ;
piGpioPupOffset = GPPUPPDN0 ;
break ;

case PI_MODEL_5:
piGpioBase = GPIO_PERI_BASE_2712 ;
piGpioPupOffset = 0 ;
break ;

default:
piGpioBase = GPIO_PERI_BASE_2835 ;
piGpioPupOffset = GPPUD ;
break ;
}
}


@@ -1194,16 +1200,16 @@ void setPadDrive (int group, int value)
if (PI_MODEL_5 == RaspberryPiModel) {
if (-1==group) {
printf ("Pad register:\n");
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
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:
default:
/* bcm*/ // RP1
case 0: /* 2mA*/ value=0; break; // 2mA
case 1: /* 4mA*/
@@ -1214,9 +1220,9 @@ void setPadDrive (int group, int value)
case 6: /*14mA*/
case 7: /*16mA*/ value=3; break; //12mA
}
wrVal = (value << 4); //Drive strength 0-3
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) {
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
@@ -1228,7 +1234,7 @@ void setPadDrive (int group, int value)
if ((group < 0) || (group > 2))
return ;

wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7
*(pads + group + 11) = wrVal ;
rdVal = *(pads + group + 11);
}
@@ -1525,6 +1531,65 @@ void pinEnableED01Pi (int pin)
#endif


const char DEV_GPIO_PI[] ="/dev/gpiochip0";
const char DEV_GPIO_PI5[]="/dev/gpiochip4";

int wiringPiGpioDeviceGetFd() {
if (chipFd<0) {
piBoard();
const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI;
chipFd = open(gpiochip, O_RDWR);
if (chipFd < 0) {
fprintf(stderr, "wiringPi: ERROR: %s open ret=%d\n", gpiochip, chipFd);
} else if (wiringPiDebug) {
printf ("wiringPi: Open chip %s succeded, fd=%d\n", gpiochip, chipFd) ;
}
}
return chipFd;
}

void releaseLine(int pin) {

if (wiringPiDebug)
printf ("releaseLine: pin:%d\n", pin) ;
lineFlags[pin] = 0;
close(lineFds[pin]);
lineFds[pin] = -1;
}

int requestLine(int pin, unsigned int lineRequestFlags) {
struct gpiohandle_request rq;

if (lineFds[pin]>=0) {
if (lineRequestFlags == lineFlags[pin]) {
//already requested
return lineFds[pin];
} else {
//different request -> rerequest
releaseLine(pin);
}
}

//requested line
if (wiringPiGpioDeviceGetFd()<0) {
return -1; // error
}
rq.lineoffsets[0] = pin;
rq.lines = 1;
rq.flags = lineRequestFlags;
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
if (ret || rq.fd<0) {
ReportDeviceError("get line handle", pin, "RequestLine", ret);
return -1; // error
}

lineFlags[pin] = lineRequestFlags;
lineFds[pin] = rq.fd;
if (wiringPiDebug)
printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ;
return lineFds[pin];
}

/*
*********************************************************************************
* Core Functions
@@ -1555,7 +1620,7 @@ void pinModeAlt (int pin, int mode)

if (PI_MODEL_5 == RaspberryPiModel) {

//confusion! diffrent to to BCM! this is taking directly the value for the register
//confusion! diffrent to to BCM! this is taking directly the value for the register
/*
"alt0" 0b100
"alt1" 0b101
@@ -1588,6 +1653,35 @@ void rp1_set_pad(int pin, int slewfast, int schmitt, int pulldown, int pullup, i
pads[1+pin] = (slewfast != 0) | ((schmitt != 0) << 1) | ((pulldown != 0) << 2) | ((pullup != 0) << 3) | ((drive & 0x3) << 4) | ((inputenable != 0) << 6) | ((outputdisable != 0) << 7);
}

void pinModeFlagsDevice (int pin, int mode, unsigned int flags) {
unsigned int lflag = flags;
if (wiringPiDebug)
printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ;

lflag &= ~(GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_OUTPUT);
switch(mode) {
default:
fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n");
return;
case INPUT:
lflag |= GPIOHANDLE_REQUEST_INPUT;
break;
case OUTPUT:
lflag |= GPIOHANDLE_REQUEST_OUTPUT;
break;
case PM_OFF:
pinModeFlagsDevice(pin, INPUT, 0);
releaseLine(pin);
return;
}

requestLine(pin, lflag);
}

void pinModeDevice (int pin, int mode) {
pinModeFlagsDevice(pin, mode, lineFlags[pin]);
}

void pinMode (int pin, int mode)
{
int fSel, shift, alt ;
@@ -1595,18 +1689,34 @@ void pinMode (int pin, int mode)
int origPin = pin ;

if (wiringPiDebug)
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ;
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ;

setupCheck ("pinMode") ;

if ((pin & PI_GPIO_MASK) == 0) // On-board pin
{
/**/ if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
switch(wiringPiMode) {
default: //WPI_MODE_GPIO_SYS
fprintf(stderr, "pinMode: invalid mode\n");
return;
case WPI_MODE_PINS:
pin = pinToGpio [pin];
break;
case WPI_MODE_PHYS:
pin = physToGpio [pin];
break;
case WPI_MODE_GPIO_DEVICE_BCM:
pinModeDevice(pin, mode);
return;
case WPI_MODE_GPIO_DEVICE_WPI:
pinModeDevice(pinToGpio[pin], mode);
return;
case WPI_MODE_GPIO_DEVICE_PHYS:
pinModeDevice(physToGpio[pin], mode);
return;
case WPI_MODE_GPIO:
break;
}

if (wiringPiDebug)
printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ;
@@ -1618,7 +1728,7 @@ void pinMode (int pin, int mode)
shift = gpioToShift [pin] ;

if (mode == INPUT) {
if (PI_MODEL_5 == RaspberryPiModel) {
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<<pin; // Input
@@ -1646,7 +1756,7 @@ void pinMode (int pin, int mode)
{
RETURN_ON_MODEL5
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
return ;
return ;

usingGpioMemCheck ("pinMode PWM") ;

@@ -1663,7 +1773,7 @@ void pinMode (int pin, int mode)
{
RETURN_ON_MODEL5
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
return ;
return ;

usingGpioMemCheck ("pinMode CLOCK") ;

@@ -1688,6 +1798,28 @@ void pinMode (int pin, int mode)
* Control the internal pull-up/down resistors on a GPIO pin.
*********************************************************************************
*/
void pullUpDnControlDevice (int pin, int pud) {
unsigned int flag = lineFlags[pin];
unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;

flag &= ~biasflags;
switch (pud){
case PUD_OFF: flag |= GPIOHANDLE_REQUEST_BIAS_DISABLE; break;
case PUD_UP: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; break;
case PUD_DOWN: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; break;
default: return ; /* An illegal value */
}

// reset input/output
if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) {
pinModeFlagsDevice (pin, OUTPUT, flag);
} else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) {
pinModeFlagsDevice (pin, INPUT, flag);
} else {
lineFlags[pin] = flag; // only store for later
}
}


void pullUpDnControl (int pin, int pud)
{
@@ -1697,13 +1829,25 @@ void pullUpDnControl (int pin, int pud)

if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{

/**/ if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
switch(wiringPiMode) {
default: //WPI_MODE_GPIO_SYS
fprintf(stderr, "pinMode: invalid mode\n");
return;
case WPI_MODE_PINS:
pin = pinToGpio [pin];
break;
case WPI_MODE_PHYS:
pin = physToGpio [pin];
break;
case WPI_MODE_GPIO_DEVICE_BCM:
return pullUpDnControlDevice(pin, pud);
case WPI_MODE_GPIO_DEVICE_WPI:
return pullUpDnControlDevice(pinToGpio[pin], pud);
case WPI_MODE_GPIO_DEVICE_PHYS:
return pullUpDnControlDevice(physToGpio[pin], pud);
case WPI_MODE_GPIO:
break;
}

if (PI_MODEL_5 == RaspberryPiModel) {
unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits
@@ -1722,11 +1866,10 @@ void pullUpDnControl (int pin, int pud)
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;
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 */
}

@@ -1755,26 +1898,58 @@ void pullUpDnControl (int pin, int pud)
}




/*
* digitalRead:
* Read the value of a given Pin, returning HIGH or LOW
*********************************************************************************
*/

int digitalReadDevice (int pin) { // INPUT and OUTPUT should work

if (lineFds[pin]<0) {
// line not requested - auto request on first read as input
pinModeDevice(pin, INPUT);
}
if (lineFds[pin]>=0) {
struct gpiohandle_data data;
int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("get line values", pin, "digitalRead", ret);
return LOW; // error
}
return data.values[0];
}
return LOW; // error , need to request line before
}


int digitalRead (int pin)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;

if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{
if (wiringPiMode == WPI_MODE_GPIO_SYS)
return LOW ;
else if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return LOW ;
switch(wiringPiMode) {
default: //WPI_MODE_GPIO_SYS
fprintf(stderr, "digitalRead: invalid mode\n");
return LOW;
case WPI_MODE_PINS:
pin = pinToGpio [pin];
break;
case WPI_MODE_PHYS:
pin = physToGpio [pin];
break;
case WPI_MODE_GPIO_DEVICE_BCM:
return digitalReadDevice(pin);
case WPI_MODE_GPIO_DEVICE_WPI:
return digitalReadDevice(pinToGpio[pin]);
case WPI_MODE_GPIO_DEVICE_PHYS:
return digitalReadDevice(physToGpio[pin]);
case WPI_MODE_GPIO:
break;
}

if (PI_MODEL_5 == RaspberryPiModel) {
switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) {
@@ -1825,27 +2000,67 @@ unsigned int digitalRead8 (int pin)
*********************************************************************************
*/

void digitalWriteDevice (int pin, int value) {

if (wiringPiDebug)
printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ;

if (lineFds[pin]<0) {
// line not requested - auto request on first write as output
pinModeDevice(pin, OUTPUT);
}
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) {
struct gpiohandle_data data;
data.values[0] = value;
if (wiringPiDebug)
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("set line values", pin, "digitalWrite", ret);
return; // error
}
} else {
fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]);
}
return; // error
}

void digitalWrite (int pin, int value)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;

if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{
if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
return ;
else if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
switch(wiringPiMode) {
default: //WPI_MODE_GPIO_SYS
fprintf(stderr, "digitalWrite: invalid mode\n");
return;
case WPI_MODE_PINS:
pin = pinToGpio [pin];
break;
case WPI_MODE_PHYS:
pin = physToGpio [pin];
break;
case WPI_MODE_GPIO_DEVICE_BCM:
digitalWriteDevice(pin, value);
return;
case WPI_MODE_GPIO_DEVICE_WPI:
digitalWriteDevice(pinToGpio[pin], value);
return;
case WPI_MODE_GPIO_DEVICE_PHYS:
digitalWriteDevice(physToGpio[pin], value);
return;
case WPI_MODE_GPIO:
break;
}

if (PI_MODEL_5 == RaspberryPiModel) {
if (value == LOW) {
//printf("Set pin %d >>0x%08x<< to low\n", pin, 1<<pin);
rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin;
} else {
//printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin);
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin;
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin;
}
} else {
if (value == LOW)
@@ -2101,7 +2316,7 @@ unsigned int digitalReadByte2 (void)

int waitForInterrupt (int pin, int mS)
{
int fd, ret;
int fd, ret;
struct pollfd polls ;
struct gpioevent_data evdata;
//struct gpio_v2_line_request req2;
@@ -2111,7 +2326,7 @@ int waitForInterrupt (int pin, int mS)
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;

if ((fd = sysFds [pin]) == -1)
if ((fd = isrFds [pin]) == -1)
return -2 ;

// Setup poll structure
@@ -2124,12 +2339,12 @@ int waitForInterrupt (int pin, int mS)
if (ret <= 0) {
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret);
} else {
//if (polls.revents & POLLIN)
//if (polls.revents & POLLIN)
if (wiringPiDebug) {
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, sysFds [pin]) ;
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ;
}
/* read event data */
int readret = read(sysFds [pin], &evdata, sizeof(evdata));
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
if (readret == sizeof(evdata)) {
if (wiringPiDebug) {
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ;
@@ -2142,9 +2357,6 @@ int waitForInterrupt (int pin, int mS)
return ret;
}

const char DEV_GPIO_PI[] ="/dev/gpiochip0";
const char DEV_GPIO_PI5[]="/dev/gpiochip4";

int waitForInterruptInit (int pin, int mode)
{
const char* strmode = "";
@@ -2157,16 +2369,8 @@ int waitForInterruptInit (int pin, int mode)

/* open gpio */
sleep(1);
const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI;
if (chipFd < 0) {
chipFd = open(gpiochip, O_RDWR);
if (chipFd < 0) {
fprintf(stderr, "wiringPi: ERROR: %s open ret=%d\n", gpiochip, chipFd);
return -1;
}
}
if (wiringPiDebug) {
printf ("wiringPi: Open chip %s succeded, fd=%d\n", gpiochip, chipFd) ;
if (wiringPiGpioDeviceGetFd()<0) {
return -1;
}

struct gpioevent_request req;
@@ -2197,7 +2401,7 @@ int waitForInterruptInit (int pin, int mode)
//later implement GPIO_V2_GET_LINE_IOCTL req2
int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req);
if (ret) {
fprintf(stderr, "wiringPi: ERROR: %s ioctl get line %d %s returned %d\n", gpiochip, pin, strmode, ret);
ReportDeviceError("get line event", pin , strmode, ret);
return -1;
}
if (wiringPiDebug) {
@@ -2206,12 +2410,12 @@ int waitForInterruptInit (int pin, int mode)

/* set event fd nonbloack read */
int fd_line = req.fd;
sysFds [pin] = fd_line;
isrFds [pin] = fd_line;
int flags = fcntl(fd_line, F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd_line, F_SETFL, flags);
if (ret) {
fprintf(stderr, "wiringPi: ERROR: %s fcntl set nonblock read=%d\n", gpiochip, chipFd);
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret);
return -1;
}

@@ -2220,10 +2424,10 @@ int waitForInterruptInit (int pin, int mode)


int waitForInterruptClose (int pin) {
if (sysFds[pin]>0) {
if (isrFds[pin]>0) {
if (wiringPiDebug) {
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ;
}
}
if (pthread_cancel(isrThreads[pin]) == 0) {
if (wiringPiDebug) {
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ;
@@ -2233,9 +2437,9 @@ int waitForInterruptClose (int pin) {
fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n");
}
}
close(sysFds [pin]);
close(isrFds [pin]);
}
sysFds [pin] = -1;
isrFds [pin] = -1;
isrFunctions [pin] = NULL;

/* -not closing so far - other isr may be using it - only close if no other is using - will code later
@@ -2323,7 +2527,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
if(waitForInterruptInit (pin, mode)<0) {
if (wiringPiDebug) {
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ;
}
}
};

if (wiringPiDebug) {
@@ -2522,6 +2726,7 @@ int wiringPiUserLevelAccess(void)
struct stat statBuf ;
const char* gpiomemModule = gpiomem_BCM;

piBoard();
if (PI_MODEL_5 == RaspberryPiModel) {
gpiomemModule = gpiomem_RP1;
}
@@ -2530,6 +2735,58 @@ int wiringPiUserLevelAccess(void)
}


int wiringPiGlobalMemoryAccess(void)
{
const char* gpiomemGlobal;
int fd=-1;
unsigned int MMAP_size;
unsigned int BaseAddr, PWMAddr;

piBoard();
if (PI_MODEL_5 == RaspberryPiModel) {
gpiomemGlobal = pciemem_RP1;
MMAP_size = pciemem_RP1_Size;
BaseAddr = 0x00000000;
PWMAddr = 0x00000000; //not supported so far
} 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 0x%X,0x%X) failed: %s\n", BaseAddr, MMAP_size, 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 0x%X,0x%X) failed: %s\n", PWMAddr, MMAP_size, 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.
@@ -2586,40 +2843,6 @@ int wiringPiSetup (void)
physToGpio = physToGpioR2 ;
}

// ...

switch (model)
{
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:
case PI_MODEL_ZERO_W:
piGpioBase = GPIO_PERI_BASE_OLD ;
piGpioPupOffset = GPPUD ;
break ;

case PI_MODEL_4B:
case PI_MODEL_400:
case PI_MODEL_CM4:
piGpioBase = GPIO_PERI_BASE_2711 ;
piGpioPupOffset = GPPUPPDN0 ;
break ;

case PI_MODEL_5:
piGpioBase = GPIO_PERI_BASE_2712 ;
piGpioPupOffset = 0 ;
break ;

default:
piGpioBase = GPIO_PERI_BASE_2835 ;
piGpioPupOffset = GPPUD ;
break ;
}

// Open the master /dev/ memory control device
// Device strategy: December 2016:
// Try /dev/mem. If that fails, then
@@ -2633,9 +2856,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 +2874,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) {
@@ -2709,7 +2935,7 @@ int wiringPiSetup (void)
_wiringPiPads = pads ;
_wiringPiTimer = timer ;
_wiringPiRio = NULL ;
} else {
} else {
unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size;

GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ;
@@ -2800,21 +3026,76 @@ int wiringPiSetupPhys (void)
return 0 ;
}

int wiringPiSetupPinType (enum WPIPinType pinType) {
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupPinType(%d) called\n", (int) pinType) ;
switch (pinType) {
case WPI_PIN_BCM: return wiringPiSetupGpio();
case WPI_PIN_WPI: return wiringPiSetup();
case WPI_PIN_PHYS: return wiringPiSetupPhys();
default: return -1;
}
}


int wiringPiSetupGpioDevice (enum WPIPinType pinType) {
if (wiringPiSetuped)
return 0 ;
if (wiringPiDebug) {
printf ("wiringPi: wiringPiSetupGpioDevice(%d) called\n", (int)pinType) ;
}
if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;

if (getenv (ENV_CODES) != NULL)
wiringPiReturnCodes = TRUE ;

if (wiringPiGpioDeviceGetFd()<0) {
return -1;
}
wiringPiSetuped = TRUE ;

if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1){
pinToGpio = pinToGpioR1 ;
physToGpio = physToGpioR1 ;
} else {
pinToGpio = pinToGpioR2 ;
physToGpio = physToGpioR2 ;
}

initialiseEpoch () ;

switch (pinType) {
case WPI_PIN_BCM:
wiringPiMode = WPI_MODE_GPIO_DEVICE_BCM;
break;
case WPI_PIN_WPI:
wiringPiMode = WPI_MODE_GPIO_DEVICE_WPI;
break;
case WPI_PIN_PHYS:
wiringPiMode = WPI_MODE_GPIO_DEVICE_PHYS;
break;
default:
wiringPiSetuped = FALSE;
return -1;
}

return 0 ;
}

/*
* wiringPiSetupSys:
* GPIO Sysfs Interface for Userspace is deprecated
* https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html
* The last Raspberry Pi Kernel with Sysfs was 6.1.
* If needed, please use WiringPi 3.1.
*
*
* Switched to new GPIO driver Interface in version 3.3
*/

int wiringPiSetupSys (void)
{
piFunctionOops("wiringPiSetupSys",
"use wringpi 3.1 (last version with GPIO Sysfs interface)",
"https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html");

return 0 ;
if (wiringPiSetuped)
return 0 ;
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;
return wiringPiSetupGpioDevice(WPI_PIN_BCM);
}

+ 19
- 7
wiringPi/wiringPi.h View File

@@ -46,12 +46,15 @@

// wiringPi modes

#define WPI_MODE_PINS 0
#define WPI_MODE_GPIO 1
#define WPI_MODE_GPIO_SYS 2
#define WPI_MODE_PHYS 3
#define WPI_MODE_PIFACE 4
#define WPI_MODE_UNINITIALISED -1
#define WPI_MODE_PINS 0
#define WPI_MODE_GPIO 1
#define WPI_MODE_GPIO_SYS 2 // deprecated since 3.2
#define WPI_MODE_PHYS 3
#define WPI_MODE_PIFACE 4
#define WPI_MODE_GPIO_DEVICE_BCM 5 // BCM pin numbers like WPI_MODE_GPIO
#define WPI_MODE_GPIO_DEVICE_WPI 6 // WiringPi pin numbers like WPI_MODE_PINS
#define WPI_MODE_GPIO_DEVICE_PHYS 7 // Physic pin numbers like WPI_MODE_PHYS
#define WPI_MODE_UNINITIALISED -1

// Pin modes

@@ -62,6 +65,7 @@
#define SOFT_PWM_OUTPUT 4
#define SOFT_TONE_OUTPUT 5
#define PWM_TONE_OUTPUT 6
#define PM_OFF 7 // to input / release line

#define LOW 0
#define HIGH 1
@@ -205,15 +209,23 @@ 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) ;
enum WPIPinType {
WPI_PIN_BCM = 1,
WPI_PIN_WPI,
WPI_PIN_PHYS,
};

extern void wiringPiVersion (int *major, int *minor) ;
extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3
extern int wiringPiUserLevelAccess (void) ;
extern int wiringPiSetup (void) ;
extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
extern int wiringPiSetupPhys (void) ;
extern int wiringPiSetupPinType (enum WPIPinType pinType); //Interface V3.3
extern int wiringPiSetupGpioDevice(enum WPIPinType pinType); //Interface V3.3

extern int wiringPiGpioDeviceGetFd(); //Interface V3.3
extern void pinModeAlt (int pin, int mode) ;
extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ;


+ 37
- 1
wiringPi/wiringPiI2C.c View File

@@ -47,7 +47,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
@@ -154,6 +154,26 @@ int wiringPiI2CReadReg16 (int fd, int reg)
return data.word & 0xFFFF ;
}

int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size)
{
union i2c_smbus_data data;

if (size>I2C_SMBUS_BLOCK_MAX) {
size = I2C_SMBUS_BLOCK_MAX;
}
data.block[0] = size;
int result = i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_I2C_BLOCK_DATA, &data);
if (result<0) {
return result;
}
memcpy(values, &data.block[1], size);
return data.block[0];
}

int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size)
{
return(read(fd, values, size));
}

/*
* wiringPiI2CWrite:
@@ -189,6 +209,22 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int value)
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
}

int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size)
{
union i2c_smbus_data data;

if (size>I2C_SMBUS_BLOCK_MAX) {
size = I2C_SMBUS_BLOCK_MAX;
}
data.block[0] = size;
memcpy(&data.block[1], values, size);
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BLOCK_DATA, &data) ;
}

int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size)
{
return(write(fd, values, size));
}

/*
* wiringPiI2CSetupInterface:


+ 6
- 0
wiringPi/wiringPiI2C.h View File

@@ -22,6 +22,8 @@
***********************************************************************
*/

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif
@@ -29,10 +31,14 @@ extern "C" {
extern int wiringPiI2CRead (int fd) ;
extern int wiringPiI2CReadReg8 (int fd, int reg) ;
extern int wiringPiI2CReadReg16 (int fd, int reg) ;
extern int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size); //Interface 3.3
extern int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size); //Interface 3.3

extern int wiringPiI2CWrite (int fd, int data) ;
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
extern int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size); //Interface 3.3
extern int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size); //Interface 3.3

extern int wiringPiI2CSetupInterface (const char *device, int devId) ;
extern int wiringPiI2CSetup (const int devId) ;


+ 0
- 63
wiringPi/wiringPiLegacy.c View File

@@ -186,66 +186,3 @@ int piGpioLayoutLegacy (void)

return gpioLayout ;
}


/*
* wiringPiSetupSys:
* Must be called once at the start of your program execution.
*
* Initialisation (again), however this time we are using the /sys/class/gpio
* interface to the GPIO systems - slightly slower, but always usable as
* a non-root user, assuming the devices are already exported and setup correctly.
*/

/*
int wiringPiSetupSys (void)
{
char fName [128] ;

if (wiringPiSetuped)
return 0 ;

wiringPiSetuped = TRUE ;

if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;

if (getenv (ENV_CODES) != NULL)
wiringPiReturnCodes = TRUE ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;

int model, rev, mem, maker, overVolted ;
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;

if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1)
{
pinToGpio = pinToGpioR1 ;
physToGpio = physToGpioR1 ;
}
else
{
pinToGpio = pinToGpioR2 ;
physToGpio = physToGpioR2 ;
}

// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later

for (int pin = 0, maxpin=GetMaxPin() ; pin <= maxpin ; ++pin)
{
int pinFS = GPIOToSysFS(pin);
if (pinFS>=0) {
sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
sysFds [pin] = open (fName, O_RDWR) ;
}
}

initialiseEpoch () ;

wiringPiMode = WPI_MODE_GPIO_SYS ;

return 0 ;
}
*/

+ 11
- 4
wiringPi/wiringSerial.c View File

@@ -153,9 +153,12 @@ void serialClose (const int fd)
*********************************************************************************
*/

void serialPutchar (const int fd, const unsigned char c)
void serialPutchar(const int fd, const unsigned char c)
{
write (fd, &c, 1) ;
ssize_t bytes_written = write(fd, &c, 1);
if (bytes_written != 1) {
perror("Error writing to file descriptor");
}
}


@@ -165,9 +168,13 @@ void serialPutchar (const int fd, const unsigned char c)
*********************************************************************************
*/

void serialPuts (const int fd, const char *s)
void serialPuts(const int fd, const char *s)
{
write (fd, s, strlen (s)) ;
size_t len = strlen(s);
ssize_t bytes_written = write(fd, s, len);
if (bytes_written != (ssize_t)len) {
perror("Error writing to file descriptor");
}
}

/*


Loading…
Cancel
Save