@@ -1 +1 @@ | |||||
3.2 | |||||
3.4 |
@@ -84,12 +84,19 @@ int main (void) | |||||
pinMode (11, OUTPUT) ; | pinMode (11, OUTPUT) ; | ||||
speedTest (11, FAST_COUNT) ; | 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) ; | printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; | ||||
wiringPiSetupSys () ; | wiringPiSetupSys () ; | ||||
speedTest (17, SLOW_COUNT) ; | 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 ; | return 0 ; | ||||
} | } |
@@ -29,13 +29,6 @@ gpio \- Command-line access to Raspberry Pi's GPIO | |||||
.B readall | .B readall | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B unexportall/exports | |||||
.PP | |||||
.B gpio | |||||
.B export/edge/unexport | |||||
.B ... | |||||
.PP | |||||
.B gpio | |||||
.B wfi | .B wfi | ||||
.B ... | .B ... | ||||
.PP | .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 | It can also control the IO's on the PiFace IO board and load the SPI and I2C | ||||
kernel modules if required. | 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 | .SH OPTIONS | ||||
.TP | .TP | ||||
@@ -90,15 +79,14 @@ Output the current version including the board revision of the Raspberry Pi. | |||||
.TP | .TP | ||||
.B \-g | .B \-g | ||||
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. | 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 | .TP | ||||
.B \-1 | .B \-1 | ||||
Use the physical pin numbers rather than wiringPi pin numbers. | 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 | \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 | 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 | .TP | ||||
.B \-x extension | .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. | The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR. | ||||
.TP | .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> | .B wfi <pin> <mode> | ||||
This set the given pin to the supplied interrupt mode: rising, falling | 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, | 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 | .PP | ||||
gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness | gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness | ||||
.PP | .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) | gpio -g read 0 # Read GPIO Pin 0 (SDA0) | ||||
.SH "NOTES" | .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, | 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 | 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 | 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" | .SH "SEE ALSO" | ||||
.LP | .LP | ||||
WiringPi's home page | |||||
WiringPi's development | |||||
.IP | .IP | ||||
https://github.com/WiringPi/WiringPi/ | https://github.com/WiringPi/WiringPi/ | ||||
.SH AUTHOR | .SH AUTHOR | ||||
Gordon Henderson | |||||
Gordon Henderson and contributors | |||||
.SH "REPORTING BUGS" | .SH "REPORTING BUGS" | ||||
@@ -340,7 +279,8 @@ Please report bugs to https://github.com/WiringPi/WiringPi/issues | |||||
.SH COPYRIGHT | .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 | This is free software; see the source for copying conditions. There is NO | ||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
@@ -72,8 +72,8 @@ char *usage = "Usage: gpio -v\n" | |||||
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n" | " gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n" | ||||
" gpio <toggle/blink> <pin>\n" | " gpio <toggle/blink> <pin>\n" | ||||
" gpio readall\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 wfi <pin> <mode>\n" | ||||
" gpio drive <group> <value>\n" | " gpio drive <group> <value>\n" | ||||
" gpio pwm-bal/pwm-ms \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. | " 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 | #ifdef NOT_FOR_NOW | ||||
/* | /* | ||||
* decodePin: | * decodePin: | ||||
@@ -290,13 +281,33 @@ static void doLoad (int argc, char *argv []) | |||||
if (!moduleLoaded (module1)) | if (!moduleLoaded (module1)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; | 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)) | if (!moduleLoaded (module2)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; | 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)) | if (!moduleLoaded (module2)) | ||||
@@ -350,13 +361,33 @@ static void doUnLoad (int argc, char *argv []) | |||||
if (moduleLoaded (module1)) | if (moduleLoaded (module1)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), 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)) | if (moduleLoaded (module2)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), 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 | * 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 | * gpio export pin mode | ||||
* This uses the /sys/class/gpio device interface. | * 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: | * doWfi: | ||||
@@ -562,15 +456,14 @@ static volatile int globalCounter ; | |||||
void printgpioflush(const char* text) { | void printgpioflush(const char* text) { | ||||
if (gpioDebug) { | if (gpioDebug) { | ||||
printf(text); | |||||
printf("%s", text); | |||||
fflush(stdout); | fflush(stdout); | ||||
} | } | ||||
} | } | ||||
void printgpio(const char* text) { | void printgpio(const char* text) { | ||||
if (gpioDebug) { | if (gpioDebug) { | ||||
printf(text); | |||||
fflush(stdout); | |||||
printf("%s", text); | |||||
} | } | ||||
} | } | ||||
@@ -620,7 +513,7 @@ void doWfi (int argc, char *argv []) | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
printgpio("wait for interrupt function call \n"); | |||||
printgpio("wait for interrupt function call\n"); | |||||
for (int Sec=0; Sec<timeoutSec; ++Sec) { | for (int Sec=0; Sec<timeoutSec; ++Sec) { | ||||
printgpioflush("."); | printgpioflush("."); | ||||
delay (999); | delay (999); | ||||
@@ -630,142 +523,29 @@ void doWfi (int argc, char *argv []) | |||||
} | } | ||||
/* | /* | ||||
* doEdge: | |||||
* doEdge: -> deprecated, removed | |||||
* gpio edge pin mode | * gpio edge pin mode | ||||
* Easy access to changing the edge trigger on a GPIO pin | * Easy access to changing the edge trigger on a GPIO pin | ||||
* This uses the /sys/class/gpio device interface. | * 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 | * gpio unexport pin | ||||
* This uses the /sys/class/gpio device interface. | * 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 | * gpio unexportall | ||||
* Un-Export all the GPIO pins. | * Un-Export all the GPIO pins. | ||||
* This uses the /sys/class/gpio device interface. | * 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: | * doReset: | ||||
@@ -1358,29 +1138,52 @@ static void doVersion (char *argv []) | |||||
printf ("\n") ; | printf ("\n") ; | ||||
piBoardId (&model, &rev, &mem, &maker, &warranty) ; | 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", | printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", | ||||
piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; | piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; | ||||
// Check for device tree | // 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 (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type | ||||
{ | { | ||||
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) | 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) ; | 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) ; | 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: | // Check for load command: | ||||
@@ -1,3 +1,3 @@ | |||||
#define VERSION "3.2" | |||||
#define VERSION "3.4" | |||||
#define VERSION_MAJOR 3 | #define VERSION_MAJOR 3 | ||||
#define VERSION_MINOR 2 | |||||
#define VERSION_MINOR 4 |
@@ -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); | |||||
} | |||||
} | } | ||||
/* | /* | ||||
@@ -24,6 +24,7 @@ | |||||
*/ | */ | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <stdio.h> | |||||
#include "wiringPi.h" | #include "wiringPi.h" | ||||
#include "wiringPiI2C.h" | #include "wiringPiI2C.h" | ||||
@@ -41,7 +42,10 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int val | |||||
unsigned char b [2] ; | unsigned char b [2] ; | ||||
b [0] = 0x40 ; | b [0] = 0x40 ; | ||||
b [1] = value & 0xFF ; | 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"); | |||||
} | |||||
} | } | ||||
@@ -35,9 +35,12 @@ | |||||
#define SHARED_NAME "wiringPiPseudoPins" | #define SHARED_NAME "wiringPiPseudoPins" | ||||
#define PSEUDO_PINS 64 | #define PSEUDO_PINS 64 | ||||
#include <stdio.h> | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <fcntl.h> | |||||
#include <stdint.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
@@ -45,21 +48,20 @@ | |||||
#include "pseudoPins.h" | #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; | |||||
} | } |
@@ -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 |
@@ -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); | |||||
} | |||||
@@ -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); | |||||
} |
@@ -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); | |||||
} |
@@ -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); | |||||
} |
@@ -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); | |||||
} | |||||
@@ -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 ; | |||||
} |
@@ -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); | |||||
} |
@@ -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 ); | |||||
} | |||||
} |
@@ -395,10 +395,23 @@ int wiringPiReturnCodes = FALSE ; | |||||
int wiringPiTryGpioMem = 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, | ||||
-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, | -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 | 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() { | 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() { | int FailOnModel5() { | ||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" | return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" | ||||
@@ -857,12 +831,12 @@ static void usingGpioMemCheck (const char *what) | |||||
void PrintSystemStdErr () { | void PrintSystemStdErr () { | ||||
struct utsname sys_info; | struct utsname sys_info; | ||||
if (uname(&sys_info) == 0) { | 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) { | 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") ; | 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) ; | 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: | * piGpioLayout: | ||||
@@ -923,10 +901,7 @@ void piGpioLayoutOops (const char *why) | |||||
int piGpioLayout (void) | int piGpioLayout (void) | ||||
{ | { | ||||
if (-1==RaspberryPiLayout) { | |||||
int model, rev, mem, maker, overVolted ; | |||||
piBoardId (&model, &rev, &mem, &maker, &overVolted) ; | |||||
} | |||||
piBoard(); | |||||
return RaspberryPiLayout; | return RaspberryPiLayout; | ||||
} | } | ||||
@@ -1135,6 +1110,37 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) | |||||
} | } | ||||
RaspberryPiModel = *model; | 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 (PI_MODEL_5 == RaspberryPiModel) { | ||||
if (-1==group) { | if (-1==group) { | ||||
printf ("Pad register:\n"); | 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; | 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) ; | 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 | if (group !=0) { // only GPIO range @RP1 | ||||
return ; | return ; | ||||
} | |||||
} | |||||
switch(value) { | switch(value) { | ||||
default: | |||||
default: | |||||
/* bcm*/ // RP1 | /* bcm*/ // RP1 | ||||
case 0: /* 2mA*/ value=0; break; // 2mA | case 0: /* 2mA*/ value=0; break; // 2mA | ||||
case 1: /* 4mA*/ | case 1: /* 4mA*/ | ||||
@@ -1214,9 +1220,9 @@ void setPadDrive (int group, int value) | |||||
case 6: /*14mA*/ | case 6: /*14mA*/ | ||||
case 7: /*16mA*/ value=3; break; //12mA | 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 | //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; | pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal; | ||||
} | } | ||||
rdVal = pads[1+17]; // only pin 17 readback, for logging | 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)) | if ((group < 0) || (group > 2)) | ||||
return ; | return ; | ||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7 | |||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7 | |||||
*(pads + group + 11) = wrVal ; | *(pads + group + 11) = wrVal ; | ||||
rdVal = *(pads + group + 11); | rdVal = *(pads + group + 11); | ||||
} | } | ||||
@@ -1525,6 +1531,65 @@ void pinEnableED01Pi (int pin) | |||||
#endif | #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 | * Core Functions | ||||
@@ -1555,7 +1620,7 @@ void pinModeAlt (int pin, int mode) | |||||
if (PI_MODEL_5 == RaspberryPiModel) { | 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 | "alt0" 0b100 | ||||
"alt1" 0b101 | "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); | 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) | void pinMode (int pin, int mode) | ||||
{ | { | ||||
int fSel, shift, alt ; | int fSel, shift, alt ; | ||||
@@ -1595,18 +1689,34 @@ void pinMode (int pin, int mode) | |||||
int origPin = pin ; | int origPin = pin ; | ||||
if (wiringPiDebug) | if (wiringPiDebug) | ||||
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ; | |||||
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ; | |||||
setupCheck ("pinMode") ; | setupCheck ("pinMode") ; | ||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin | 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) | if (wiringPiDebug) | ||||
printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ; | printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ; | ||||
@@ -1618,7 +1728,7 @@ void pinMode (int pin, int mode) | |||||
shift = gpioToShift [pin] ; | shift = gpioToShift [pin] ; | ||||
if (mode == INPUT) { | 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; | pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; | ||||
gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO | gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO | ||||
rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input | rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input | ||||
@@ -1646,7 +1756,7 @@ void pinMode (int pin, int mode) | |||||
{ | { | ||||
RETURN_ON_MODEL5 | RETURN_ON_MODEL5 | ||||
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin | if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin | ||||
return ; | |||||
return ; | |||||
usingGpioMemCheck ("pinMode PWM") ; | usingGpioMemCheck ("pinMode PWM") ; | ||||
@@ -1663,7 +1773,7 @@ void pinMode (int pin, int mode) | |||||
{ | { | ||||
RETURN_ON_MODEL5 | RETURN_ON_MODEL5 | ||||
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin | if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin | ||||
return ; | |||||
return ; | |||||
usingGpioMemCheck ("pinMode CLOCK") ; | usingGpioMemCheck ("pinMode CLOCK") ; | ||||
@@ -1688,6 +1798,28 @@ void pinMode (int pin, int mode) | |||||
* Control the internal pull-up/down resistors on a GPIO pin. | * 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) | 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 ((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) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits | 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 pullbits; | ||||
unsigned int pull; | 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 */ | default: return ; /* An illegal value */ | ||||
} | } | ||||
@@ -1755,26 +1898,58 @@ void pullUpDnControl (int pin, int pud) | |||||
} | } | ||||
/* | /* | ||||
* digitalRead: | * digitalRead: | ||||
* Read the value of a given Pin, returning HIGH or LOW | * 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) | int digitalRead (int pin) | ||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | 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) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) { | 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) | void digitalWrite (int pin, int value) | ||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | 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 (PI_MODEL_5 == RaspberryPiModel) { | ||||
if (value == LOW) { | if (value == LOW) { | ||||
//printf("Set pin %d >>0x%08x<< to low\n", pin, 1<<pin); | //printf("Set pin %d >>0x%08x<< to low\n", pin, 1<<pin); | ||||
rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin; | rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin; | ||||
} else { | } else { | ||||
//printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin); | //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 { | } else { | ||||
if (value == LOW) | if (value == LOW) | ||||
@@ -2101,7 +2316,7 @@ unsigned int digitalReadByte2 (void) | |||||
int waitForInterrupt (int pin, int mS) | int waitForInterrupt (int pin, int mS) | ||||
{ | { | ||||
int fd, ret; | |||||
int fd, ret; | |||||
struct pollfd polls ; | struct pollfd polls ; | ||||
struct gpioevent_data evdata; | struct gpioevent_data evdata; | ||||
//struct gpio_v2_line_request req2; | //struct gpio_v2_line_request req2; | ||||
@@ -2111,7 +2326,7 @@ int waitForInterrupt (int pin, int mS) | |||||
else if (wiringPiMode == WPI_MODE_PHYS) | else if (wiringPiMode == WPI_MODE_PHYS) | ||||
pin = physToGpio [pin] ; | pin = physToGpio [pin] ; | ||||
if ((fd = sysFds [pin]) == -1) | |||||
if ((fd = isrFds [pin]) == -1) | |||||
return -2 ; | return -2 ; | ||||
// Setup poll structure | // Setup poll structure | ||||
@@ -2124,12 +2339,12 @@ int waitForInterrupt (int pin, int mS) | |||||
if (ret <= 0) { | if (ret <= 0) { | ||||
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); | fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); | ||||
} else { | } else { | ||||
//if (polls.revents & POLLIN) | |||||
//if (polls.revents & POLLIN) | |||||
if (wiringPiDebug) { | 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 */ | /* read event data */ | ||||
int readret = read(sysFds [pin], &evdata, sizeof(evdata)); | |||||
int readret = read(isrFds [pin], &evdata, sizeof(evdata)); | |||||
if (readret == sizeof(evdata)) { | if (readret == sizeof(evdata)) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ; | 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; | return ret; | ||||
} | } | ||||
const char DEV_GPIO_PI[] ="/dev/gpiochip0"; | |||||
const char DEV_GPIO_PI5[]="/dev/gpiochip4"; | |||||
int waitForInterruptInit (int pin, int mode) | int waitForInterruptInit (int pin, int mode) | ||||
{ | { | ||||
const char* strmode = ""; | const char* strmode = ""; | ||||
@@ -2157,16 +2369,8 @@ int waitForInterruptInit (int pin, int mode) | |||||
/* open gpio */ | /* open gpio */ | ||||
sleep(1); | 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; | struct gpioevent_request req; | ||||
@@ -2197,7 +2401,7 @@ int waitForInterruptInit (int pin, int mode) | |||||
//later implement GPIO_V2_GET_LINE_IOCTL req2 | //later implement GPIO_V2_GET_LINE_IOCTL req2 | ||||
int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req); | int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req); | ||||
if (ret) { | 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; | return -1; | ||||
} | } | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
@@ -2206,12 +2410,12 @@ int waitForInterruptInit (int pin, int mode) | |||||
/* set event fd nonbloack read */ | /* set event fd nonbloack read */ | ||||
int fd_line = req.fd; | int fd_line = req.fd; | ||||
sysFds [pin] = fd_line; | |||||
isrFds [pin] = fd_line; | |||||
int flags = fcntl(fd_line, F_GETFL); | int flags = fcntl(fd_line, F_GETFL); | ||||
flags |= O_NONBLOCK; | flags |= O_NONBLOCK; | ||||
ret = fcntl(fd_line, F_SETFL, flags); | ret = fcntl(fd_line, F_SETFL, flags); | ||||
if (ret) { | 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; | return -1; | ||||
} | } | ||||
@@ -2220,10 +2424,10 @@ int waitForInterruptInit (int pin, int mode) | |||||
int waitForInterruptClose (int pin) { | int waitForInterruptClose (int pin) { | ||||
if (sysFds[pin]>0) { | |||||
if (isrFds[pin]>0) { | |||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; | printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; | ||||
} | |||||
} | |||||
if (pthread_cancel(isrThreads[pin]) == 0) { | if (pthread_cancel(isrThreads[pin]) == 0) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; | printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; | ||||
@@ -2233,9 +2437,9 @@ int waitForInterruptClose (int pin) { | |||||
fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); | fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n"); | ||||
} | } | ||||
} | } | ||||
close(sysFds [pin]); | |||||
close(isrFds [pin]); | |||||
} | } | ||||
sysFds [pin] = -1; | |||||
isrFds [pin] = -1; | |||||
isrFunctions [pin] = NULL; | isrFunctions [pin] = NULL; | ||||
/* -not closing so far - other isr may be using it - only close if no other is using - will code later | /* -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(waitForInterruptInit (pin, mode)<0) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; | fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; | ||||
} | |||||
} | |||||
}; | }; | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
@@ -2522,6 +2726,7 @@ int wiringPiUserLevelAccess(void) | |||||
struct stat statBuf ; | struct stat statBuf ; | ||||
const char* gpiomemModule = gpiomem_BCM; | const char* gpiomemModule = gpiomem_BCM; | ||||
piBoard(); | |||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
gpiomemModule = gpiomem_RP1; | 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: | * wiringPiSetup: | ||||
* Must be called once at the start of your program execution. | * Must be called once at the start of your program execution. | ||||
@@ -2586,40 +2843,6 @@ int wiringPiSetup (void) | |||||
physToGpio = physToGpioR2 ; | 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 | // Open the master /dev/ memory control device | ||||
// Device strategy: December 2016: | // Device strategy: December 2016: | ||||
// Try /dev/mem. If that fails, then | // Try /dev/mem. If that fails, then | ||||
@@ -2633,9 +2856,12 @@ int wiringPiSetup (void) | |||||
gpiomemModule = gpiomem_RP1; | gpiomemModule = gpiomem_RP1; | ||||
} | } | ||||
usingGpioMem = FALSE; | |||||
if (gpiomemGlobal==NULL || (fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) < 0) | 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 | if (gpiomemModule && (fd = open (gpiomemModule, O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem | ||||
{ | { | ||||
piGpioBase = 0 ; | piGpioBase = 0 ; | ||||
@@ -2648,7 +2874,7 @@ int wiringPiSetup (void) | |||||
" Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ; | " Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ; | ||||
} | } | ||||
if (wiringPiDebug) { | 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: | // GPIO: | ||||
if (PI_MODEL_5 != model) { | if (PI_MODEL_5 != model) { | ||||
@@ -2709,7 +2935,7 @@ int wiringPiSetup (void) | |||||
_wiringPiPads = pads ; | _wiringPiPads = pads ; | ||||
_wiringPiTimer = timer ; | _wiringPiTimer = timer ; | ||||
_wiringPiRio = NULL ; | _wiringPiRio = NULL ; | ||||
} else { | |||||
} else { | |||||
unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; | unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; | ||||
GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; | GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; | ||||
@@ -2800,21 +3026,76 @@ int wiringPiSetupPhys (void) | |||||
return 0 ; | 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: | * wiringPiSetupSys: | ||||
* GPIO Sysfs Interface for Userspace is deprecated | * GPIO Sysfs Interface for Userspace is deprecated | ||||
* https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html | * 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) | 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); | |||||
} | } |
@@ -46,12 +46,15 @@ | |||||
// wiringPi modes | // 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 | // Pin modes | ||||
@@ -62,6 +65,7 @@ | |||||
#define SOFT_PWM_OUTPUT 4 | #define SOFT_PWM_OUTPUT 4 | ||||
#define SOFT_TONE_OUTPUT 5 | #define SOFT_TONE_OUTPUT 5 | ||||
#define PWM_TONE_OUTPUT 6 | #define PWM_TONE_OUTPUT 6 | ||||
#define PM_OFF 7 // to input / release line | |||||
#define LOW 0 | #define LOW 0 | ||||
#define HIGH 1 | #define HIGH 1 | ||||
@@ -205,15 +209,23 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; | |||||
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; | extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; | ||||
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; | 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 void wiringPiVersion (int *major, int *minor) ; | ||||
extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3 | |||||
extern int wiringPiUserLevelAccess (void) ; | extern int wiringPiUserLevelAccess (void) ; | ||||
extern int wiringPiSetup (void) ; | extern int wiringPiSetup (void) ; | ||||
extern int wiringPiSetupSys (void) ; | extern int wiringPiSetupSys (void) ; | ||||
extern int wiringPiSetupGpio (void) ; | extern int wiringPiSetupGpio (void) ; | ||||
extern int wiringPiSetupPhys (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 pinModeAlt (int pin, int mode) ; | ||||
extern void pinMode (int pin, int mode) ; | extern void pinMode (int pin, int mode) ; | ||||
extern void pullUpDnControl (int pin, int pud) ; | extern void pullUpDnControl (int pin, int pud) ; | ||||
@@ -47,7 +47,7 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdint.h> | |||||
#include <unistd.h> | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
@@ -154,6 +154,26 @@ int wiringPiI2CReadReg16 (int fd, int reg) | |||||
return data.word & 0xFFFF ; | 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: | * 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) ; | 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: | * wiringPiI2CSetupInterface: | ||||
@@ -22,6 +22,8 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <stdint.h> | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
@@ -29,10 +31,14 @@ extern "C" { | |||||
extern int wiringPiI2CRead (int fd) ; | extern int wiringPiI2CRead (int fd) ; | ||||
extern int wiringPiI2CReadReg8 (int fd, int reg) ; | extern int wiringPiI2CReadReg8 (int fd, int reg) ; | ||||
extern int wiringPiI2CReadReg16 (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 wiringPiI2CWrite (int fd, int data) ; | ||||
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; | extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; | ||||
extern int wiringPiI2CWriteReg16 (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 wiringPiI2CSetupInterface (const char *device, int devId) ; | ||||
extern int wiringPiI2CSetup (const int devId) ; | extern int wiringPiI2CSetup (const int devId) ; | ||||
@@ -186,66 +186,3 @@ int piGpioLayoutLegacy (void) | |||||
return gpioLayout ; | 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 ; | |||||
} | |||||
*/ |
@@ -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"); | |||||
} | |||||
} | } | ||||
/* | /* | ||||