@@ -84,12 +84,19 @@ int main (void)
|
||||
pinMode (11, OUTPUT) ;
|
||||
speedTest (11, FAST_COUNT) ;
|
||||
|
||||
// Switch to SYS mode:
|
||||
// Switch to SYS mode: -> character device ABI
|
||||
|
||||
system ("/usr/local/bin/gpio export 17 out") ;
|
||||
printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
|
||||
wiringPiSetupSys () ;
|
||||
speedTest (17, SLOW_COUNT) ;
|
||||
|
||||
// character device ABI
|
||||
|
||||
printf ("\ncharacter device ABI method: (%8d iterations)\n", SLOW_COUNT) ;
|
||||
wiringPiSetupGpioDevice () ;
|
||||
pinMode (17, OUTPUT) ;
|
||||
speedTest (17, SLOW_COUNT) ;
|
||||
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
72
gpio/gpio.1
72
gpio/gpio.1
@@ -29,13 +29,6 @@ gpio \- Command-line access to Raspberry Pi's GPIO
|
||||
.B readall
|
||||
.PP
|
||||
.B gpio
|
||||
.B unexportall/exports
|
||||
.PP
|
||||
.B gpio
|
||||
.B export/edge/unexport
|
||||
.B ...
|
||||
.PP
|
||||
.B gpio
|
||||
.B wfi
|
||||
.B ...
|
||||
.PP
|
||||
@@ -77,10 +70,6 @@ somewhat slow control of the GPIO pins.
|
||||
It can also control the IO's on the PiFace IO board and load the SPI and I2C
|
||||
kernel modules if required.
|
||||
|
||||
Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR
|
||||
system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR
|
||||
interface without needing to be run as root.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
@@ -90,15 +79,14 @@ Output the current version including the board revision of the Raspberry Pi.
|
||||
.TP
|
||||
.B \-g
|
||||
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
|
||||
\fINote:\fR The BCM_GPIO pin numbers are always used with the
|
||||
export and edge commands.
|
||||
.\" \fINote:\fR The BCM_GPIO pin numbers are always used with character device ABI.
|
||||
|
||||
.TP
|
||||
.B \-1
|
||||
Use the physical pin numbers rather than wiringPi pin numbers.
|
||||
\fINote:\fR that this applies to the P1 connector only. It is not possible to
|
||||
use pins on the Revision 2 P5 connector this way, and as with \-g the
|
||||
BCM_GPIO pin numbers are always used with the export and edge commands.
|
||||
.\" BCM_GPIO pin numbers are always used with character device ABI.
|
||||
|
||||
.TP
|
||||
.B \-x extension
|
||||
@@ -190,47 +178,6 @@ pull-up, pull-down or tristate (off) controls.
|
||||
|
||||
The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR.
|
||||
|
||||
.TP
|
||||
.B unexportall
|
||||
Un-Export all the GPIO pins in the /sys/class/gpio directory.
|
||||
|
||||
.TP
|
||||
.B exports
|
||||
Print a list (if any) of all the exported GPIO pins and their current values.
|
||||
|
||||
.TP
|
||||
.B export
|
||||
Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the
|
||||
mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and
|
||||
\fRlow\fR are supported at this time. Note that the pin number is the
|
||||
\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and
|
||||
\fIlow\fR commands pre-set the output value at the same time as the
|
||||
export to output mode.
|
||||
|
||||
Once a GPIO pin has been exported, the \fBgpio\fR program changes the
|
||||
ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in
|
||||
later kernels, the \fI/sys/class/gpio/gpioX/edge\fR pseudo files to
|
||||
that of the user running the \fBgpio\fR program. This means that you
|
||||
can have a small script of gpio exports to setup the gpio pins as your
|
||||
program requires without the need to run anything as root, or with the
|
||||
sudo command.
|
||||
|
||||
.TP
|
||||
.B edge
|
||||
This exports a GPIO pin in the \fI/sys/class/gpio\fR directory, set
|
||||
the direction to input and set the edge interrupt method to \fInone\fR,
|
||||
\fIrising\fR, \fIfalling\fR or \fIboth\fR. Use like the export command
|
||||
above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin
|
||||
numbering.
|
||||
|
||||
Like the export commands above, ownership is set to that of the
|
||||
calling user, allowing subsequent access from user programs without
|
||||
requiring root/sudo.
|
||||
|
||||
.TP
|
||||
.B unexport
|
||||
Un-Export a GPIO pin in the /sys/class/gpio directory.
|
||||
|
||||
.TP
|
||||
.B wfi <pin> <mode>
|
||||
This set the given pin to the supplied interrupt mode: rising, falling
|
||||
@@ -299,18 +246,10 @@ gpio mode 1 pwm # Set pin 1 to PWM mode
|
||||
.PP
|
||||
gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness
|
||||
.PP
|
||||
gpio export 17 out # Set GPIO Pin 17 to output
|
||||
.PP
|
||||
gpio export 0 in # Set GPIO Pin 0 (SDA0) to input.
|
||||
.PP
|
||||
gpio -g read 0 # Read GPIO Pin 0 (SDA0)
|
||||
|
||||
.SH "NOTES"
|
||||
|
||||
When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the
|
||||
pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi
|
||||
pin numbers.
|
||||
|
||||
As of kernels 4.1.7, a user-level GPIO access mechanism is available,
|
||||
however wiringPi will not use this by default - because at this time
|
||||
there appears to be issues when trying to program the PWM or clock output
|
||||
@@ -326,13 +265,13 @@ in future releases once the /dev/gpiomem interface is fully operational.
|
||||
.SH "SEE ALSO"
|
||||
|
||||
.LP
|
||||
WiringPi's home page
|
||||
WiringPi's development
|
||||
.IP
|
||||
https://github.com/WiringPi/WiringPi/
|
||||
|
||||
.SH AUTHOR
|
||||
|
||||
Gordon Henderson
|
||||
Gordon Henderson and contributors
|
||||
|
||||
.SH "REPORTING BUGS"
|
||||
|
||||
@@ -340,7 +279,8 @@ Please report bugs to https://github.com/WiringPi/WiringPi/issues
|
||||
|
||||
.SH COPYRIGHT
|
||||
|
||||
Copyright (c) 2012-2018 Gordon Henderson
|
||||
Copyright (c) 2012-2024 Gordon Henderson and contributors
|
||||
.br
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
393
gpio/gpio.c
393
gpio/gpio.c
@@ -72,8 +72,8 @@ char *usage = "Usage: gpio -v\n"
|
||||
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
|
||||
" gpio <toggle/blink> <pin>\n"
|
||||
" gpio readall\n"
|
||||
" gpio unexportall/exports\n"
|
||||
" gpio export/edge/unexport ...\n"
|
||||
// " gpio unexportall/exports\n"
|
||||
// " gpio export/edge/unexport ...\n"
|
||||
" gpio wfi <pin> <mode>\n"
|
||||
" gpio drive <group> <value>\n"
|
||||
" gpio pwm-bal/pwm-ms \n"
|
||||
@@ -89,15 +89,6 @@ char *usage = "Usage: gpio -v\n"
|
||||
" gpio gbw <channel> <value>" ; // No trailing newline needed here.
|
||||
|
||||
|
||||
int GPIOToSysFS_ExitonFail (const int pin, const char* name) {
|
||||
int pinFS = GPIOToSysFS(pin);
|
||||
if (pinFS<0) {
|
||||
fprintf (stderr, "%s: invalid sysfs pin of bcm pin %d\n", name, pin) ;
|
||||
exit (1) ;
|
||||
}
|
||||
return pinFS;
|
||||
}
|
||||
|
||||
#ifdef NOT_FOR_NOW
|
||||
/*
|
||||
* decodePin:
|
||||
@@ -290,13 +281,33 @@ static void doLoad (int argc, char *argv [])
|
||||
if (!moduleLoaded (module1))
|
||||
{
|
||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
|
||||
system (cmd) ;
|
||||
int ret = system(cmd);
|
||||
if (ret == -1) {
|
||||
perror("Error executing command");
|
||||
} else if (WIFEXITED(ret)) {
|
||||
int exit_status = WEXITSTATUS(ret);
|
||||
if (exit_status != 0) {
|
||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Command terminated by signal\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!moduleLoaded (module2))
|
||||
{
|
||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
|
||||
system (cmd) ;
|
||||
int ret = system(cmd);
|
||||
if (ret == -1) {
|
||||
perror("Error executing command");
|
||||
} else if (WIFEXITED(ret)) {
|
||||
int exit_status = WEXITSTATUS(ret);
|
||||
if (exit_status != 0) {
|
||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Command terminated by signal\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!moduleLoaded (module2))
|
||||
@@ -350,13 +361,33 @@ static void doUnLoad (int argc, char *argv [])
|
||||
if (moduleLoaded (module1))
|
||||
{
|
||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
|
||||
system (cmd) ;
|
||||
int ret = system(cmd);
|
||||
if (ret == -1) {
|
||||
perror("Error executing command");
|
||||
} else if (WIFEXITED(ret)) {
|
||||
int exit_status = WEXITSTATUS(ret);
|
||||
if (exit_status != 0) {
|
||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Command terminated by signal\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleLoaded (module2))
|
||||
{
|
||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
|
||||
system (cmd) ;
|
||||
int ret = system(cmd);
|
||||
if (ret == -1) {
|
||||
perror("Error executing command");
|
||||
} else if (WIFEXITED(ret)) {
|
||||
int exit_status = WEXITSTATUS(ret);
|
||||
if (exit_status != 0) {
|
||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Command terminated by signal\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,160 +423,23 @@ static void doI2Cdetect (UNU int argc, char *argv [])
|
||||
}
|
||||
|
||||
|
||||
void SYSFS_DEPRECATED(const char *progName) {
|
||||
fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName);
|
||||
}
|
||||
|
||||
/*
|
||||
* doExports:
|
||||
* doExports: -> deprecated, removed
|
||||
* List all GPIO exports
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void doExports (UNU int argc, UNU char *argv [])
|
||||
{
|
||||
int fd ;
|
||||
int pin, l, first ;
|
||||
char fName [128] ;
|
||||
char buf [16] ;
|
||||
|
||||
for (first = 0, pin = 0 ; pin < 64 ; ++pin) // Crude, but effective
|
||||
{
|
||||
|
||||
// Try to read the direction
|
||||
int pinFS = GPIOToSysFS(pin);
|
||||
if (pinFS<0) {
|
||||
continue;
|
||||
}
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ;
|
||||
if ((fd = open (fName, O_RDONLY)) == -1)
|
||||
continue ;
|
||||
|
||||
if (first == 0)
|
||||
{
|
||||
++first ;
|
||||
printf ("GPIO Pins exported:\n") ;
|
||||
}
|
||||
|
||||
if(pinFS==pin) {
|
||||
printf ("%4d: ", pin) ;
|
||||
} else {
|
||||
printf ("%4d (%4d): ", pin, pinFS) ;
|
||||
}
|
||||
|
||||
if ((l = read (fd, buf, 16)) == 0)
|
||||
sprintf (buf, "%s", "?") ;
|
||||
|
||||
buf [l] = 0 ;
|
||||
if ((buf [strlen (buf) - 1]) == '\n')
|
||||
buf [strlen (buf) - 1] = 0 ;
|
||||
|
||||
printf ("%-3s", buf) ;
|
||||
|
||||
close (fd) ;
|
||||
|
||||
// Try to Read the value
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
|
||||
if ((fd = open (fName, O_RDONLY)) == -1)
|
||||
{
|
||||
printf ("No Value file (huh?)\n") ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
if ((l = read (fd, buf, 16)) == 0)
|
||||
sprintf (buf, "%s", "?") ;
|
||||
|
||||
buf [l] = 0 ;
|
||||
if ((buf [strlen (buf) - 1]) == '\n')
|
||||
buf [strlen (buf) - 1] = 0 ;
|
||||
|
||||
printf (" %s", buf) ;
|
||||
|
||||
// Read any edge trigger file
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
|
||||
if ((fd = open (fName, O_RDONLY)) == -1)
|
||||
{
|
||||
printf ("\n") ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
if ((l = read (fd, buf, 16)) == 0)
|
||||
sprintf (buf, "%s", "?") ;
|
||||
|
||||
buf [l] = 0 ;
|
||||
if ((buf [strlen (buf) - 1]) == '\n')
|
||||
buf [strlen (buf) - 1] = 0 ;
|
||||
|
||||
printf (" %-8s\n", buf) ;
|
||||
|
||||
close (fd) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExport:
|
||||
* doExport: -> deprecated, removed
|
||||
* gpio export pin mode
|
||||
* This uses the /sys/class/gpio device interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void doExport (int argc, char *argv [])
|
||||
{
|
||||
FILE *fd ;
|
||||
int pin ;
|
||||
char *mode ;
|
||||
char fName [128] ;
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
pin = atoi (argv [2]) ;
|
||||
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);
|
||||
mode = argv [3] ;
|
||||
|
||||
if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
fprintf (fd, "%d\n", pinFS) ;
|
||||
fclose (fd) ;
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ;
|
||||
if ((fd = fopen (fName, "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
|
||||
fprintf (fd, "in\n") ;
|
||||
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
|
||||
fprintf (fd, "out\n") ;
|
||||
else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
|
||||
fprintf (fd, "high\n") ;
|
||||
else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
|
||||
fprintf (fd, "low\n") ;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
fclose (fd) ;
|
||||
|
||||
// Change ownership so the current user can actually use it
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
|
||||
changeOwner (argv [0], fName) ;
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
|
||||
changeOwner (argv [0], fName) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doWfi:
|
||||
@@ -562,15 +456,14 @@ static volatile int globalCounter ;
|
||||
|
||||
void printgpioflush(const char* text) {
|
||||
if (gpioDebug) {
|
||||
printf(text);
|
||||
printf("%s", text);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void printgpio(const char* text) {
|
||||
if (gpioDebug) {
|
||||
printf(text);
|
||||
fflush(stdout);
|
||||
printf("%s", text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,7 +513,7 @@ void doWfi (int argc, char *argv [])
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
printgpio("wait for interrupt function call \n");
|
||||
printgpio("wait for interrupt function call\n");
|
||||
for (int Sec=0; Sec<timeoutSec; ++Sec) {
|
||||
printgpioflush(".");
|
||||
delay (999);
|
||||
@@ -630,142 +523,29 @@ void doWfi (int argc, char *argv [])
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* doEdge:
|
||||
* doEdge: -> deprecated, removed
|
||||
* gpio edge pin mode
|
||||
* Easy access to changing the edge trigger on a GPIO pin
|
||||
* This uses the /sys/class/gpio device interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void doEdge (int argc, char *argv [])
|
||||
{
|
||||
FILE *fd ;
|
||||
int pin ;
|
||||
char *mode ;
|
||||
char fName [128] ;
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
pin = atoi (argv [2]) ;
|
||||
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);
|
||||
mode = argv [3] ;
|
||||
|
||||
// Export the pin and set direction to input
|
||||
|
||||
if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
fprintf (fd, "%d\n", pinFS) ;
|
||||
fclose (fd) ;
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/direction", pinFS) ;
|
||||
if ((fd = fopen (fName, "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
fprintf (fd, "in\n") ;
|
||||
fclose (fd) ;
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
|
||||
if ((fd = fopen (fName, "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
/**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
|
||||
else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
|
||||
else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
|
||||
else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
// Change ownership of the value and edge files, so the current user can actually use it!
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
|
||||
changeOwner (argv [0], fName) ;
|
||||
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pinFS) ;
|
||||
changeOwner (argv [0], fName) ;
|
||||
|
||||
fclose (fd) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doUnexport:
|
||||
* doUnexport: -> deprecated, removed
|
||||
* gpio unexport pin
|
||||
* This uses the /sys/class/gpio device interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void doUnexport (int argc, char *argv [])
|
||||
{
|
||||
FILE *fd ;
|
||||
int pin ;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
pin = atoi (argv [2]) ;
|
||||
int pinFS = GPIOToSysFS_ExitonFail(pin, argv [0]);
|
||||
|
||||
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
fprintf (fd, "%d\n", pinFS) ;
|
||||
fclose (fd) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doUnexportAll:
|
||||
* doUnexportAll: -> deprecated, removed
|
||||
* gpio unexportall
|
||||
* Un-Export all the GPIO pins.
|
||||
* This uses the /sys/class/gpio device interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void doUnexportall (char *progName)
|
||||
{
|
||||
FILE *fd ;
|
||||
int pin ;
|
||||
|
||||
for (pin = 0 ; pin < 63 ; ++pin)
|
||||
{
|
||||
int pinFS = GPIOToSysFS(pin);
|
||||
if (pinFS>=0) {
|
||||
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
|
||||
exit (1) ;
|
||||
}
|
||||
fprintf (fd, "%d\n", pinFS) ;
|
||||
fclose (fd) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doReset:
|
||||
@@ -1358,29 +1138,52 @@ static void doVersion (char *argv [])
|
||||
printf ("\n") ;
|
||||
piBoardId (&model, &rev, &mem, &maker, &warranty) ;
|
||||
|
||||
printf ("Raspberry Pi Details:\n") ;
|
||||
printf ("Hardware details:\n") ;
|
||||
printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
|
||||
piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
|
||||
|
||||
// Check for device tree
|
||||
|
||||
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
|
||||
printf (" * Device tree is enabled.\n") ;
|
||||
|
||||
printf ("\nSystem details:\n") ;
|
||||
if (stat ("/proc/device-tree", &statBuf) == 0) { // We're on a devtree system ...
|
||||
printf (" * Device tree present.\n") ;
|
||||
}
|
||||
if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
|
||||
{
|
||||
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
|
||||
{
|
||||
fgets (name, 80, fd) ;
|
||||
if (fgets(name, sizeof(name), fd) == NULL) {
|
||||
// Handle error or end of file condition
|
||||
perror("Error reading /proc/device-tree/model");
|
||||
}
|
||||
fclose (fd) ;
|
||||
printf (" *--> %s\n", name) ;
|
||||
printf (" Model: %s\n", name) ;
|
||||
}
|
||||
}
|
||||
|
||||
if (wiringPiUserLevelAccess()) // User level GPIO is GO
|
||||
printf (" * This Raspberry Pi supports user-level GPIO access.\n") ;
|
||||
else
|
||||
printf (" * Root or sudo required for GPIO access.\n") ;
|
||||
int bGlobalAccess = wiringPiGlobalMemoryAccess(); // User level GPIO is GO
|
||||
switch(bGlobalAccess) {
|
||||
case 0:
|
||||
printf (" * Does not support basic user-level GPIO access via memory.\n") ;
|
||||
break;
|
||||
case 1:
|
||||
printf (" * Supports basic user-level GPIO access via /dev/mem.\n") ;
|
||||
break;
|
||||
case 2:
|
||||
printf (" * Supports full user-level GPIO access via memory.\n") ;
|
||||
break;
|
||||
}
|
||||
if (wiringPiUserLevelAccess()) {
|
||||
printf (" * Supports basic user-level GPIO access via /dev/gpiomem.\n") ;
|
||||
} else {
|
||||
printf (" * Does not support basic user-level GPIO access via /dev/gpiomem.\n") ;
|
||||
if(0==bGlobalAccess) {
|
||||
printf (" * root or sudo may be required for direct GPIO access.\n") ;
|
||||
}
|
||||
}
|
||||
if (wiringPiGpioDeviceGetFd()>0) {
|
||||
printf (" * Supports basic user-level GPIO access via /dev/gpiochip (slow).\n") ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1466,13 +1269,13 @@ int main (int argc, char *argv [])
|
||||
exit (EXIT_FAILURE) ;
|
||||
}
|
||||
|
||||
// Initial test for /sys/class/gpio operations:
|
||||
// Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there
|
||||
|
||||
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
|
||||
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
|
||||
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
|
||||
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
|
||||
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
|
||||
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
|
||||
else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
|
||||
else if (strcasecmp (argv [1], "edge" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
|
||||
else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
|
||||
else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
|
||||
|
||||
// Check for load command:
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#define VERSION "3.2"
|
||||
#define VERSION "3.4"
|
||||
#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 <stdio.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
@@ -41,7 +42,10 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int val
|
||||
unsigned char b [2] ;
|
||||
b [0] = 0x40 ;
|
||||
b [1] = value & 0xFF ;
|
||||
write (node->fd, b, 2) ;
|
||||
ssize_t bytes_written = write(node->fd, b, 2);
|
||||
if (bytes_written != 2) {
|
||||
perror("Error writing to file descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,12 @@
|
||||
#define SHARED_NAME "wiringPiPseudoPins"
|
||||
#define PSEUDO_PINS 64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -45,21 +48,20 @@
|
||||
|
||||
#include "pseudoPins.h"
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
static int myAnalogRead(struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int *ptr = (int *)node->data0 ;
|
||||
int myPin = pin - node->pinBase ;
|
||||
int *ptr = (int *)(intptr_t)node->data0; // Cast to intptr_t to handle pointer-to-integer conversion
|
||||
int myPin = pin - node->pinBase;
|
||||
|
||||
return *(ptr + myPin) ;
|
||||
return *(ptr + myPin);
|
||||
}
|
||||
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
static void myAnalogWrite(struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int *ptr = (int *)node->data0 ;
|
||||
int myPin = pin - node->pinBase ;
|
||||
int *ptr = (int *)(intptr_t)node->data0;
|
||||
int myPin = pin - node->pinBase;
|
||||
|
||||
*(ptr + myPin) = value ;
|
||||
*(ptr + myPin) = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,27 +71,39 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int pseudoPinsSetup (const int pinBase)
|
||||
|
||||
int pseudoPinsSetup(const int pinBase)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
void *ptr ;
|
||||
struct wiringPiNodeStruct *node;
|
||||
void *ptr;
|
||||
|
||||
node = wiringPiNewNode (pinBase, PSEUDO_PINS) ;
|
||||
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) ;
|
||||
node->fd = shm_open(SHARED_NAME, O_CREAT | O_RDWR, 0666);
|
||||
if (node->fd < 0) {
|
||||
perror("Error opening shared memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (node->fd < 0)
|
||||
return FALSE ;
|
||||
if (ftruncate(node->fd, PSEUDO_PINS * sizeof(int)) < 0) {
|
||||
perror("Error resizing shared memory");
|
||||
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);
|
||||
if (ptr == MAP_FAILED) {
|
||||
perror("Error mapping shared memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ;
|
||||
node->data0 = (unsigned int)(uintptr_t)ptr;
|
||||
|
||||
node->data0 = (unsigned int)ptr ;
|
||||
node->analogRead = myAnalogRead;
|
||||
node->analogWrite = myAnalogWrite;
|
||||
|
||||
node->analogRead = myAnalogRead ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
return TRUE ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
38
wiringPi/test/Makefile
Normal file
38
wiringPi/test/Makefile
Normal file
@@ -0,0 +1,38 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall
|
||||
LDFLAGS =
|
||||
|
||||
tests = wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_version
|
||||
|
||||
all: $(tests)
|
||||
|
||||
wiringpi_test1_sysfs:
|
||||
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi
|
||||
|
||||
wiringpi_test2_sysfs:
|
||||
${CC} ${CFLAGS} wiringpi_test2_sysfs.c -o wiringpi_test2_sysfs -lwiringPi
|
||||
|
||||
wiringpi_test3_device_wpi:
|
||||
${CC} ${CFLAGS} wiringpi_test3_device_wpi.c -o wiringpi_test3_device_wpi -lwiringPi
|
||||
|
||||
wiringpi_test4_device_phys:
|
||||
${CC} ${CFLAGS} wiringpi_test4_device_phys.c -o wiringpi_test4_device_phys -lwiringPi
|
||||
|
||||
wiringpi_test5_default:
|
||||
${CC} ${CFLAGS} wiringpi_test5_default.c -o wiringpi_test5_default -lwiringPi
|
||||
|
||||
wiringpi_test6_isr:
|
||||
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi
|
||||
|
||||
wiringpi_test7_version:
|
||||
${CC} ${CFLAGS} wiringpi_test7_version.c -o wiringpi_test7_version -lwiringPi
|
||||
|
||||
test:
|
||||
for t in $(tests) ; do \
|
||||
echo === unit test: $${t} === ; \
|
||||
time ./$${t} ; \
|
||||
echo ; echo ; \
|
||||
done
|
||||
|
||||
clean:
|
||||
for t in $(tests) ; do rm -fv $${t} ; done
|
||||
57
wiringPi/test/wiringpi_test1_sysfs.c
Normal file
57
wiringPi/test/wiringpi_test1_sysfs.c
Normal file
@@ -0,0 +1,57 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
|
||||
printf(" testing digitalWrite, digitalRead and pullUpDnControl\n");
|
||||
|
||||
if (wiringPiSetupSys() == -1) {
|
||||
printf("wiringPiSetupSys failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
printf("toggle %d times ...\n", ToggleValue);
|
||||
for (int loop=1; loop<ToggleValue; loop++) {
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
digitalWriteEx(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
}
|
||||
|
||||
digitalWrite(GPIO, LOW);
|
||||
|
||||
printf("\nWiringPi GPIO test program (using GPIO%d (input pull up/down) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
|
||||
pullUpDnControl (GPIO, PUD_UP);
|
||||
pinMode(GPIO, INPUT);
|
||||
delayMicroseconds(3000000);
|
||||
pullUpDnControl (GPIOIN, PUD_OFF);
|
||||
|
||||
for (int loop=1; loop<ToggleValue; loop++) {
|
||||
pullUpDnControlEx (GPIO, GPIOIN, PUD_DOWN);
|
||||
delayMicroseconds(600000);
|
||||
pullUpDnControlEx (GPIO, GPIOIN, PUD_UP);
|
||||
delayMicroseconds(600000);
|
||||
}
|
||||
|
||||
//Error wrong direction - only for fun
|
||||
digitalWrite(GPIO, LOW);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
54
wiringPi/test/wiringpi_test2_sysfs.c
Normal file
54
wiringPi/test/wiringpi_test2_sysfs.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test2_device.c -o wiringpi_test2_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
printf("WiringPi GPIO test program 2 (using GPIO%d (output) and GPIO%d (input) via sys)\n", GPIO, GPIOIN);
|
||||
printf(" testing pullUpDnControl and pinMode PM_OFF\n");
|
||||
|
||||
if (wiringPiSetupSys() == -1) {
|
||||
printf("wiringPiSetupSys failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
printf("\nTest output\n");
|
||||
digitalWriteEx(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull up\n");
|
||||
pinMode(GPIO, OUTPUT);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
pullUpDnControl (GPIO, PUD_UP);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull down\n");
|
||||
pullUpDnControl (GPIO, PUD_DOWN);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
54
wiringPi/test/wiringpi_test3_device_wpi.c
Normal file
54
wiringPi/test/wiringpi_test3_device_wpi.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test3_device.c -o wiringpi_test3_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 24; //BCM 19
|
||||
const int GPIOIN = 25; //BCM 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
printf("WiringPi GPIO test program 2 (using WiringPi GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN);
|
||||
printf(" testing pullUpDnControl and pinMode PM_OFF\n");
|
||||
|
||||
if (wiringPiSetupGpioDevice(WPI_PIN_WPI) == -1) {
|
||||
printf("wiringPiSetupGpioDevice failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
printf("\nTest output\n");
|
||||
digitalWriteEx(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull up\n");
|
||||
pinMode(GPIO, OUTPUT);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
pullUpDnControl (GPIO, PUD_UP);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull down\n");
|
||||
pullUpDnControl (GPIO, PUD_DOWN);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
54
wiringPi/test/wiringpi_test4_device_phys.c
Normal file
54
wiringPi/test/wiringpi_test4_device_phys.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test4_device.c -o wiringpi_test4_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 35; //BCM 19
|
||||
const int GPIOIN = 37; //BCM 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
printf("WiringPi GPIO test program 2 (using physical GPIO%d (output) and GPIO%d (input) via GPIO device)\n", GPIO, GPIOIN);
|
||||
printf(" testing pullUpDnControl and pinMode PM_OFF\n");
|
||||
|
||||
if (wiringPiSetupGpioDevice(WPI_PIN_PHYS) == -1) {
|
||||
printf("wiringPiSetupGpioDevice failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
printf("\nTest output\n");
|
||||
digitalWriteEx(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull up\n");
|
||||
pinMode(GPIO, OUTPUT);
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
pullUpDnControl (GPIO, PUD_UP);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
printf("\nTest output off with pull down\n");
|
||||
pullUpDnControl (GPIO, PUD_DOWN);
|
||||
pinMode(GPIO, PM_OFF);
|
||||
delayMicroseconds(600000);
|
||||
printf("out = off ");
|
||||
CheckGPIO(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
57
wiringPi/test/wiringpi_test5_default.c
Normal file
57
wiringPi/test/wiringpi_test5_default.c
Normal file
@@ -0,0 +1,57 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||
printf(" testing digitalWrite, digitalRead and pullUpDnControl\n");
|
||||
|
||||
if (wiringPiSetupGpio() == -1) {
|
||||
printf("wiringPiSetupGpio failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
printf("toggle %d times ...\n", ToggleValue);
|
||||
for (int loop=1; loop<ToggleValue; loop++) {
|
||||
digitalWriteEx(GPIO, GPIOIN, LOW);
|
||||
delayMicroseconds(600000);
|
||||
digitalWriteEx(GPIO, GPIOIN, HIGH);
|
||||
delayMicroseconds(600000);
|
||||
}
|
||||
|
||||
digitalWrite(GPIO, LOW);
|
||||
|
||||
printf("\nWiringPi GPIO test program (using GPIO%d (input pull up/down) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||
pullUpDnControl (GPIO, PUD_UP);
|
||||
pinMode(GPIO, INPUT);
|
||||
delayMicroseconds(3000000);
|
||||
pullUpDnControl (GPIOIN, PUD_OFF);
|
||||
|
||||
for (int loop=1; loop<ToggleValue; loop++) {
|
||||
pullUpDnControlEx (GPIO, GPIOIN, PUD_DOWN);
|
||||
delayMicroseconds(600000);
|
||||
pullUpDnControlEx (GPIO, GPIOIN, PUD_UP);
|
||||
delayMicroseconds(600000);
|
||||
}
|
||||
|
||||
//Error wrong direction - only for fun
|
||||
digitalWrite(GPIO, LOW);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
170
wiringPi/test/wiringpi_test6_isr.c
Normal file
170
wiringPi/test/wiringpi_test6_isr.c
Normal file
@@ -0,0 +1,170 @@
|
||||
// WiringPi test program: Kernel char device interface / sysfs successor
|
||||
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
static volatile int globalCounter;
|
||||
volatile long long gStartTime, gEndTime;
|
||||
|
||||
|
||||
static void wfi (void) {
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, 0);
|
||||
if (0==gStartTime) {
|
||||
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||
} else {
|
||||
gEndTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||
}
|
||||
globalCounter++;
|
||||
}
|
||||
|
||||
|
||||
double StartSequence (int Enge, int OUTpin) {
|
||||
int expected;
|
||||
double timeExpected;
|
||||
|
||||
gStartTime = 0;
|
||||
gEndTime = 0;
|
||||
globalCounter = 0;
|
||||
printf("Start\n");
|
||||
digitalWrite(OUTpin, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(OUTpin, LOW);
|
||||
delay(100);
|
||||
digitalWrite(OUTpin, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(OUTpin, LOW);
|
||||
delay(100);
|
||||
printf("Stop\n");
|
||||
int globalCounterCopy = globalCounter;
|
||||
|
||||
if (INT_EDGE_BOTH == Enge) {
|
||||
expected = 4;
|
||||
timeExpected = 500;
|
||||
} else {
|
||||
expected = 2;
|
||||
timeExpected = 300;
|
||||
}
|
||||
|
||||
if (globalCounter==expected) {
|
||||
double fTime = (gEndTime - gStartTime) / 1000000.0;
|
||||
printf("IRQ worked %g sec (~%gs expected)", fTime, timeExpected/1000.0);
|
||||
double diff = fTime-(timeExpected/1000.0);
|
||||
if(diff<0.05 && diff>0) {
|
||||
printf(" -> %spassed%s\n", COLORGRN, COLORDEF);
|
||||
} else {
|
||||
printf(" -> %sfailed%s\n", COLORRED, COLORDEF);
|
||||
}
|
||||
|
||||
return fTime;
|
||||
} else {
|
||||
printf("IRQ not worked got %d iterations (%d exprected)\n\n", globalCounterCopy, expected);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double DurationTime(int Enge, int OUTpin, int IRQpin) {
|
||||
struct timeval now;
|
||||
double fTime = 0.0;
|
||||
|
||||
gStartTime = 0;
|
||||
gEndTime = 0;
|
||||
globalCounter = 0;
|
||||
printf("Start\n");
|
||||
|
||||
if (INT_EDGE_RISING == Enge) {
|
||||
digitalWrite(OUTpin, LOW);
|
||||
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
|
||||
sleep(1);
|
||||
gettimeofday(&now, 0);
|
||||
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||
digitalWrite(OUTpin, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(OUTpin, LOW);
|
||||
} else if (INT_EDGE_FALLING == Enge) {
|
||||
digitalWrite(OUTpin, HIGH);
|
||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
|
||||
sleep(1);
|
||||
gettimeofday(&now, 0);
|
||||
gStartTime = now.tv_sec*1000000LL + now.tv_usec;
|
||||
digitalWrite(OUTpin, LOW);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
fTime = (gEndTime - gStartTime);
|
||||
printf("IRQ detect time %g usec", fTime);
|
||||
if (fTime<2000 && fTime>0) {
|
||||
printf(" -> %spassed%s\n", COLORGRN, COLORDEF);
|
||||
} else {
|
||||
printf(" -> %sfailed%s\n", COLORRED, COLORDEF);
|
||||
}
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
return fTime;
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
const int IRQpin = GPIOIN ;
|
||||
const int OUTpin = GPIO ;
|
||||
int major, minor;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
|
||||
printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||
printf(" testing irq\n");
|
||||
|
||||
printf("\nISR test (WiringPi %d.%d)\n", major, minor);
|
||||
|
||||
wiringPiSetupGpio() ;
|
||||
|
||||
pinMode(IRQpin, INPUT);
|
||||
pinMode(OUTpin, OUTPUT);
|
||||
digitalWrite (OUTpin, LOW) ;
|
||||
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_RISING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_FALLING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_BOTH, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
for (int count=0; count<2; count++) {
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_RISING, OUTpin, IRQpin);
|
||||
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin);
|
||||
}
|
||||
pinMode(OUTpin, INPUT);
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
11
wiringPi/test/wiringpi_test7_version.c
Normal file
11
wiringPi/test/wiringpi_test7_version.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "wpi_test.h"
|
||||
#include "../../version.h"
|
||||
|
||||
int main (void) {
|
||||
int major, minor;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
|
||||
CheckSame("version major", major, VERSION_MAJOR);
|
||||
CheckSame("version minor", minor, VERSION_MINOR);
|
||||
}
|
||||
48
wiringPi/test/wpi_test.h
Normal file
48
wiringPi/test/wpi_test.h
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COLORDEF "\x1B[0m"
|
||||
#define COLORRED "\x1B[31m"
|
||||
#define COLORGRN "\x1B[32m"
|
||||
|
||||
void CheckGPIO(int GPIO, int GPIOIN, int out) {
|
||||
int in = digitalRead(GPIOIN);
|
||||
int read = digitalRead(GPIO);
|
||||
|
||||
int pass = 0;
|
||||
if (out==in && in==read) {
|
||||
pass = 1;
|
||||
}
|
||||
if (pass) {
|
||||
printf("GPIO%d = %d (GPIO%d = %d) -> %spassed%s\n", GPIOIN, in, GPIO, read, COLORGRN, COLORDEF );
|
||||
} else {
|
||||
printf("GPIO%d = %d (GPIO%d = %d) -> %sfailed%s\n", GPIOIN, in, GPIO, read, COLORRED, COLORDEF );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void digitalWriteEx(int GPIO, int GPIOIN, int mode) {
|
||||
digitalWrite(GPIO, mode);
|
||||
printf("out = %d ", mode);
|
||||
delayMicroseconds(5000);
|
||||
CheckGPIO(GPIO, GPIOIN, mode);
|
||||
}
|
||||
|
||||
|
||||
void pullUpDnControlEx (int GPIO, int GPIOIN, int mode) {
|
||||
pullUpDnControl (GPIO, mode);
|
||||
int out = mode==PUD_UP ? 1:0;
|
||||
printf("in = %4s ", mode==PUD_UP ? "up":"down");
|
||||
delayMicroseconds(5000);
|
||||
CheckGPIO(GPIO, GPIOIN, out);
|
||||
}
|
||||
|
||||
|
||||
void CheckSame(const char* msg, int value, int expect) {
|
||||
if (value==expect) {
|
||||
printf("%s -> %spassed%s\n", msg, COLORGRN, COLORDEF );
|
||||
} else {
|
||||
printf("%s -> %sfailed%s\n", msg, COLORRED, COLORDEF );
|
||||
}
|
||||
}
|
||||
@@ -395,10 +395,23 @@ int wiringPiReturnCodes = FALSE ;
|
||||
|
||||
int wiringPiTryGpioMem = FALSE ;
|
||||
|
||||
// sysFds:
|
||||
// Map a file descriptor from the /sys/class/gpio/gpioX/value
|
||||
static unsigned int lineFlags [64] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
} ;
|
||||
|
||||
static int sysFds [64] =
|
||||
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 isrFds [64] =
|
||||
{
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
@@ -531,52 +544,13 @@ static int physToGpioR2 [64] =
|
||||
-1, -1,
|
||||
} ;
|
||||
|
||||
const int _5v=-1;
|
||||
const int _0v=-1;
|
||||
const int _3v=-1;
|
||||
|
||||
|
||||
static int physToSysGPIOPi5 [41] =
|
||||
{
|
||||
-1, // 0
|
||||
_3v, _5v, // 1, 2
|
||||
401, _5v,
|
||||
402, _0v,
|
||||
403, 413,
|
||||
_0v, 414,
|
||||
416, 417,
|
||||
426, _0v,
|
||||
421, 422,
|
||||
_3v, 423,
|
||||
409, _0v,
|
||||
408, 424,
|
||||
410, 407,
|
||||
_0v, 406,
|
||||
399, 400,
|
||||
404, _0v,
|
||||
405, 411,
|
||||
412, _0v,
|
||||
418, 415,
|
||||
425, 419,
|
||||
_0v, 420, //39, 40
|
||||
} ;
|
||||
|
||||
int GPIOToSysFS(const int pin) {
|
||||
int sysfspin = pin;
|
||||
int piBoard() {
|
||||
if (RaspberryPiModel<0) { //need to detect pi model
|
||||
int model, rev, mem, maker, overVolted ;
|
||||
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (wiringPiDebug)
|
||||
printf ("GPIOToSysFS: translate bcm gpio %d to sysfs gpio %d\n", pin, sysfspin) ;
|
||||
|
||||
return sysfspin;
|
||||
return RaspberryPiModel<0 ? 0 : 1;
|
||||
}
|
||||
|
||||
int GetMaxPin() {
|
||||
@@ -584,8 +558,8 @@ int GetMaxPin() {
|
||||
}
|
||||
|
||||
|
||||
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
|
||||
|
||||
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
|
||||
|
||||
int FailOnModel5() {
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n"
|
||||
@@ -857,12 +831,12 @@ static void usingGpioMemCheck (const char *what)
|
||||
void PrintSystemStdErr () {
|
||||
struct utsname sys_info;
|
||||
if (uname(&sys_info) == 0) {
|
||||
fprintf (stderr, " wiringpi = %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
|
||||
fprintf (stderr, " system name = %s\n", sys_info.sysname);
|
||||
//fprintf (stderr, " node name = %s\n", sys_info.nodename);
|
||||
fprintf (stderr, " release = %s\n", sys_info.release);
|
||||
fprintf (stderr, " version = %s\n", sys_info.version);
|
||||
fprintf (stderr, " machine = %s\n", sys_info.machine);
|
||||
fprintf (stderr, " WiringPi : %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
|
||||
fprintf (stderr, " system name : %s\n", sys_info.sysname);
|
||||
//fprintf (stderr, " node name : %s\n", sys_info.nodename);
|
||||
fprintf (stderr, " release : %s\n", sys_info.release);
|
||||
fprintf (stderr, " version : %s\n", sys_info.version);
|
||||
fprintf (stderr, " machine : %s\n", sys_info.machine);
|
||||
if (strstr(sys_info.machine, "arm") == NULL && strstr(sys_info.machine, "aarch")==NULL) {
|
||||
fprintf (stderr, " -> This is not an ARM architecture; it cannot be a Raspberry Pi.\n") ;
|
||||
}
|
||||
@@ -884,6 +858,10 @@ void piFunctionOops (const char *function, const char* suggestion, const char* u
|
||||
exit (EXIT_FAILURE) ;
|
||||
}
|
||||
|
||||
void ReportDeviceError(const char *function, int pin, const char *mode, int ret) {
|
||||
fprintf(stderr, "wiringPi: ERROR: ioctl %s of %d (%s) returned error '%s' (%d)\n", function, pin, mode, strerror(errno), ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* piGpioLayout:
|
||||
@@ -923,10 +901,7 @@ void piGpioLayoutOops (const char *why)
|
||||
|
||||
int piGpioLayout (void)
|
||||
{
|
||||
if (-1==RaspberryPiLayout) {
|
||||
int model, rev, mem, maker, overVolted ;
|
||||
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
|
||||
}
|
||||
piBoard();
|
||||
return RaspberryPiLayout;
|
||||
}
|
||||
|
||||
@@ -1135,6 +1110,37 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
|
||||
}
|
||||
|
||||
RaspberryPiModel = *model;
|
||||
|
||||
switch (RaspberryPiModel){
|
||||
case PI_MODEL_A:
|
||||
case PI_MODEL_B:
|
||||
case PI_MODEL_AP:
|
||||
case PI_MODEL_BP:
|
||||
case PI_ALPHA:
|
||||
case PI_MODEL_CM:
|
||||
case PI_MODEL_ZERO:
|
||||
case PI_MODEL_ZERO_W:
|
||||
piGpioBase = GPIO_PERI_BASE_OLD ;
|
||||
piGpioPupOffset = GPPUD ;
|
||||
break ;
|
||||
|
||||
case PI_MODEL_4B:
|
||||
case PI_MODEL_400:
|
||||
case PI_MODEL_CM4:
|
||||
piGpioBase = GPIO_PERI_BASE_2711 ;
|
||||
piGpioPupOffset = GPPUPPDN0 ;
|
||||
break ;
|
||||
|
||||
case PI_MODEL_5:
|
||||
piGpioBase = GPIO_PERI_BASE_2712 ;
|
||||
piGpioPupOffset = 0 ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
piGpioBase = GPIO_PERI_BASE_2835 ;
|
||||
piGpioPupOffset = GPPUD ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1194,16 +1200,16 @@ void setPadDrive (int group, int value)
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if (-1==group) {
|
||||
printf ("Pad register:\n");
|
||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
|
||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
|
||||
unsigned int drive = (pads[1+pin] & RP1_PAD_DRIVE_MASK)>>4;
|
||||
printf (" Pin %2d: 0x%08X drive: 0x%d = %2dmA\n", pin, pads[1+pin], drive, 0==drive ? 2 : drive*4) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (group !=0) { // only GPIO range @RP1
|
||||
return ;
|
||||
}
|
||||
}
|
||||
switch(value) {
|
||||
default:
|
||||
default:
|
||||
/* bcm*/ // RP1
|
||||
case 0: /* 2mA*/ value=0; break; // 2mA
|
||||
case 1: /* 4mA*/
|
||||
@@ -1214,9 +1220,9 @@ void setPadDrive (int group, int value)
|
||||
case 6: /*14mA*/
|
||||
case 7: /*16mA*/ value=3; break; //12mA
|
||||
}
|
||||
wrVal = (value << 4); //Drive strength 0-3
|
||||
wrVal = (value << 4); //Drive strength 0-3
|
||||
//set for all pins even when it's avaiable for each pin separately
|
||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
|
||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
|
||||
pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal;
|
||||
}
|
||||
rdVal = pads[1+17]; // only pin 17 readback, for logging
|
||||
@@ -1228,7 +1234,7 @@ void setPadDrive (int group, int value)
|
||||
if ((group < 0) || (group > 2))
|
||||
return ;
|
||||
|
||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7
|
||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7
|
||||
*(pads + group + 11) = wrVal ;
|
||||
rdVal = *(pads + group + 11);
|
||||
}
|
||||
@@ -1525,6 +1531,65 @@ void pinEnableED01Pi (int pin)
|
||||
#endif
|
||||
|
||||
|
||||
const char DEV_GPIO_PI[] ="/dev/gpiochip0";
|
||||
const char DEV_GPIO_PI5[]="/dev/gpiochip4";
|
||||
|
||||
int wiringPiGpioDeviceGetFd() {
|
||||
if (chipFd<0) {
|
||||
piBoard();
|
||||
const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI;
|
||||
chipFd = open(gpiochip, O_RDWR);
|
||||
if (chipFd < 0) {
|
||||
fprintf(stderr, "wiringPi: ERROR: %s open ret=%d\n", gpiochip, chipFd);
|
||||
} else if (wiringPiDebug) {
|
||||
printf ("wiringPi: Open chip %s succeded, fd=%d\n", gpiochip, chipFd) ;
|
||||
}
|
||||
}
|
||||
return chipFd;
|
||||
}
|
||||
|
||||
void releaseLine(int pin) {
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("releaseLine: pin:%d\n", pin) ;
|
||||
lineFlags[pin] = 0;
|
||||
close(lineFds[pin]);
|
||||
lineFds[pin] = -1;
|
||||
}
|
||||
|
||||
int requestLine(int pin, unsigned int lineRequestFlags) {
|
||||
struct gpiohandle_request rq;
|
||||
|
||||
if (lineFds[pin]>=0) {
|
||||
if (lineRequestFlags == lineFlags[pin]) {
|
||||
//already requested
|
||||
return lineFds[pin];
|
||||
} else {
|
||||
//different request -> rerequest
|
||||
releaseLine(pin);
|
||||
}
|
||||
}
|
||||
|
||||
//requested line
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return -1; // error
|
||||
}
|
||||
rq.lineoffsets[0] = pin;
|
||||
rq.lines = 1;
|
||||
rq.flags = lineRequestFlags;
|
||||
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
|
||||
if (ret || rq.fd<0) {
|
||||
ReportDeviceError("get line handle", pin, "RequestLine", ret);
|
||||
return -1; // error
|
||||
}
|
||||
|
||||
lineFlags[pin] = lineRequestFlags;
|
||||
lineFds[pin] = rq.fd;
|
||||
if (wiringPiDebug)
|
||||
printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ;
|
||||
return lineFds[pin];
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************
|
||||
* Core Functions
|
||||
@@ -1555,7 +1620,7 @@ void pinModeAlt (int pin, int mode)
|
||||
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
|
||||
//confusion! diffrent to to BCM! this is taking directly the value for the register
|
||||
//confusion! diffrent to to BCM! this is taking directly the value for the register
|
||||
/*
|
||||
"alt0" 0b100
|
||||
"alt1" 0b101
|
||||
@@ -1588,6 +1653,35 @@ void rp1_set_pad(int pin, int slewfast, int schmitt, int pulldown, int pullup, i
|
||||
pads[1+pin] = (slewfast != 0) | ((schmitt != 0) << 1) | ((pulldown != 0) << 2) | ((pullup != 0) << 3) | ((drive & 0x3) << 4) | ((inputenable != 0) << 6) | ((outputdisable != 0) << 7);
|
||||
}
|
||||
|
||||
void pinModeFlagsDevice (int pin, int mode, unsigned int flags) {
|
||||
unsigned int lflag = flags;
|
||||
if (wiringPiDebug)
|
||||
printf ("pinModeFlagsDevice: pin:%d mode:%d, flags: %u\n", pin, mode, flags) ;
|
||||
|
||||
lflag &= ~(GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_OUTPUT);
|
||||
switch(mode) {
|
||||
default:
|
||||
fprintf(stderr, "pinMode: invalid mode request (only input und output supported)\n");
|
||||
return;
|
||||
case INPUT:
|
||||
lflag |= GPIOHANDLE_REQUEST_INPUT;
|
||||
break;
|
||||
case OUTPUT:
|
||||
lflag |= GPIOHANDLE_REQUEST_OUTPUT;
|
||||
break;
|
||||
case PM_OFF:
|
||||
pinModeFlagsDevice(pin, INPUT, 0);
|
||||
releaseLine(pin);
|
||||
return;
|
||||
}
|
||||
|
||||
requestLine(pin, lflag);
|
||||
}
|
||||
|
||||
void pinModeDevice (int pin, int mode) {
|
||||
pinModeFlagsDevice(pin, mode, lineFlags[pin]);
|
||||
}
|
||||
|
||||
void pinMode (int pin, int mode)
|
||||
{
|
||||
int fSel, shift, alt ;
|
||||
@@ -1595,18 +1689,34 @@ void pinMode (int pin, int mode)
|
||||
int origPin = pin ;
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ;
|
||||
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ;
|
||||
|
||||
setupCheck ("pinMode") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin
|
||||
{
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return ;
|
||||
switch(wiringPiMode) {
|
||||
default: //WPI_MODE_GPIO_SYS
|
||||
fprintf(stderr, "pinMode: invalid mode\n");
|
||||
return;
|
||||
case WPI_MODE_PINS:
|
||||
pin = pinToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_PHYS:
|
||||
pin = physToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_GPIO_DEVICE_BCM:
|
||||
pinModeDevice(pin, mode);
|
||||
return;
|
||||
case WPI_MODE_GPIO_DEVICE_WPI:
|
||||
pinModeDevice(pinToGpio[pin], mode);
|
||||
return;
|
||||
case WPI_MODE_GPIO_DEVICE_PHYS:
|
||||
pinModeDevice(physToGpio[pin], mode);
|
||||
return;
|
||||
case WPI_MODE_GPIO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ;
|
||||
@@ -1618,7 +1728,7 @@ void pinMode (int pin, int mode)
|
||||
shift = gpioToShift [pin] ;
|
||||
|
||||
if (mode == INPUT) {
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9;
|
||||
gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO
|
||||
rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input
|
||||
@@ -1646,7 +1756,7 @@ void pinMode (int pin, int mode)
|
||||
{
|
||||
RETURN_ON_MODEL5
|
||||
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
|
||||
return ;
|
||||
return ;
|
||||
|
||||
usingGpioMemCheck ("pinMode PWM") ;
|
||||
|
||||
@@ -1663,7 +1773,7 @@ void pinMode (int pin, int mode)
|
||||
{
|
||||
RETURN_ON_MODEL5
|
||||
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
|
||||
return ;
|
||||
return ;
|
||||
|
||||
usingGpioMemCheck ("pinMode CLOCK") ;
|
||||
|
||||
@@ -1688,6 +1798,28 @@ void pinMode (int pin, int mode)
|
||||
* Control the internal pull-up/down resistors on a GPIO pin.
|
||||
*********************************************************************************
|
||||
*/
|
||||
void pullUpDnControlDevice (int pin, int pud) {
|
||||
unsigned int flag = lineFlags[pin];
|
||||
unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
|
||||
|
||||
flag &= ~biasflags;
|
||||
switch (pud){
|
||||
case PUD_OFF: flag |= GPIOHANDLE_REQUEST_BIAS_DISABLE; break;
|
||||
case PUD_UP: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_UP; break;
|
||||
case PUD_DOWN: flag |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; break;
|
||||
default: return ; /* An illegal value */
|
||||
}
|
||||
|
||||
// reset input/output
|
||||
if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) {
|
||||
pinModeFlagsDevice (pin, OUTPUT, flag);
|
||||
} else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) {
|
||||
pinModeFlagsDevice (pin, INPUT, flag);
|
||||
} else {
|
||||
lineFlags[pin] = flag; // only store for later
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pullUpDnControl (int pin, int pud)
|
||||
{
|
||||
@@ -1697,13 +1829,25 @@ void pullUpDnControl (int pin, int pud)
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
{
|
||||
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return ;
|
||||
switch(wiringPiMode) {
|
||||
default: //WPI_MODE_GPIO_SYS
|
||||
fprintf(stderr, "pinMode: invalid mode\n");
|
||||
return;
|
||||
case WPI_MODE_PINS:
|
||||
pin = pinToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_PHYS:
|
||||
pin = physToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_GPIO_DEVICE_BCM:
|
||||
return pullUpDnControlDevice(pin, pud);
|
||||
case WPI_MODE_GPIO_DEVICE_WPI:
|
||||
return pullUpDnControlDevice(pinToGpio[pin], pud);
|
||||
case WPI_MODE_GPIO_DEVICE_PHYS:
|
||||
return pullUpDnControlDevice(physToGpio[pin], pud);
|
||||
case WPI_MODE_GPIO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits
|
||||
@@ -1722,11 +1866,10 @@ void pullUpDnControl (int pin, int pud)
|
||||
unsigned int pullbits;
|
||||
unsigned int pull;
|
||||
|
||||
switch (pud)
|
||||
{
|
||||
case PUD_OFF: pull = 0; break;
|
||||
case PUD_UP: pull = 1; break;
|
||||
case PUD_DOWN: pull = 2; break;
|
||||
switch (pud) {
|
||||
case PUD_OFF: pull = 0; break;
|
||||
case PUD_UP: pull = 1; break;
|
||||
case PUD_DOWN: pull = 2; break;
|
||||
default: return ; /* An illegal value */
|
||||
}
|
||||
|
||||
@@ -1755,26 +1898,58 @@ void pullUpDnControl (int pin, int pud)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* digitalRead:
|
||||
* Read the value of a given Pin, returning HIGH or LOW
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int digitalReadDevice (int pin) { // INPUT and OUTPUT should work
|
||||
|
||||
if (lineFds[pin]<0) {
|
||||
// line not requested - auto request on first read as input
|
||||
pinModeDevice(pin, INPUT);
|
||||
}
|
||||
if (lineFds[pin]>=0) {
|
||||
struct gpiohandle_data data;
|
||||
int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
|
||||
if (ret) {
|
||||
ReportDeviceError("get line values", pin, "digitalRead", ret);
|
||||
return LOW; // error
|
||||
}
|
||||
return data.values[0];
|
||||
}
|
||||
return LOW; // error , need to request line before
|
||||
}
|
||||
|
||||
|
||||
int digitalRead (int pin)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
{
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||
return LOW ;
|
||||
else if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return LOW ;
|
||||
switch(wiringPiMode) {
|
||||
default: //WPI_MODE_GPIO_SYS
|
||||
fprintf(stderr, "digitalRead: invalid mode\n");
|
||||
return LOW;
|
||||
case WPI_MODE_PINS:
|
||||
pin = pinToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_PHYS:
|
||||
pin = physToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_GPIO_DEVICE_BCM:
|
||||
return digitalReadDevice(pin);
|
||||
case WPI_MODE_GPIO_DEVICE_WPI:
|
||||
return digitalReadDevice(pinToGpio[pin]);
|
||||
case WPI_MODE_GPIO_DEVICE_PHYS:
|
||||
return digitalReadDevice(physToGpio[pin]);
|
||||
case WPI_MODE_GPIO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) {
|
||||
@@ -1825,27 +2000,67 @@ unsigned int digitalRead8 (int pin)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void digitalWriteDevice (int pin, int value) {
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ;
|
||||
|
||||
if (lineFds[pin]<0) {
|
||||
// line not requested - auto request on first write as output
|
||||
pinModeDevice(pin, OUTPUT);
|
||||
}
|
||||
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) {
|
||||
struct gpiohandle_data data;
|
||||
data.values[0] = value;
|
||||
if (wiringPiDebug)
|
||||
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
|
||||
int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
|
||||
if (ret) {
|
||||
ReportDeviceError("set line values", pin, "digitalWrite", ret);
|
||||
return; // error
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]);
|
||||
}
|
||||
return; // error
|
||||
}
|
||||
|
||||
void digitalWrite (int pin, int value)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
{
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
|
||||
return ;
|
||||
else if (wiringPiMode == WPI_MODE_PINS)
|
||||
pin = pinToGpio [pin] ;
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return ;
|
||||
switch(wiringPiMode) {
|
||||
default: //WPI_MODE_GPIO_SYS
|
||||
fprintf(stderr, "digitalWrite: invalid mode\n");
|
||||
return;
|
||||
case WPI_MODE_PINS:
|
||||
pin = pinToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_PHYS:
|
||||
pin = physToGpio [pin];
|
||||
break;
|
||||
case WPI_MODE_GPIO_DEVICE_BCM:
|
||||
digitalWriteDevice(pin, value);
|
||||
return;
|
||||
case WPI_MODE_GPIO_DEVICE_WPI:
|
||||
digitalWriteDevice(pinToGpio[pin], value);
|
||||
return;
|
||||
case WPI_MODE_GPIO_DEVICE_PHYS:
|
||||
digitalWriteDevice(physToGpio[pin], value);
|
||||
return;
|
||||
case WPI_MODE_GPIO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if (value == LOW) {
|
||||
//printf("Set pin %d >>0x%08x<< to low\n", pin, 1<<pin);
|
||||
rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin;
|
||||
} else {
|
||||
//printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin);
|
||||
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin;
|
||||
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin;
|
||||
}
|
||||
} else {
|
||||
if (value == LOW)
|
||||
@@ -2101,7 +2316,7 @@ unsigned int digitalReadByte2 (void)
|
||||
|
||||
int waitForInterrupt (int pin, int mS)
|
||||
{
|
||||
int fd, ret;
|
||||
int fd, ret;
|
||||
struct pollfd polls ;
|
||||
struct gpioevent_data evdata;
|
||||
//struct gpio_v2_line_request req2;
|
||||
@@ -2111,7 +2326,7 @@ int waitForInterrupt (int pin, int mS)
|
||||
else if (wiringPiMode == WPI_MODE_PHYS)
|
||||
pin = physToGpio [pin] ;
|
||||
|
||||
if ((fd = sysFds [pin]) == -1)
|
||||
if ((fd = isrFds [pin]) == -1)
|
||||
return -2 ;
|
||||
|
||||
// Setup poll structure
|
||||
@@ -2124,12 +2339,12 @@ int waitForInterrupt (int pin, int mS)
|
||||
if (ret <= 0) {
|
||||
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret);
|
||||
} else {
|
||||
//if (polls.revents & POLLIN)
|
||||
//if (polls.revents & POLLIN)
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, sysFds [pin]) ;
|
||||
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ;
|
||||
}
|
||||
/* read event data */
|
||||
int readret = read(sysFds [pin], &evdata, sizeof(evdata));
|
||||
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
|
||||
if (readret == sizeof(evdata)) {
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: IRQ data id: %d, timestamp: %lld\n", evdata.id, evdata.timestamp) ;
|
||||
@@ -2142,9 +2357,6 @@ int waitForInterrupt (int pin, int mS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char DEV_GPIO_PI[] ="/dev/gpiochip0";
|
||||
const char DEV_GPIO_PI5[]="/dev/gpiochip4";
|
||||
|
||||
int waitForInterruptInit (int pin, int mode)
|
||||
{
|
||||
const char* strmode = "";
|
||||
@@ -2157,16 +2369,8 @@ int waitForInterruptInit (int pin, int mode)
|
||||
|
||||
/* open gpio */
|
||||
sleep(1);
|
||||
const char* gpiochip = PI_MODEL_5 == RaspberryPiModel ? DEV_GPIO_PI5 : DEV_GPIO_PI;
|
||||
if (chipFd < 0) {
|
||||
chipFd = open(gpiochip, O_RDWR);
|
||||
if (chipFd < 0) {
|
||||
fprintf(stderr, "wiringPi: ERROR: %s open ret=%d\n", gpiochip, chipFd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: Open chip %s succeded, fd=%d\n", gpiochip, chipFd) ;
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct gpioevent_request req;
|
||||
@@ -2197,7 +2401,7 @@ int waitForInterruptInit (int pin, int mode)
|
||||
//later implement GPIO_V2_GET_LINE_IOCTL req2
|
||||
int ret = ioctl(chipFd, GPIO_GET_LINEEVENT_IOCTL, &req);
|
||||
if (ret) {
|
||||
fprintf(stderr, "wiringPi: ERROR: %s ioctl get line %d %s returned %d\n", gpiochip, pin, strmode, ret);
|
||||
ReportDeviceError("get line event", pin , strmode, ret);
|
||||
return -1;
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
@@ -2206,12 +2410,12 @@ int waitForInterruptInit (int pin, int mode)
|
||||
|
||||
/* set event fd nonbloack read */
|
||||
int fd_line = req.fd;
|
||||
sysFds [pin] = fd_line;
|
||||
isrFds [pin] = fd_line;
|
||||
int flags = fcntl(fd_line, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
ret = fcntl(fd_line, F_SETFL, flags);
|
||||
if (ret) {
|
||||
fprintf(stderr, "wiringPi: ERROR: %s fcntl set nonblock read=%d\n", gpiochip, chipFd);
|
||||
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2220,10 +2424,10 @@ int waitForInterruptInit (int pin, int mode)
|
||||
|
||||
|
||||
int waitForInterruptClose (int pin) {
|
||||
if (sysFds[pin]>0) {
|
||||
if (isrFds[pin]>0) {
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ;
|
||||
}
|
||||
}
|
||||
if (pthread_cancel(isrThreads[pin]) == 0) {
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ;
|
||||
@@ -2233,9 +2437,9 @@ int waitForInterruptClose (int pin) {
|
||||
fprintf (stderr, "wiringPi: waitForInterruptClose could not cancel thread\n");
|
||||
}
|
||||
}
|
||||
close(sysFds [pin]);
|
||||
close(isrFds [pin]);
|
||||
}
|
||||
sysFds [pin] = -1;
|
||||
isrFds [pin] = -1;
|
||||
isrFunctions [pin] = NULL;
|
||||
|
||||
/* -not closing so far - other isr may be using it - only close if no other is using - will code later
|
||||
@@ -2323,7 +2527,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
|
||||
if(waitForInterruptInit (pin, mode)<0) {
|
||||
if (wiringPiDebug) {
|
||||
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (wiringPiDebug) {
|
||||
@@ -2522,6 +2726,7 @@ int wiringPiUserLevelAccess(void)
|
||||
struct stat statBuf ;
|
||||
const char* gpiomemModule = gpiomem_BCM;
|
||||
|
||||
piBoard();
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
gpiomemModule = gpiomem_RP1;
|
||||
}
|
||||
@@ -2530,6 +2735,58 @@ int wiringPiUserLevelAccess(void)
|
||||
}
|
||||
|
||||
|
||||
int wiringPiGlobalMemoryAccess(void)
|
||||
{
|
||||
const char* gpiomemGlobal;
|
||||
int fd=-1;
|
||||
unsigned int MMAP_size;
|
||||
unsigned int BaseAddr, PWMAddr;
|
||||
|
||||
piBoard();
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
gpiomemGlobal = pciemem_RP1;
|
||||
MMAP_size = pciemem_RP1_Size;
|
||||
BaseAddr = 0x00000000;
|
||||
PWMAddr = 0x00000000; //not supported so far
|
||||
} else {
|
||||
gpiomemGlobal = gpiomem_global;
|
||||
MMAP_size = BLOCK_SIZE;
|
||||
BaseAddr = piGpioBase + 0x00200000 ;
|
||||
PWMAddr = piGpioBase + 0x0020C000 ;
|
||||
}
|
||||
|
||||
if ((fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) >0) {
|
||||
int returnvalue = 1; // OK
|
||||
|
||||
uint32_t * lgpio = (uint32_t *)mmap(0, MMAP_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, BaseAddr) ;
|
||||
if (lgpio == MAP_FAILED) {
|
||||
returnvalue = 0;
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (GPIO 0x%X,0x%X) failed: %s\n", BaseAddr, MMAP_size, strerror (errno)) ;
|
||||
} else {
|
||||
munmap(lgpio, MMAP_size);
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
returnvalue = 2; // GPIO & PWM accessible (same area, nothing to mmap)
|
||||
} else {
|
||||
//check PWM area
|
||||
uint32_t* lpwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PWMAddr) ;
|
||||
if (lpwm == MAP_FAILED) {
|
||||
returnvalue = 1; // only GPIO accessible
|
||||
if (wiringPiDebug)
|
||||
fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (PWM 0x%X,0x%X) failed: %s\n", PWMAddr, MMAP_size, strerror (errno)) ;
|
||||
} else {
|
||||
returnvalue = 2; // GPIO & PWM accessible
|
||||
munmap(lpwm, BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return returnvalue;
|
||||
}
|
||||
return 0; // Failed!
|
||||
}
|
||||
|
||||
/*
|
||||
* wiringPiSetup:
|
||||
* Must be called once at the start of your program execution.
|
||||
@@ -2586,40 +2843,6 @@ int wiringPiSetup (void)
|
||||
physToGpio = physToGpioR2 ;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
switch (model)
|
||||
{
|
||||
case PI_MODEL_A:
|
||||
case PI_MODEL_B:
|
||||
case PI_MODEL_AP:
|
||||
case PI_MODEL_BP:
|
||||
case PI_ALPHA:
|
||||
case PI_MODEL_CM:
|
||||
case PI_MODEL_ZERO:
|
||||
case PI_MODEL_ZERO_W:
|
||||
piGpioBase = GPIO_PERI_BASE_OLD ;
|
||||
piGpioPupOffset = GPPUD ;
|
||||
break ;
|
||||
|
||||
case PI_MODEL_4B:
|
||||
case PI_MODEL_400:
|
||||
case PI_MODEL_CM4:
|
||||
piGpioBase = GPIO_PERI_BASE_2711 ;
|
||||
piGpioPupOffset = GPPUPPDN0 ;
|
||||
break ;
|
||||
|
||||
case PI_MODEL_5:
|
||||
piGpioBase = GPIO_PERI_BASE_2712 ;
|
||||
piGpioPupOffset = 0 ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
piGpioBase = GPIO_PERI_BASE_2835 ;
|
||||
piGpioPupOffset = GPPUD ;
|
||||
break ;
|
||||
}
|
||||
|
||||
// Open the master /dev/ memory control device
|
||||
// Device strategy: December 2016:
|
||||
// Try /dev/mem. If that fails, then
|
||||
@@ -2633,9 +2856,12 @@ int wiringPiSetup (void)
|
||||
gpiomemModule = gpiomem_RP1;
|
||||
}
|
||||
|
||||
usingGpioMem = FALSE;
|
||||
if (gpiomemGlobal==NULL || (fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
|
||||
{
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: no access to %s try %s\n", gpiomemGlobal, gpiomemModule) ;
|
||||
}
|
||||
if (gpiomemModule && (fd = open (gpiomemModule, O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem
|
||||
{
|
||||
piGpioBase = 0 ;
|
||||
@@ -2648,7 +2874,7 @@ int wiringPiSetup (void)
|
||||
" Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ;
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: access to %s succeded\n", usingGpioMem ? gpiomemModule : gpiomemGlobal) ;
|
||||
printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ;
|
||||
}
|
||||
// GPIO:
|
||||
if (PI_MODEL_5 != model) {
|
||||
@@ -2709,7 +2935,7 @@ int wiringPiSetup (void)
|
||||
_wiringPiPads = pads ;
|
||||
_wiringPiTimer = timer ;
|
||||
_wiringPiRio = NULL ;
|
||||
} else {
|
||||
} else {
|
||||
unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size;
|
||||
|
||||
GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ;
|
||||
@@ -2800,21 +3026,76 @@ int wiringPiSetupPhys (void)
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int wiringPiSetupPinType (enum WPIPinType pinType) {
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: wiringPiSetupPinType(%d) called\n", (int) pinType) ;
|
||||
switch (pinType) {
|
||||
case WPI_PIN_BCM: return wiringPiSetupGpio();
|
||||
case WPI_PIN_WPI: return wiringPiSetup();
|
||||
case WPI_PIN_PHYS: return wiringPiSetupPhys();
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wiringPiSetupGpioDevice (enum WPIPinType pinType) {
|
||||
if (wiringPiSetuped)
|
||||
return 0 ;
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: wiringPiSetupGpioDevice(%d) called\n", (int)pinType) ;
|
||||
}
|
||||
if (getenv (ENV_DEBUG) != NULL)
|
||||
wiringPiDebug = TRUE ;
|
||||
|
||||
if (getenv (ENV_CODES) != NULL)
|
||||
wiringPiReturnCodes = TRUE ;
|
||||
|
||||
if (wiringPiGpioDeviceGetFd()<0) {
|
||||
return -1;
|
||||
}
|
||||
wiringPiSetuped = TRUE ;
|
||||
|
||||
if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1){
|
||||
pinToGpio = pinToGpioR1 ;
|
||||
physToGpio = physToGpioR1 ;
|
||||
} else {
|
||||
pinToGpio = pinToGpioR2 ;
|
||||
physToGpio = physToGpioR2 ;
|
||||
}
|
||||
|
||||
initialiseEpoch () ;
|
||||
|
||||
switch (pinType) {
|
||||
case WPI_PIN_BCM:
|
||||
wiringPiMode = WPI_MODE_GPIO_DEVICE_BCM;
|
||||
break;
|
||||
case WPI_PIN_WPI:
|
||||
wiringPiMode = WPI_MODE_GPIO_DEVICE_WPI;
|
||||
break;
|
||||
case WPI_PIN_PHYS:
|
||||
wiringPiMode = WPI_MODE_GPIO_DEVICE_PHYS;
|
||||
break;
|
||||
default:
|
||||
wiringPiSetuped = FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* wiringPiSetupSys:
|
||||
* GPIO Sysfs Interface for Userspace is deprecated
|
||||
* https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html
|
||||
* The last Raspberry Pi Kernel with Sysfs was 6.1.
|
||||
* If needed, please use WiringPi 3.1.
|
||||
*
|
||||
*
|
||||
* Switched to new GPIO driver Interface in version 3.3
|
||||
*/
|
||||
|
||||
int wiringPiSetupSys (void)
|
||||
{
|
||||
piFunctionOops("wiringPiSetupSys",
|
||||
"use wringpi 3.1 (last version with GPIO Sysfs interface)",
|
||||
"https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html");
|
||||
|
||||
return 0 ;
|
||||
if (wiringPiSetuped)
|
||||
return 0 ;
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: wiringPiSetupSys called\n") ;
|
||||
return wiringPiSetupGpioDevice(WPI_PIN_BCM);
|
||||
}
|
||||
|
||||
@@ -46,12 +46,15 @@
|
||||
|
||||
// wiringPi modes
|
||||
|
||||
#define WPI_MODE_PINS 0
|
||||
#define WPI_MODE_GPIO 1
|
||||
#define WPI_MODE_GPIO_SYS 2
|
||||
#define WPI_MODE_PHYS 3
|
||||
#define WPI_MODE_PIFACE 4
|
||||
#define WPI_MODE_UNINITIALISED -1
|
||||
#define WPI_MODE_PINS 0
|
||||
#define WPI_MODE_GPIO 1
|
||||
#define WPI_MODE_GPIO_SYS 2 // deprecated since 3.2
|
||||
#define WPI_MODE_PHYS 3
|
||||
#define WPI_MODE_PIFACE 4
|
||||
#define WPI_MODE_GPIO_DEVICE_BCM 5 // BCM pin numbers like WPI_MODE_GPIO
|
||||
#define WPI_MODE_GPIO_DEVICE_WPI 6 // WiringPi pin numbers like WPI_MODE_PINS
|
||||
#define WPI_MODE_GPIO_DEVICE_PHYS 7 // Physic pin numbers like WPI_MODE_PHYS
|
||||
#define WPI_MODE_UNINITIALISED -1
|
||||
|
||||
// Pin modes
|
||||
|
||||
@@ -62,6 +65,7 @@
|
||||
#define SOFT_PWM_OUTPUT 4
|
||||
#define SOFT_TONE_OUTPUT 5
|
||||
#define PWM_TONE_OUTPUT 6
|
||||
#define PM_OFF 7 // to input / release line
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
@@ -205,15 +209,23 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ;
|
||||
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ;
|
||||
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
|
||||
|
||||
extern int GPIOToSysFS(const int pin) ;
|
||||
enum WPIPinType {
|
||||
WPI_PIN_BCM = 1,
|
||||
WPI_PIN_WPI,
|
||||
WPI_PIN_PHYS,
|
||||
};
|
||||
|
||||
extern void wiringPiVersion (int *major, int *minor) ;
|
||||
extern int wiringPiGlobalMemoryAccess(void); //Interface V3.3
|
||||
extern int wiringPiUserLevelAccess (void) ;
|
||||
extern int wiringPiSetup (void) ;
|
||||
extern int wiringPiSetupSys (void) ;
|
||||
extern int wiringPiSetupGpio (void) ;
|
||||
extern int wiringPiSetupPhys (void) ;
|
||||
extern int wiringPiSetupPinType (enum WPIPinType pinType); //Interface V3.3
|
||||
extern int wiringPiSetupGpioDevice(enum WPIPinType pinType); //Interface V3.3
|
||||
|
||||
extern int wiringPiGpioDeviceGetFd(); //Interface V3.3
|
||||
extern void pinModeAlt (int pin, int mode) ;
|
||||
extern void pinMode (int pin, int mode) ;
|
||||
extern void pullUpDnControl (int pin, int pud) ;
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
@@ -154,6 +154,26 @@ int wiringPiI2CReadReg16 (int fd, int reg)
|
||||
return data.word & 0xFFFF ;
|
||||
}
|
||||
|
||||
int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
|
||||
if (size>I2C_SMBUS_BLOCK_MAX) {
|
||||
size = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
data.block[0] = size;
|
||||
int result = i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_I2C_BLOCK_DATA, &data);
|
||||
if (result<0) {
|
||||
return result;
|
||||
}
|
||||
memcpy(values, &data.block[1], size);
|
||||
return data.block[0];
|
||||
}
|
||||
|
||||
int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size)
|
||||
{
|
||||
return(read(fd, values, size));
|
||||
}
|
||||
|
||||
/*
|
||||
* wiringPiI2CWrite:
|
||||
@@ -189,6 +209,22 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int value)
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
|
||||
}
|
||||
|
||||
int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
|
||||
if (size>I2C_SMBUS_BLOCK_MAX) {
|
||||
size = I2C_SMBUS_BLOCK_MAX;
|
||||
}
|
||||
data.block[0] = size;
|
||||
memcpy(&data.block[1], values, size);
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BLOCK_DATA, &data) ;
|
||||
}
|
||||
|
||||
int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size)
|
||||
{
|
||||
return(write(fd, values, size));
|
||||
}
|
||||
|
||||
/*
|
||||
* wiringPiI2CSetupInterface:
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -29,10 +31,14 @@ extern "C" {
|
||||
extern int wiringPiI2CRead (int fd) ;
|
||||
extern int wiringPiI2CReadReg8 (int fd, int reg) ;
|
||||
extern int wiringPiI2CReadReg16 (int fd, int reg) ;
|
||||
extern int wiringPiI2CReadBlockData (int fd, int reg, uint8_t *values, uint8_t size); //Interface 3.3
|
||||
extern int wiringPiI2CRawRead (int fd, uint8_t *values, uint8_t size); //Interface 3.3
|
||||
|
||||
extern int wiringPiI2CWrite (int fd, int data) ;
|
||||
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
|
||||
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
|
||||
extern int wiringPiI2CWriteBlockData (int fd, int reg, const uint8_t *values, uint8_t size); //Interface 3.3
|
||||
extern int wiringPiI2CRawWrite (int fd, const uint8_t *values, uint8_t size); //Interface 3.3
|
||||
|
||||
extern int wiringPiI2CSetupInterface (const char *device, int devId) ;
|
||||
extern int wiringPiI2CSetup (const int devId) ;
|
||||
|
||||
@@ -186,66 +186,3 @@ int piGpioLayoutLegacy (void)
|
||||
|
||||
return gpioLayout ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSetupSys:
|
||||
* Must be called once at the start of your program execution.
|
||||
*
|
||||
* Initialisation (again), however this time we are using the /sys/class/gpio
|
||||
* interface to the GPIO systems - slightly slower, but always usable as
|
||||
* a non-root user, assuming the devices are already exported and setup correctly.
|
||||
*/
|
||||
|
||||
/*
|
||||
int wiringPiSetupSys (void)
|
||||
{
|
||||
char fName [128] ;
|
||||
|
||||
if (wiringPiSetuped)
|
||||
return 0 ;
|
||||
|
||||
wiringPiSetuped = TRUE ;
|
||||
|
||||
if (getenv (ENV_DEBUG) != NULL)
|
||||
wiringPiDebug = TRUE ;
|
||||
|
||||
if (getenv (ENV_CODES) != NULL)
|
||||
wiringPiReturnCodes = TRUE ;
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("wiringPi: wiringPiSetupSys called\n") ;
|
||||
|
||||
int model, rev, mem, maker, overVolted ;
|
||||
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
|
||||
|
||||
if (piGpioLayout () == GPIO_LAYOUT_PI1_REV1)
|
||||
{
|
||||
pinToGpio = pinToGpioR1 ;
|
||||
physToGpio = physToGpioR1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
pinToGpio = pinToGpioR2 ;
|
||||
physToGpio = physToGpioR2 ;
|
||||
}
|
||||
|
||||
// Open and scan the directory, looking for exported GPIOs, and pre-open
|
||||
// the 'value' interface to speed things up for later
|
||||
|
||||
for (int pin = 0, maxpin=GetMaxPin() ; pin <= maxpin ; ++pin)
|
||||
{
|
||||
int pinFS = GPIOToSysFS(pin);
|
||||
if (pinFS>=0) {
|
||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", pinFS) ;
|
||||
sysFds [pin] = open (fName, O_RDWR) ;
|
||||
}
|
||||
}
|
||||
|
||||
initialiseEpoch () ;
|
||||
|
||||
wiringPiMode = WPI_MODE_GPIO_SYS ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user