Browse Source

merge change from https://github.com/WiringPi/WiringPi

Signed-off-by: sndnvaps <sndnvaps@gmail.com>
pull/48/head
sndnvaps 6 years ago
parent
commit
b9be947b6a
No known key found for this signature in database GPG Key ID: 309C3FC08F9C9F57
59 changed files with 4170 additions and 477 deletions
  1. +0
    -7
      INSTALL
  2. +10
    -0
      README.TXT
  3. +1
    -1
      VERSION
  4. +12
    -1
      build
  5. +2
    -2
      debian-template/wiringPi/DEBIAN/control
  6. +140
    -0
      devLib/Makefile
  7. +1
    -1
      devLib/gertboard.c
  8. +1
    -2
      devLib/piFaceOld.c
  9. +2
    -2
      examples/Makefile
  10. +2
    -2
      examples/PiFace/Makefile
  11. +2
    -2
      examples/PiGlow/Makefile
  12. +61
    -0
      examples/blink-thread.c
  13. +61
    -0
      examples/blink8-drcn.c
  14. +18
    -23
      examples/delayTest.c
  15. +2
    -2
      examples/q2w/Makefile
  16. +2
    -2
      examples/scrollPhat/Makefile
  17. +103
    -0
      gpio/Makefile
  18. +26
    -35
      gpio/gpio.1
  19. +178
    -42
      gpio/gpio.c
  20. +1
    -1
      gpio/pintest
  21. +36
    -7
      gpio/readall.c
  22. +1
    -1
      gpio/test.sh
  23. +0
    -1
      gpio/version.h
  24. +8
    -4
      newVersion
  25. +5
    -0
      update
  26. +3
    -0
      version.h
  27. +165
    -0
      wiringPi/Makefile
  28. +1
    -1
      wiringPi/ads1115.c
  29. +237
    -0
      wiringPi/bmp180.c
  30. +34
    -0
      wiringPi/bmp180.h
  31. +405
    -0
      wiringPi/drcNet.c
  32. +42
    -0
      wiringPi/drcNet.h
  33. +146
    -0
      wiringPi/ds18b20.c
  34. +34
    -0
      wiringPi/ds18b20.h
  35. +150
    -0
      wiringPi/htu21d.c
  36. +34
    -0
      wiringPi/htu21d.h
  37. +1
    -1
      wiringPi/mcp3002.c
  38. +20
    -0
      wiringPi/noMoreStatic
  39. +1
    -1
      wiringPi/pcf8591.c
  40. +95
    -0
      wiringPi/pseudoPins.c
  41. +26
    -0
      wiringPi/pseudoPins.h
  42. +252
    -0
      wiringPi/rht03.c
  43. +25
    -0
      wiringPi/rht03.h
  44. +41
    -24
      wiringPi/softPwm.c
  45. +396
    -237
      wiringPi/wiringPi.c
  46. +61
    -31
      wiringPi/wiringPi.h
  47. +2
    -1
      wiringPi/wiringPiI2C.c
  48. +5
    -4
      wiringPi/wiringPiSPI.c
  49. +31
    -19
      wiringPi/wiringSerial.c
  50. +177
    -9
      wiringPi/wpiExtensions.c
  51. +100
    -0
      wiringPiD/Makefile
  52. +82
    -0
      wiringPiD/daemonise.c
  53. +9
    -0
      wiringPiD/daemonise.h
  54. +44
    -0
      wiringPiD/drcNetCmd.h
  55. +330
    -0
      wiringPiD/network.c
  56. +31
    -0
      wiringPiD/network.h
  57. +126
    -0
      wiringPiD/runRemote.c
  58. +7
    -11
      wiringPiD/runRemote.h
  59. +382
    -0
      wiringPiD/wiringpid.c

+ 0
- 7
INSTALL View File

@@ -19,13 +19,6 @@ then run the ldconfig command.

sudo ldconfig

If you want to install a static library, you may need to do this manually:

cd wiringPi
make static
sudo make install-static


To un-install wiringPi:

./build uninstall


+ 10
- 0
README.TXT View File

@@ -1,3 +1,13 @@
Note
====

This is an unofficial mirror of WiringPi to support ports (Python/Ruby/etc).

Please do not email Gordon if you have issues, he will not be able to help.

Pull-requests are not currently accepted, since this is a mirror.

For support, comments, questions, etc please join the WiringPi Discord channel: https://discord.gg/SM4WUVG

wiringPi README
===============


+ 1
- 1
VERSION View File

@@ -1 +1 @@
2.32
2.46

+ 12
- 1
build View File

@@ -6,7 +6,7 @@
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -64,6 +64,9 @@ if [ x$1 = "xclean" ]; then
echo -n "PiGlow: " ; make clean
cd ../scrollPhat
echo -n "scrollPhat: " ; make clean
cd ../..
echo -n "Deb: " ; rm -f debian-template/wiringpi*.deb
echo
exit
fi

@@ -161,6 +164,14 @@ fi
check_make_ok

# echo
# echo "wiringPi Daemon"
# cd ../wiringPiD
# make -j5
# check_make_ok
# $sudo make install
# check_make_ok

# echo
# echo "Examples"
# cd ../examples
# make


+ 2
- 2
debian-template/wiringPi/DEBIAN/control View File

@@ -1,5 +1,5 @@
Package: wiringpi
Version: 2.32
Version: 2.46
Section: libraries
Priority: optional
Architecture: armhf
@@ -7,4 +7,4 @@ Depends: libc6
Maintainer: Gordon Henderson <projects@drogon.net>
Description: The wiringPi libraries, headers and gpio command
Libraries to allow GPIO access on a Raspberry Pi from C and C++
programs as well as from the command-line
and BASIC programs as well as from the command-line

+ 140
- 0
devLib/Makefile View File

@@ -0,0 +1,140 @@
#
# Makefile:
# wiringPi device - A "wiring" library for the Raspberry Pi
#
# Copyright (c) 2012-2016 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# https://projects.drogon.net/raspberry-pi/wiringpi/
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################

VERSION=$(shell cat ../VERSION)
DESTDIR?=/usr
PREFIX?=/local

LDCONFIG?=ldconfig

ifneq ($V,1)
Q ?= @
endif

STATIC=libwiringPiDev.a
DYNAMIC=libwiringPiDev.so.$(VERSION)

#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I.
DEFS = -D_GNU_SOURCE
CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -pipe -fPIC

LIBS =

###############################################################################

SRC = ds1302.c maxdetect.c piNes.c \
gertboard.c piFace.c \
lcd128x64.c lcd.c \
scrollPhat.c \
piGlow.c

OBJ = $(SRC:.c=.o)

HEADERS = ds1302.h gertboard.h lcd128x64.h lcd.h maxdetect.h piFace.h piGlow.h piNes.h\
scrollPhat.h

all: $(DYNAMIC)

static: $(STATIC)

$(STATIC): $(OBJ)
$Q echo "[Link (Static)]"
$Q ar rcs $(STATIC) $(OBJ)
$Q ranlib $(STATIC)
# @size $(STATIC)

$(DYNAMIC): $(OBJ)
$Q echo "[Link (Dynamic)]"
$Q $(CC) -shared -Wl,-soname,libwiringPiDev.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPiDev.so.$(VERSION) -lpthread $(OBJ)

.c.o:
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@

.PHONY: clean
clean:
$Q echo "[Clean]"
$Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPiDev.*

.PHONY: tags
tags: $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)


.PHONY: install
install: $(DYNAMIC)
$Q echo "[Install Headers]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include
$Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include
$Q echo "[Install Dynamic Lib]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
$Q install -m 0755 libwiringPiDev.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION)
$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) $(DESTDIR)/lib/libwiringPiDev.so
$Q $(LDCONFIG)

.PHONY: install-static
install-static: $(STATIC)
$Q echo "[Install Headers]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include
$Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include
$Q echo "[Install Static Lib]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
$Q install -m 0755 libwiringPiDev.a $(DESTDIR)$(PREFIX)/lib

.PHONY: install-deb
install-deb: $(DYNAMIC)
$Q echo "[Install Headers: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include
$Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include
$Q echo "[Install Dynamic Lib: deb]"
install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib
install -m 0755 libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION)
ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so

.PHONY: uninstall
uninstall:
$Q echo "[UnInstall]"
$Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS)
$Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPiDev.*
$Q $(LDCONFIG)


.PHONY: depend
depend:
makedepend -Y $(SRC)

# DO NOT DELETE

ds1302.o: ds1302.h
maxdetect.o: maxdetect.h
piNes.o: piNes.h
gertboard.o: gertboard.h
piFace.o: piFace.h
lcd128x64.o: font.h lcd128x64.h
lcd.o: lcd.h
scrollPhat.o: scrollPhatFont.h scrollPhat.h
piGlow.o: piGlow.h

+ 1
- 1
devLib/gertboard.c View File

@@ -101,7 +101,7 @@ int gertboardAnalogRead (const int chan)

wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;

return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
}




+ 1
- 2
devLib/piFaceOld.c View File

@@ -1,7 +1,6 @@
/*
* piFace.:
* Arduino compatable (ish) Wiring library for the Raspberry Pi
* Copyright (c) 2012-2013 Gordon Henderson
* Copyright (c) 2012-2016 Gordon Henderson
*
* This file to interface with the PiFace peripheral device which
* has an MCP23S17 GPIO device connected via the SPI bus.


+ 2
- 2
examples/Makefile View File

@@ -1,6 +1,6 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# wiringPi - A "wiring" library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2015 Gordon Henderson
@@ -33,7 +33,7 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe

LDFLAGS = -L/usr/local/lib
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt

# Should not alter anything below this line
###############################################################################


+ 2
- 2
examples/PiFace/Makefile View File

@@ -1,12 +1,12 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# wiringPi - A "wiring" library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 2
- 2
examples/PiGlow/Makefile View File

@@ -1,12 +1,12 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# wiringPi - A "wiring" library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 61
- 0
examples/blink-thread.c View File

@@ -0,0 +1,61 @@
/*
* blink-thread.c:
* Standard "blink" program in wiringPi. Blinks an LED connected
* to the first GPIO pin.
*
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

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

// LED Pin - wiringPi pin 0 is BCM_GPIO 17.

#define LED 0

PI_THREAD (blinky)
{
for (;;)
{
digitalWrite (LED, HIGH) ; // On
delay (500) ; // mS
digitalWrite (LED, LOW) ; // Off
delay (500) ;
}
}


int main (void)
{
printf ("Raspberry Pi blink\n") ;

wiringPiSetup () ;
pinMode (LED, OUTPUT) ;

piThreadCreate (blinky) ;

for (;;)
{
printf ("Hello, world\n") ;
delay (600) ;
}

return 0 ;
}

+ 61
- 0
examples/blink8-drcn.c View File

@@ -0,0 +1,61 @@
/*
* blink8-drcn.c:
* Simple sequence over the first 8 GPIO pins - LEDs
* Aimed at the Ladder board, but it's fairly generic.
*
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

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

int main (void)
{
int i, led ;

printf ("Raspberry Pi - 8-LED Sequencer\n") ;
printf ("==============================\n") ;
printf ("\n") ;
printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ;

int pinBase = 100 ;

// wiringPiSetup () ;
drcSetupNet (pinBase, 100, "192.168.254.21", "6124", "123456") ;

for (i = 0 ; i < 8 ; ++i)
pinMode (i + pinBase, OUTPUT) ;

for (;;)
{
for (led = 0 ; led < 8 ; ++led)
{
digitalWrite (led + pinBase, 1) ;
delay (10) ;
}

for (led = 0 ; led < 8 ; ++led)
{
digitalWrite (led + pinBase, 0) ;
delay (10) ;
}
}
}

+ 18
- 23
examples/delayTest.c View File

@@ -25,7 +25,6 @@

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

#include <sys/time.h>

@@ -34,17 +33,13 @@
int main()
{
int x ;
struct timeval t1, t2 ;
struct timeval t1, t2, t3 ;
int t ;
int max, min ;
int del ;
int underRuns, overRuns, exactRuns, total ;
int underRuns, overRuns, exactRuns, bogusRuns, total ;
int descheds ;

if (wiringPiSetup () == -1)
return 1 ;

piHiPri (10) ; sleep (1) ;

// Baseline test

@@ -58,21 +53,22 @@ int main()
{
underRuns = overRuns = exactRuns = total = 0 ;
descheds = 0 ;
max = del ;
min = del ;
max = 0 ;
min = 999 ;

for (x = 0 ; x < CYCLES ; ++x)
{
for (;;) // Repeat this if we get a delay over 999uS
{ // -> High probability Linux has deschedulled us
gettimeofday (&t1, NULL) ;
delayMicroseconds (del) ;
usleep (del) ;
// delayMicroseconds (del) ;
gettimeofday (&t2, NULL) ;

if (t2.tv_usec < t1.tv_usec) // Counter wrapped
t = (1000000 + t2.tv_usec) - t1.tv_usec;
else
t = t2.tv_usec - t1.tv_usec ;
timersub (&t2, &t1, &t3) ;
t = t3.tv_usec ;
if (t > 999)
{
++descheds ;
@@ -82,25 +78,24 @@ int main()
break ;
}

if (t == del)
++exactRuns ;
else if (t < del)
++underRuns ;
else if (t > del)
++overRuns ;

if (t > max)
{
max = t ;
++overRuns ;
}
else if (t < min)
{
min = t ;
++underRuns ;
}
else
++exactRuns ;

total += t ;
}
printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n",
del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ;
fflush (stdout) ;
delay (1) ;
usleep (1000) ;
}

return 0 ;


+ 2
- 2
examples/q2w/Makefile View File

@@ -1,12 +1,12 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# wiringPi - A "wiring" library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2013 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 2
- 2
examples/scrollPhat/Makefile View File

@@ -1,12 +1,12 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# wiringPi - A "wiring" library for the Raspberry Pi
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 103
- 0
gpio/Makefile View File

@@ -0,0 +1,103 @@
#
# Makefile:
# The gpio command:
# A swiss-army knige of GPIO shenanigans.
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2016 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################

DESTDIR?=/usr
PREFIX?=/local

ifneq ($V,1)
Q ?= @
endif

#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I$(DESTDIR)$(PREFIX)/include
CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe

LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib
LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt

# May not need to alter anything below this line
###############################################################################

SRC = gpio.c readall.c

OBJ = $(SRC:.c=.o)

all: gpio

version.h: ../VERSION
$Q echo Need to run newVersion above.

gpio: $(OBJ)
$Q echo [Link]
$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)

.c.o:
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@

.PHONY: clean
clean:
$Q echo "[Clean]"
$Q rm -f $(OBJ) gpio *~ core tags *.bak

.PHONY: tags
tags: $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)

.PHONY: install
install: gpio
$Q echo "[Install]"
$Q cp gpio $(DESTDIR)$(PREFIX)/bin
ifneq ($(WIRINGPI_SUID),0)
$Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio
$Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio
endif
$Q mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1
$Q cp gpio.1 $(DESTDIR)$(PREFIX)/share/man/man1

.PHONY: install-deb
install-deb: gpio
$Q echo "[Install: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/share/man/man1
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/usr/share/man/man1

.PHONY: uninstall
uninstall:
$Q echo "[UnInstall]"
$Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio
$Q rm -f $(DESTDIR)$(PREFIX)/share/man/man1/gpio.1

.PHONY: depend
depend:
makedepend -Y $(SRC)

# DO NOT DELETE

gpio.o: ../version.h

+ 26
- 35
gpio/gpio.1 View File

@@ -1,4 +1,4 @@
.TH GPIO 1 "September 2015" wiringPi "Command-Line access to Raspberry Pi's GPIO"
.TH GPIO 1 "March 2018" wiringPi "Command-Line access to Raspberry Pi's GPIO"

.SH NAME
gpio \- Command-line access to Raspberry Pi's GPIO
@@ -9,15 +9,20 @@ gpio \- Command-line access to Raspberry Pi's GPIO
.PP
.B gpio
.B [ \-g | \-1 ]
.B mode/read/write/aread/awrite/wb/pwm/clock ...
.B mode/read/write/aread/awrite/wb/pwm/pwnTone/clock/toggle/blink ...
.PP
.B gpio
.B [ \-x extension:params ]
.B mode/read/write/aread/awrite/pwm/pwmTone ...
.B mode/read/write/aread/awrite/pwm/toggle/blink ...
.PP
.B gpio
.B [ \-p ]
.B read/write/toggle/wb
.B read/write/toggle/blink
.B ...
.PP
.B gpio
.B [ \-p ]
.B pwnTone pin frequency
.B ...
.PP
.B gpio
@@ -119,10 +124,22 @@ Write the given value (0 or 1) to the pin. You need to set the pin
to output mode first.

.TP
.B toggle <pin>
Changes the state of a GPIO pin; 0 to 1, or 1 to 0.

Note unlike the blink command, the pin must be in output mode first.

.TP
.B blink <pin>
Blinks the given pin on/off. Press Control-C to exit.

Note: This command explicitly sets the pin to output mode.

.TP
.B aread <pin>
Read the analog value of the given pin. This needs to be uses in
Read the analog value of the given pin. This needs to be used in
conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels.
inputs.

e.g. gpio -x mcp3002:200:0 aread 200

@@ -132,7 +149,7 @@ will read the first analog input on an mcp3002 SPI ADC chip.
.B awrite <pin> <value>
Write the analog value to the given pin. This needs to be used in
conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels.
inputs.

e.g. gpio -x mcp4802:200:0 awrite 200 128

@@ -234,7 +251,7 @@ absolutely sure you know what you're doing.
high | low

Change the USB current limiter to high (1.2 amps) or low (the default, 600mA)
This is only applicable to the model B+
This is only applicable to the Model B+ and the Model B, v2.

.TP
.B pwm-bal/pwm-ms
@@ -245,32 +262,6 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional)
Change the PWM range register. The default is 1024.

.TP
.B load i2c [baudrate]
This loads the i2c or drivers into the kernel and changes the permissions
on the associated /dev/ entries so that the current user has access to
them. Optionally it will set the I2C baudrate to that supplied in Kb/sec
(or as close as the Pi can manage) The default speed is 100Kb/sec.

Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the I2C device at boot time.
(or disable the device tree to continue to use this method)

.TP
.B load spi
This loads the spi drivers into the kernel and changes the permissions
on the associated /dev/ entries so that the current user has access to
them. It used to have the ability to change the buffer size from the
default of 4096 bytes to an arbitrary value, however for some time the
Pi Foundation have compiled the SPI device driver into the kernel and
this has fixed the buffer size. The way to change it now is to edit
the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to
e.g. 8192 bytes then reboot.

Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the SPI device at boot time.
(or disable the device tree to continue to use this method)

.TP
.B gbr
channel

@@ -350,7 +341,7 @@ Please report bugs to <projects@drogon.net>

.SH COPYRIGHT

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



+ 178
- 42
gpio/gpio.c View File

@@ -2,7 +2,7 @@
* gpio.c:
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
* Pi's GPIO.
* Copyright (c) 2012-2015 Gordon Henderson
* Copyright (c) 2012-2018 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -40,7 +40,7 @@
#include <gertboard.h>
#include <piFace.h>

#include "version.h"
#include "../version.h"

extern int wiringPiDebug ;

@@ -48,7 +48,7 @@ extern int wiringPiDebug ;

extern void doReadall (void) ;
extern void doAllReadall (void) ;
extern void doPins (void) ;
extern void doQmode (int argc, char *argv []) ;

#ifndef TRUE
# define TRUE (1==1)
@@ -56,16 +56,21 @@ extern void doPins (void) ;
#endif

#define PI_USB_POWER_CONTROL 38
#define I2CDETECT "/usr/sbin/i2cdetect"
#define I2CDETECT "i2cdetect"
#define MODPROBE "modprobe"
#define RMMOD "rmmod"

int wpMode ;

char *usage = "Usage: gpio -v\n"
" gpio -h\n"
" gpio [-g|-1] [-x extension:params] ...\n"
" gpio [-g|-1] ...\n"
" gpio [-d] ...\n"
" [-x extension:params] [[ -x ...]] ...\n"
" gpio [-p] <read/write/wb> ...\n"
" gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
" gpio readall/reset\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 wfi <pin> <mode>\n"
@@ -76,6 +81,8 @@ char *usage = "Usage: gpio -v\n"
" gpio load spi/i2c\n"
" gpio unload spi/i2c\n"
" gpio i2cd/i2cdetect\n"
" gpio rbx/rbd\n"
" gpio wb <value>\n"
" gpio usbp high/low\n"
" gpio gbr <channel>\n"
" gpio gbw <channel> <value>" ; // No trailing newline needed here.
@@ -103,6 +110,45 @@ static int decodePin (const char *str)


/*
* findExecutable:
* Code to locate the path to the given executable. We have a fixed list
* of locations to try which completely overrides any $PATH environment.
* This may be detrimental, however it avoids the reliance on $PATH
* which may be a security issue when this program is run a set-uid-root.
*********************************************************************************
*/

static const char *searchPath [] =
{
"/sbin",
"/usr/sbin",
"/bin",
"/usr/bin",
NULL,
} ;

static char *findExecutable (const char *progName)
{
static char *path = NULL ;
int len = strlen (progName) ;
int i = 0 ;
struct stat statBuf ;

for (i = 0 ; searchPath [i] != NULL ; ++i)
{
path = malloc (strlen (searchPath [i]) + len + 2) ;
sprintf (path, "%s/%s", searchPath [i], progName) ;

if (stat (path, &statBuf) == 0)
return path ;
free (path) ;
}

return NULL ;
}


/*
* changeOwner:
* Change the ownership of the file to the real userId of the calling
* program so we can access it.
@@ -175,9 +221,7 @@ static void checkDevTree (char *argv [])
fprintf (stderr,
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
" You need to run the raspi-config program (as root) and select the\n"
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n"
" There is more information here:\n"
" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ;
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
exit (1) ;
}
}
@@ -230,15 +274,18 @@ static void doLoad (int argc, char *argv [])
else
_doLoadUsage (argv) ;

if (findExecutable ("modprobe") == NULL)
printf ("No found\n") ;

if (!moduleLoaded (module1))
{
sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
system (cmd) ;
}

if (!moduleLoaded (module2))
{
sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
system (cmd) ;
}

@@ -292,13 +339,13 @@ static void doUnLoad (int argc, char *argv [])

if (moduleLoaded (module1))
{
sprintf (cmd, "/sbin/rmmod %s", module1) ;
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
system (cmd) ;
}

if (moduleLoaded (module2))
{
sprintf (cmd, "/sbin/rmmod %s", module2) ;
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
system (cmd) ;
}
}
@@ -310,13 +357,12 @@ static void doUnLoad (int argc, char *argv [])
*********************************************************************************
*/

static void doI2Cdetect (int argc, char *argv [])
static void doI2Cdetect (UNU int argc, char *argv [])
{
int port = piBoardRev () == 1 ? 0 : 1 ;
char command [128] ;
struct stat statBuf ;
int port = piGpioLayout () == 1 ? 0 : 1 ;
char *c, *command ;

if (stat (I2CDETECT, &statBuf) < 0)
if ((c = findExecutable (I2CDETECT)) == NULL)
{
fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
return ;
@@ -328,7 +374,8 @@ static void doI2Cdetect (int argc, char *argv [])
return ;
}

sprintf (command, "%s -y %d", I2CDETECT, port) ;
command = malloc (strlen (c) + 16) ;
sprintf (command, "%s -y %d", c, port) ;
if (system (command) < 0)
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;

@@ -341,7 +388,7 @@ static void doI2Cdetect (int argc, char *argv [])
*********************************************************************************
*/

static void doExports (int argc, char *argv [])
static void doExports (UNU int argc, UNU char *argv [])
{
int fd ;
int i, l, first ;
@@ -667,7 +714,7 @@ void doUnexportall (char *progName)
*********************************************************************************
*/

static void doReset (char *progName)
static void doReset (UNU char *progName)
{
printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
@@ -943,7 +990,7 @@ static void doAwrite (int argc, char *argv [])

/*
* doWriteByte:
* gpio write value
* gpio wb value
*********************************************************************************
*/

@@ -964,6 +1011,30 @@ static void doWriteByte (int argc, char *argv [])


/*
* doReadByte:
* gpio rbx|rbd value
*********************************************************************************
*/

static void doReadByte (int argc, char *argv [], int printHex)
{
int val ;

if (argc != 2)
{
fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ;
exit (1) ;
}

val = digitalReadByte () ;
if (printHex)
printf ("%02X\n", val) ;
else
printf ("%d\n", val) ;
}


/*
* doRead:
* Read a pin and return the value
*********************************************************************************
@@ -1027,6 +1098,34 @@ void doToggle (int argc, char *argv [])


/*
* doBlink:
* Blink an IO pin
*********************************************************************************
*/

void doBlink (int argc, char *argv [])
{
int pin ;

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

pin = atoi (argv [2]) ;

pinMode (pin, OUTPUT) ;
for (;;)
{
digitalWrite (pin, !digitalRead (pin)) ;
delay (500) ;
}

}


/*
* doPwmTone:
* Output a tone in a PWM pin
*********************************************************************************
@@ -1162,9 +1261,14 @@ static void doVersion (char *argv [])
{
int model, rev, mem, maker, warranty ;
struct stat statBuf ;
char name [80] ;
FILE *fd ;

int vMaj, vMin ;

printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
wiringPiVersion (&vMaj, &vMin) ;
printf ("gpio version: %d.%d\n", vMaj, vMin) ;
printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
@@ -1179,12 +1283,18 @@ static void doVersion (char *argv [])
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
printf (" * Device tree is enabled.\n") ;

if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO
if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
{
printf (" * This Raspberry Pi supports user-level GPIO access.\n") ;
printf (" -> See the man-page for more details\n") ;
printf (" -> ie. export WIRINGPI_GPIOMEM=1\n") ;
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
{
fgets (name, 80, fd) ;
fclose (fd) ;
printf (" *--> %s\n", name) ;
}
}

if (stat ("/dev/gpiomem", &statBuf) == 0) // 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") ;
}
@@ -1208,8 +1318,11 @@ int main (int argc, char *argv [])

if (argc == 1)
{
fprintf (stderr, "%s\n", usage) ;
return 1 ;
fprintf (stderr,
"%s: At your service!\n"
" Type: gpio -h for full details and\n"
" gpio readall for a quick printout of your connector details\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}

// Help
@@ -1217,7 +1330,7 @@ int main (int argc, char *argv [])
if (strcasecmp (argv [1], "-h") == 0)
{
printf ("%s: %s\n", argv [0], usage) ;
return 0 ;
exit (EXIT_SUCCESS) ;
}

// Version & Warranty
@@ -1225,8 +1338,8 @@ int main (int argc, char *argv [])

if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
{
printf ("%d\n", piBoardRev ()) ;
return 0 ;
printf ("%d\n", piGpioLayout ()) ;
exit (EXIT_SUCCESS) ;
}

// Version and information
@@ -1234,13 +1347,13 @@ int main (int argc, char *argv [])
if (strcmp (argv [1], "-v") == 0)
{
doVersion (argv) ;
return 0 ;
exit (EXIT_SUCCESS) ;
}

if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
@@ -1255,13 +1368,13 @@ int main (int argc, char *argv [])
printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
printf ("\n") ;
return 0 ;
exit (EXIT_SUCCESS) ;
}

if (geteuid () != 0)
{
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
return 1 ;
exit (EXIT_FAILURE) ;
}

// Initial test for /sys/class/gpio operations:
@@ -1331,6 +1444,16 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_PIFACE ;
}

// Check for -z argument so we don't actually initialise wiringPi

else if (strcasecmp (argv [1], "-z") == 0)
{
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
wpMode = WPI_MODE_UNINITIALISED ;
}

// Default to wiringPi mode

else
@@ -1340,17 +1463,25 @@ int main (int argc, char *argv [])
}

// Check for -x argument to load in a new extension
// -x extension:base:args
// Can load many modules, but unless daemon mode we can only send one
// command at a time.

if (strcasecmp (argv [1], "-x") == 0)
while (strcasecmp (argv [1], "-x") == 0)
{
if (argc < 3)
{
fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}

if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages
if (!loadWPiExtension (argv [0], argv [2], TRUE))
{
fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ;
exit (EXIT_FAILURE) ;
}

// Shift args down by 2

for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
@@ -1375,6 +1506,7 @@ int main (int argc, char *argv [])
// GPIO Nicies

else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
else if (strcasecmp (argv [1], "blink" ) == 0) doBlink (argc, argv) ;

// Pi Specifics

@@ -1386,11 +1518,14 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ;
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;
else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
else
@@ -1398,5 +1533,6 @@ int main (int argc, char *argv [])
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
exit (EXIT_FAILURE) ;
}

return 0 ;
}

+ 1
- 1
gpio/pintest View File

@@ -5,7 +5,7 @@
# Copyright (c) 2013-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 36
- 7
gpio/readall.c View File

@@ -1,7 +1,7 @@
/*
* readall.c:
* The readall functions - getting a bit big, so split them out.
* Copyright (c) 2012-2015 Gordon Henderson
* Copyright (c) 2012-2018 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -118,7 +118,7 @@ static char *physNames [64] =
NULL,

" 3.3v", "5v ",
" SDA.1", "5V ",
" SDA.1", "5v ",
" SCL.1", "0v ",
"GPIO. 7", "TxD ",
" 0v", "RxD ",
@@ -287,22 +287,26 @@ void abReadall (int model, int rev)

/*
* piPlusReadall:
* Read all the pins on the model A+ or the B+
* Read all the pins on the model A+ or the B+ or actually, all 40-pin Pi's
*********************************************************************************
*/

static void plus2header (int model)
{
/**/ if (model == PI_MODEL_AP)
printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ;
printf (" +-----+-----+---------+------+---+---Pi A+--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_BP)
printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ;
printf (" +-----+-----+---------+------+---+---Pi B+--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_ZERO)
printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_ZERO_W)
printf (" +-----+-----+---------+------+---+-Pi ZeroW-+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_2)
printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_3)
printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_3P)
printf (" +-----+-----+---------+------+---+---Pi 3+--+---+------+---------+-----+-----+\n") ;
else
printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ;
}
@@ -346,14 +350,18 @@ void doReadall (void)

/**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B))
abReadall (model, rev) ;
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_3) || (model == PI_MODEL_ZERO))
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) ||
(model == PI_MODEL_2) ||
(model == PI_MODEL_3) || (model == PI_MODEL_3P) ||
(model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W))
piPlusReadall (model) ;
else if (model == PI_MODEL_CM)
else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3))
allReadall () ;
else
printf ("Oops - unable to determine board type... model: %d\n", model) ;
}


/*
* doAllReadall:
* Force reading of all pins regardless of Pi model
@@ -364,3 +372,24 @@ void doAllReadall (void)
{
allReadall () ;
}


/*
* doQmode:
* Query mode on a pin
*********************************************************************************
*/

void doQmode (int argc, char *argv [])
{
int pin ;

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

pin = atoi (argv [2]) ;
printf ("%s\n", alts [getAlt (pin)]) ;
}

+ 1
- 1
gpio/test.sh View File

@@ -5,7 +5,7 @@
# in-turn.
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by


+ 0
- 1
gpio/version.h View File

@@ -1 +0,0 @@
#define VERSION "2.32"

+ 8
- 4
newVersion View File

@@ -7,7 +7,7 @@
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -25,8 +25,12 @@

echo Updating to version: `cat VERSION`

rm -f gpio/version.h
echo "#define VERSION \"`cat VERSION`\"" > gpio/version.h
rm -f version.h
vMaj=`cut -d. -f1 VERSION`
vMin=`cut -d. -f2 VERSION`
echo "#define VERSION \"`cat VERSION`\"" > version.h
echo "#define VERSION_MAJOR $vMaj" >> version.h
echo "#define VERSION_MINOR $vMin" >> version.h

rm -f debian-template/wiringPi/DEBIAN/control
cat > debian-template/wiringPi/DEBIAN/control <<EOF
@@ -39,5 +43,5 @@ Depends: libc6
Maintainer: Gordon Henderson <projects@drogon.net>
Description: The wiringPi libraries, headers and gpio command
Libraries to allow GPIO access on a Raspberry Pi from C and C++
programs as well as from the command-line
and BASIC programs as well as from the command-line
EOF

+ 5
- 0
update View File

@@ -0,0 +1,5 @@
#!/bin/sh

# update - update source files from master on yakko

rsync -aHx --exclude='*.o' --exclude='*~' -v --delete gordon@yakko:rpi/git/wiringPi/ .

+ 3
- 0
version.h View File

@@ -0,0 +1,3 @@
#define VERSION "2.46"
#define VERSION_MAJOR 2
#define VERSION_MINOR 46

+ 165
- 0
wiringPi/Makefile View File

@@ -0,0 +1,165 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
#
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# https://projects.drogon.net/raspberry-pi/wiringpi/
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################

VERSION=$(shell cat ../VERSION)
DESTDIR?=/usr
PREFIX?=/local

LDCONFIG?=ldconfig

ifneq ($V,1)
Q ?= @
endif

STATIC=libwiringPi.a
DYNAMIC=libwiringPi.so.$(VERSION)

#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I.
DEFS = -D_GNU_SOURCE
CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC
#CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Wconversion -Winline $(INCLUDE) -pipe -fPIC

LIBS = -lm -lpthread -lrt -lcrypt

###############################################################################

SRC = wiringPi.c \
wiringSerial.c wiringShift.c \
piHiPri.c piThread.c \
wiringPiSPI.c wiringPiI2C.c \
softPwm.c softTone.c \
mcp23008.c mcp23016.c mcp23017.c \
mcp23s08.c mcp23s17.c \
sr595.c \
pcf8574.c pcf8591.c \
mcp3002.c mcp3004.c mcp4802.c mcp3422.c \
max31855.c max5322.c ads1115.c \
sn3218.c \
bmp180.c htu21d.c ds18b20.c rht03.c \
drcSerial.c drcNet.c \
pseudoPins.c \
wpiExtensions.c

HEADERS = $(shell ls *.h)

OBJ = $(SRC:.c=.o)

all: $(DYNAMIC)

.PHONY: static
static:
$Q cat noMoreStatic

$(DYNAMIC): $(OBJ)
$Q echo "[Link (Dynamic)]"
$Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) $(LIBS) $(OBJ)

.c.o:
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@


.PHONY: clean
clean:
$Q echo "[Clean]"
$Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*

.PHONY: tags
tags: $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)


.PHONY: install
install: $(DYNAMIC)
$Q echo "[Install Headers]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include
$Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include
$Q echo "[Install Dynamic Lib]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
$Q install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
$Q $(LDCONFIG)

.PHONY: install-deb
install-deb: $(DYNAMIC)
$Q echo "[Install Headers: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include
$Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include
$Q echo "[Install Dynamic Lib: deb]"
install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib
install -m 0755 libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION)
ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so

.PHONY: uninstall
uninstall:
$Q echo "[UnInstall]"
$Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS)
$Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPi.*
$Q $(LDCONFIG)


.PHONY: depend
depend:
makedepend -Y $(SRC) $(SRC_I2C)

# DO NOT DELETE

wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h
wiringSerial.o: wiringSerial.h
wiringShift.o: wiringPi.h wiringShift.h
piHiPri.o: wiringPi.h
piThread.o: wiringPi.h
wiringPiSPI.o: wiringPi.h wiringPiSPI.h
wiringPiI2C.o: wiringPi.h wiringPiI2C.h
softPwm.o: wiringPi.h softPwm.h
softTone.o: wiringPi.h softTone.h
mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h
mcp23016.o: wiringPi.h wiringPiI2C.h mcp23016.h mcp23016reg.h
mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h
mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
sr595.o: wiringPi.h sr595.h
pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h
pcf8591.o: wiringPi.h wiringPiI2C.h pcf8591.h
mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h
mcp3004.o: wiringPi.h wiringPiSPI.h mcp3004.h
mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h
max31855.o: wiringPi.h wiringPiSPI.h max31855.h
max5322.o: wiringPi.h wiringPiSPI.h max5322.h
ads1115.o: wiringPi.h wiringPiI2C.h ads1115.h
sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h
bmp180.o: wiringPi.h wiringPiI2C.h bmp180.h
htu21d.o: wiringPi.h wiringPiI2C.h htu21d.h
ds18b20.o: wiringPi.h ds18b20.h
drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h
pseudoPins.o: wiringPi.h pseudoPins.h
wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h
wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h
wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h ads1115.h sn3218.h
wpiExtensions.o: drcSerial.h pseudoPins.h bmp180.h htu21d.h ds18b20.h
wpiExtensions.o: wpiExtensions.h

+ 1
- 1
wiringPi/ads1115.c View File

@@ -228,7 +228,7 @@ static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data)
{
if ( (data < 0) || (data > 7) ) // Use default if out of range
data = 4 ;
node->data0 = dataRates [data] ;
node->data1 = dataRates [data] ; // Bugfix 0-1 by "Eric de jong (gm)" <ericdejong@gmx.net> - Thanks.
}
}


+ 237
- 0
wiringPi/bmp180.c View File

@@ -0,0 +1,237 @@
/*
* bmp180.c:
* Extend wiringPi with the BMP180 I2C Pressure and Temperature
* sensor. This is used in the Pi Weather Station
* Copyright (c) 2016 Gordon Henderson
*
* Information from the document held at:
* http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf
* was very useful when building this code.
*
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

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

#include "wiringPi.h"
#include "wiringPiI2C.h"

#include "bmp180.h"

#undef DEBUG

#define I2C_ADDRESS 0x77
#define BMP180_OSS 0


// Static calibration data
// The down-side of this is that there can only be one BMP180 in
// a system - which is practice isn't an issue as it's I2C
// address is fixed.

static int16_t AC1, AC2, AC3 ;
static uint16_t AC4, AC5, AC6 ;
static int16_t VB1, VB2 ;
static int16_t MB, MC, MD ;

static double c5, c6, mc, md, x0, x1, x2, yy0, yy1, yy2, p0, p1, p2 ;

// Pressure & Temp variables

uint32_t cPress, cTemp ;

static int altitude ;

/*
* read16:
* Quick hack to read the 16-bit data with the correct endian
*********************************************************************************
*/

uint16_t read16 (int fd, int reg)
{
return (wiringPiI2CReadReg8 (fd, reg) << 8) | wiringPiI2CReadReg8 (fd, reg + 1) ;

}


/*
* bmp180ReadTempPress:
* Does the hard work of reading the sensor
*********************************************************************************
*/

static void bmp180ReadTempPress (int fd)
{
double fTemp, fPress ;
double tu, a ;
double pu, s, x, y, z ;

uint8_t data [4] ;

// Start a temperature sensor reading

wiringPiI2CWriteReg8 (fd, 0xF4, 0x2E) ;
delay (5) ;

// Read the raw data

data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ;
data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ;

// And calculate...

tu = (data [0] * 256.0) + data [1] ;

a = c5 * (tu - c6) ;
fTemp = a + (mc / (a + md)) ;
cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;

#ifdef DEBUG
printf ("fTemp: %f, cTemp: %6d\n", fTemp, cTemp) ;
#endif

// Start a pressure snsor reading

wiringPiI2CWriteReg8 (fd, 0xF4, 0x34 | (BMP180_OSS << 6)) ;
delay (5) ;

// Read the raw data

data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ;
data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ;
data [2] = wiringPiI2CReadReg8 (fd, 0xF8) ;

// And calculate...

pu = ((double)data [0] * 256.0) + (double)data [1] + ((double)data [2] / 256.0) ;
s = fTemp - 25.0 ;
x = (x2 * pow (s, 2.0)) + (x1 * s) + x0 ;
y = (yy2 * pow (s, 2.0)) + (yy1 * s) + yy0 ;
z = (pu - x) / y ;
fPress = (p2 * pow (z, 2.0)) + (p1 * z) + p0 ;
cPress = (int)rint (((100.0 * fPress) + 0.5) / 10.0) ;

#ifdef DEBUG
printf ("fPress: %f, cPress: %6d\n", fPress, cPress) ;
#endif
}


/*
* myAnalogWrite:
* Write to a fake register to represent the height above sea level
* so that the peudo millibar register can read the pressure in mB
*********************************************************************************
*/

static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
int chan = pin - node->pinBase ;

if (chan == 0)
altitude = value ;
}

/*
* myAnalogRead:
*********************************************************************************
*/

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int chan = pin - node->pinBase ;

bmp180ReadTempPress (node->fd) ;

/**/ if (chan == 0) // Read Temperature
return cTemp ;
else if (chan == 1) // Pressure
return cPress ;
else if (chan == 2) // Pressure in mB
return cPress / pow (1 - ((double)altitude / 44330.0), 5.255) ;
else
return -9999 ;

}


/*
* bmp180Setup:
* Create a new instance of a PCF8591 I2C GPIO interface. We know it
* has 4 pins, (4 analog inputs and 1 analog output which we'll shadow
* input 0) so all we need to know here is the I2C address and the
* user-defined pin base.
*********************************************************************************
*/

int bmp180Setup (const int pinBase)
{
double c3, c4, b1 ;
int fd ;
struct wiringPiNodeStruct *node ;

if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
return FALSE ;

node = wiringPiNewNode (pinBase, 4) ;

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

// Read calibration data

AC1 = read16 (fd, 0xAA) ;
AC2 = read16 (fd, 0xAC) ;
AC3 = read16 (fd, 0xAE) ;
AC4 = read16 (fd, 0xB0) ;
AC5 = read16 (fd, 0xB2) ;
AC6 = read16 (fd, 0xB4) ;
VB1 = read16 (fd, 0xB6) ;
VB2 = read16 (fd, 0xB8) ;
MB = read16 (fd, 0xBA) ;
MC = read16 (fd, 0xBC) ;
MD = read16 (fd, 0xBE) ;

// Calculate coefficients

c3 = 160.0 * pow (2.0, -15.0) * AC3 ;
c4 = pow (10.0, -3.0) * pow(2.0,-15.0) * AC4 ;
b1 = pow (160.0, 2.0) * pow(2.0,-30.0) * VB1 ;
c5 = (pow (2.0, -15.0) / 160.0) * AC5 ;
c6 = AC6 ;
mc = (pow (2.0, 11.0) / pow(160.0,2.0)) * MC ;
md = MD / 160.0 ;
x0 = AC1 ;
x1 = 160.0 * pow (2.0, -13.0) * AC2 ;
x2 = pow (160.0, 2.0) * pow(2.0,-25.0) * VB2 ;
yy0 = c4 * pow (2.0, 15.0) ;
yy1 = c4 * c3 ;
yy2 = c4 * b1 ;
p0 = (3791.0 - 8.0) / 1600.0 ;
p1 = 1.0 - 7357.0 * pow (2.0, -20.0) ;
p2 = 3038.0 * 100.0 * pow (2.0, -36.0) ;

return TRUE ;
}

+ 34
- 0
wiringPi/bmp180.h View File

@@ -0,0 +1,34 @@
/*
* bmp180.h:
* Extend wiringPi with the BMP180 I2C Pressure and Temperature
* sensor.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int bmp180Setup (const int pinBase) ;

#ifdef __cplusplus
}
#endif

+ 405
- 0
wiringPi/drcNet.c View File

@@ -0,0 +1,405 @@
/*
* drcNet.h:
* Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <crypt.h>


#include "wiringPi.h"
#include "drcNet.h"
#include "../wiringPiD/drcNetCmd.h"


/*
* remoteReadline:
* Read in a line of data from the remote server, ending with a newline
* character which is not stored. Returns the length or < 0 on
* any sort of failure.
*********************************************************************************
*/

static int remoteReadline (int fd, char *buf, int max)
{
int len = 0 ;
char c ;

for (;;)
{
if (read (fd, &c, 1) < 1)
return -1 ;

if (c == '\n')
return len ;

*buf++ = c ;
if (++len == max)
return len ;
}
}


/*
* getChallenge:
* Read in lines from the remote site until we get one identified
* as the challenge. This line contains the password salt.
*********************************************************************************
*/

static char *getChallenge (int fd)
{
static char buf [1024] ;
int num ;

for (;;)
{
if ((num = remoteReadline (fd, buf, 1023)) < 0)
return NULL ;
buf [num] = 0 ;

if (strncmp (buf, "Challenge ", 10) == 0)
return &buf [10] ;
}
}


/*
* authenticate:
* Read in the challenge from the server, use it to encrypt our password
* and send it back to the server. Wait for a reply back from the server
* to say that we're good to go.
* The server will simply disconnect on a bad response. No 3 chances here.
*********************************************************************************
*/

static int authenticate (int fd, const char *pass)
{
char *challenge ;
char *encrypted ;
char salted [1024] ;

if ((challenge = getChallenge (fd)) == NULL)
return -1 ;

sprintf (salted, "$6$%s$", challenge) ;
encrypted = crypt (pass, salted) ;
// This is an assertion, or sanity check on my part...
// The '20' comes from the $6$ then the 16 characters of the salt,
// then the terminating $.

if (strncmp (encrypted, salted, 20) != 0)
{
errno = EBADE ;
return -1 ;
}

// 86 characters is the length of the SHA-256 hash

if (write (fd, encrypted + 20, 86) == 86)
return 0 ;
else
return -1 ;
}


/*
* _drcSetupNet:
* Do the hard work of establishing a network connection and authenticating
* the password.
*********************************************************************************
*/

int _drcSetupNet (const char *ipAddress, const char *port, const char *password)
{
struct addrinfo hints;
struct addrinfo *result, *rp ;
struct in6_addr serveraddr ;
int remoteFd ;

// Start by seeing if we've been given a (textual) numeric IP address
// which will save lookups in getaddrinfo()

memset (&hints, 0, sizeof (hints)) ;
hints.ai_flags = AI_NUMERICSERV ;
hints.ai_family = AF_UNSPEC ;
hints.ai_socktype = SOCK_STREAM ;
hints.ai_protocol = 0 ;

if (inet_pton (AF_INET, ipAddress, &serveraddr) == 1) // Valid IPv4
{
hints.ai_family = AF_INET ;
hints.ai_flags |= AI_NUMERICHOST ;
}
else
{
if (inet_pton (AF_INET6, ipAddress, &serveraddr) == 1) // Valid IPv6
{
hints.ai_family = AF_INET6 ;
hints.ai_flags |= AI_NUMERICHOST ;
}
}

// Now use getaddrinfo() with the newly supplied hints

if (getaddrinfo (ipAddress, port, &hints, &result) != 0)
return -1 ;

// Now try each address in-turn until we get one that connects...

for (rp = result; rp != NULL; rp = rp->ai_next)
{
if ((remoteFd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
continue ;

if (connect (remoteFd, rp->ai_addr, rp->ai_addrlen) < 0)
continue ;

if (authenticate (remoteFd, password) < 0)
{
close (remoteFd) ;
errno = EACCES ; // Permission denied
return -1 ;
}
else
return remoteFd ;
}

errno = EHOSTUNREACH ; // Host unreachable - may not be right, but good enough
return -1 ; // Nothing connected
}


/*
* myPinMode:
* Change the pin mode on the remote DRC device
*********************************************************************************
*/

static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PIN_MODE ;
cmd.data = mode ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}


/*
* myPullUpDnControl:
*********************************************************************************
*/

static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PULL_UP_DN ;
cmd.data = mode ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}


/*
* myDigitalWrite:
*********************************************************************************
*/

static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_WRITE ;
cmd.data = value ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}


/*
* myDigitalWrite8:
*********************************************************************************

static void myDigitalWrite8 (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_WRITE8 ;
cmd.data = value ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}
*/


/*
* myAnalogWrite:
*********************************************************************************
*/

static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_ANALOG_WRITE ;
cmd.data = value ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}


/*
* myPwmWrite:
*********************************************************************************
*/

static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_PWM_WRITE ;
cmd.data = value ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
}


/*
* myAnalogRead:
*********************************************************************************
*/

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_ANALOG_READ ;
cmd.data = 0 ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;

return cmd.data ;
}


/*
* myDigitalRead:
*********************************************************************************
*/

static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_READ ;
cmd.data = 0 ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;

return cmd.data ;
}


/*
* myDigitalRead8:
*********************************************************************************

static unsigned int myDigitalRead8 (struct wiringPiNodeStruct *node, int pin)
{
struct drcNetComStruct cmd ;

cmd.pin = pin - node->pinBase ;
cmd.cmd = DRCN_DIGITAL_READ8 ;
cmd.data = 0 ;

(void)send (node->fd, &cmd, sizeof (cmd), 0) ;
(void)recv (node->fd, &cmd, sizeof (cmd), 0) ;

return cmd.data ;
}
*/


/*
* drcNet:
* Create a new instance of an DRC GPIO interface.
* Could be a variable nunber of pins here - we might not know in advance.
*********************************************************************************
*/

int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password)
{
int fd, len ;
struct wiringPiNodeStruct *node ;

if ((fd = _drcSetupNet (ipAddress, port, password)) < 0)
return FALSE ;

len = sizeof (struct drcNetComStruct) ;

if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return FALSE ;

node = wiringPiNewNode (pinBase, numPins) ;

node->fd = fd ;
node->pinMode = myPinMode ;
node->pullUpDnControl = myPullUpDnControl ;
node->analogRead = myAnalogRead ;
node->analogRead = myAnalogRead ;
node->analogWrite = myAnalogWrite ;
node->digitalRead = myDigitalRead ;
node->digitalWrite = myDigitalWrite ;
//node->digitalRead8 = myDigitalRead8 ;
//node->digitalWrite8 = myDigitalWrite8 ;
node->pwmWrite = myPwmWrite ;

return TRUE ;
}

+ 42
- 0
wiringPi/drcNet.h View File

@@ -0,0 +1,42 @@
/*
* drcNet.h:
* Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

/*********
struct drcNetStruct
{
uint32_t pin ;
uint32_t cmd ;
uint32_t data ;
} ;
**************/

#ifdef __cplusplus
extern "C" {
#endif

extern int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password) ;

#ifdef __cplusplus
}
#endif

+ 146
- 0
wiringPi/ds18b20.c View File

@@ -0,0 +1,146 @@
/*
* ds18b20.c:
* Extend wiringPi with the DS18B20 1-Wire temperature sensor.
* This is used in the Pi Weather Station and many other places.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>

#include "wiringPi.h"

#include "ds18b20.h"

#define W1_PREFIX "/sys/bus/w1/devices/28-"
#define W1_POSTFIX "/w1_slave"


/*
* myAnalogRead:
*********************************************************************************
*/

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int chan = pin - node->pinBase ;
int fd = node->fd ;
char buffer [4096] ;
char *p ;
int temp, sign ;

if (chan != 0)
return -9999 ;

// Rewind the file - we're keeping it open to keep things going
// smoothly

lseek (fd, 0, SEEK_SET) ;

// Read the file - we know it's only a couple of lines, so this ought to be
// more than enough

if (read (fd, buffer, 4096) <= 0) // Read nothing, or it failed in some odd way
return -9998 ;

// Look for YES, then t=

if (strstr (buffer, "YES") == NULL)
return -9997 ;

if ((p = strstr (buffer, "t=")) == NULL)
return -9996 ;

// p points to the 't', so we skip over it...

p += 2 ;

// and extract the number
// (without caring about overflow)


if (*p == '-') // Negative number?
{
sign = -1 ;
++p ;
}
else
sign = 1 ;

temp = 0 ;
while (isdigit (*p))
{
temp = temp * 10 + (*p - '0') ;
++p ;
}

// We know it returns temp * 1000, but we only really want temp * 10, so
// do a bit of rounding...

temp = (temp + 50) / 100 ;
return temp * sign ;
}


/*
* ds18b20Setup:
* Create a new instance of a DS18B20 temperature sensor.
*********************************************************************************
*/

int ds18b20Setup (const int pinBase, const char *deviceId)
{
int fd ;
struct wiringPiNodeStruct *node ;
char *fileName ;

// Allocate space for the filename

if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL)
return FALSE ;

sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ;

fd = open (fileName, O_RDONLY) ;

free (fileName) ;

if (fd < 0)
return FALSE ;

// We'll keep the file open, to make access a little faster
// although it's very slow reading these things anyway )-:

node = wiringPiNewNode (pinBase, 1) ;

node->fd = fd ;
node->analogRead = myAnalogRead ;

return TRUE ;
}

+ 34
- 0
wiringPi/ds18b20.h View File

@@ -0,0 +1,34 @@
/*
* bmp180.h:
* Extend wiringPi with the BMP180 I2C Pressure and Temperature
* sensor.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int ds18b20Setup (const int pinBase, const char *serialNum) ;

#ifdef __cplusplus
}
#endif

+ 150
- 0
wiringPi/htu21d.c View File

@@ -0,0 +1,150 @@
/*
* htu21d.c:
* Extend wiringPi with the HTU21D I2C humidity and Temperature
* sensor. This is used in the Pi Weather station.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

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

#include "wiringPi.h"
#include "wiringPiI2C.h"

#include "htu21d.h"

#define DEBUG
#undef FAKE_SENSOR

#define I2C_ADDRESS 0x40

int checksum (UNU uint8_t data [4])
{
return TRUE ;
}



/*
* myAnalogRead:
*********************************************************************************
*/

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int chan = pin - node->pinBase ;
int fd = node->fd ;
uint8_t data [4] ;
uint32_t sTemp, sHumid ;
double fTemp, fHumid ;
int cTemp, cHumid ;

/**/ if (chan == 0) // Read Temperature
{

// Send read temperature command:

data [0] = 0xF3 ;
if (write (fd, data, 1) != 1)
return -9999 ;

// Wait then read the data

delay (50) ;
if (read (fd, data, 3) != 3)
return -9998 ;

if (!checksum (data))
return -9997 ;

// Do the calculation

sTemp = (data [0] << 8) | data [1] ;
fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ;
cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;
return cTemp ;
}
else if (chan == 1) // humidity
{
// Send read humidity command:

data [0] = 0xF5 ;
if (write (fd, data, 1) != 1)
return -9999 ;

// Wait then read the data

delay (50) ;
if (read (fd, data, 3) != 3)
return -9998 ;

if (!checksum (data))
return -9997 ;

sHumid = (data [0] << 8) | data [1] ;
fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ;
cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ;
return cHumid ;
}
else
return -9999 ;
}


/*
* htu21dSetup:
* Create a new instance of a HTU21D I2C GPIO interface.
* This chip has a fixed I2C address, so we are not providing any
* allowance to change this.
*********************************************************************************
*/

int htu21dSetup (const int pinBase)
{
int fd ;
struct wiringPiNodeStruct *node ;
uint8_t data ;
int status ;

if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
return FALSE ;

node = wiringPiNewNode (pinBase, 2) ;

node->fd = fd ;
node->analogRead = myAnalogRead ;

// Send a reset code to it:

data = 0xFE ;
if (write (fd, &data, 1) != 1)
return FALSE ;

delay (15) ;

// Read the status register to check it's really there

status = wiringPiI2CReadReg8 (fd, 0xE7) ;

return (status == 0x02) ? TRUE : FALSE ;
}

+ 34
- 0
wiringPi/htu21d.h View File

@@ -0,0 +1,34 @@
/*
* htu21d.h:
* Extend wiringPi with the HTU21D I2C Humidity and Temperature
* sensor.
* Copyright (c) 2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#ifdef __cplusplus
extern "C" {
#endif

extern int htu21dSetup (const int pinBase) ;

#ifdef __cplusplus
}
#endif

+ 1
- 1
wiringPi/mcp3002.c View File

@@ -49,7 +49,7 @@ static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)

wiringPiSPIDataRW (node->fd, spiData, 2) ;

return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
}




+ 20
- 0
wiringPi/noMoreStatic View File

@@ -0,0 +1,20 @@

wiringPi is no-longer shipped with the ability to statically link it.

Many reasons but the biggest issue is people who have statically linked
wiringPi into their product - for example a Pi UPS device or a Tetris-like
game and not subsequently shipped their modified sources. These people are
no better than common thieves with complete disregard to the conditions
of the LGPL that wiringPi ships with.

Additionally, many think it's a good idea to statically link wiringPi
into their favourite language - like Node, and Java and other itsy bitsy
little things. These people have a complete and utter disregard to what
happens underneath when e.g. the Linux kernel changes on the Pi then
wiringPi stops as it depends on some Pi kernel features, then the poor
user get in-touch with me and I've had over 10,000 emails so-far and
it's now beyond a joke.

DO NOT STATICALLY LINK WIRINGPI.

Gordon Henderson, March 2018.

+ 1
- 1
wiringPi/pcf8591.c View File

@@ -36,7 +36,7 @@
*********************************************************************************
*/

static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int value)
{
unsigned char b [2] ;
b [0] = 0x40 ;


+ 95
- 0
wiringPi/pseudoPins.c View File

@@ -0,0 +1,95 @@
/*
* pseudoPins.c:
* Extend wiringPi with a number of pseudo pins which can be
* digitally or analog written/read.
*
* Note:
* Just one set of pseudo pins can exist per Raspberry Pi.
* These pins are shared between all programs running on
* that Raspberry Pi. The values are also persistant as
* they live in shared RAM. This gives you a means for
* temporary variable storing/sharing between programs,
* or for other cunning things I've not thought of yet..
*
* Copyright (c) 2012-2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define SHARED_NAME "wiringPiPseudoPins"
#define PSEUDO_PINS 64

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

#include <wiringPi.h>

#include "pseudoPins.h"

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int *ptr = (int *)node->data0 ;
int myPin = pin - node->pinBase ;

return *(ptr + myPin) ;
}


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

*(ptr + myPin) = value ;
}


/*
* pseudoPinsSetup:
* Create a new wiringPi device node for the pseudoPins driver
*********************************************************************************
*/

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 ;
}

+ 26
- 0
wiringPi/pseudoPins.h View File

@@ -0,0 +1,26 @@
/*
* pseudoPins.h:
* Extend wiringPi with a number of pseudo pins which can be
* digitally or analog written/read.
* Copyright (c) 2012-2016 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

extern int pseudoPinsSetup (const int pinBase) ;

+ 252
- 0
wiringPi/rht03.c View File

@@ -0,0 +1,252 @@
/*
* rht03.c:
* Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <sys/time.h>
#include <stdio.h>
#include <stdio.h>
#include <time.h>

#include "wiringPi.h"
#include "rht03.h"

/*
* maxDetectLowHighWait:
* Wait for a transition from low to high on the bus
*********************************************************************************
*/

static int maxDetectLowHighWait (const int pin)
{
struct timeval now, timeOut, timeUp ;

// If already high then wait for pin to go low

gettimeofday (&now, NULL) ;
timerclear (&timeOut) ;
timeOut.tv_usec = 1000 ;
timeradd (&now, &timeOut, &timeUp) ;

while (digitalRead (pin) == HIGH)
{
gettimeofday (&now, NULL) ;
if (timercmp (&now, &timeUp, >))
return FALSE ;
}

// Wait for it to go HIGH

gettimeofday (&now, NULL) ;
timerclear (&timeOut) ;
timeOut.tv_usec = 1000 ;
timeradd (&now, &timeOut, &timeUp) ;

while (digitalRead (pin) == LOW)
{
gettimeofday (&now, NULL) ;
if (timercmp (&now, &timeUp, >))
return FALSE ;
}

return TRUE ;
}


/*
* maxDetectClockByte:
* Read in a single byte from the MaxDetect bus
*********************************************************************************
*/

static unsigned int maxDetectClockByte (const int pin)
{
unsigned int byte = 0 ;
int bit ;

for (bit = 0 ; bit < 8 ; ++bit)
{
if (!maxDetectLowHighWait (pin))
return 0 ;

// bit starting now - we need to time it.

delayMicroseconds (30) ;
byte <<= 1 ;
if (digitalRead (pin) == HIGH) // It's a 1
byte |= 1 ;
}

return byte ;
}


/*
* maxDetectRead:
* Read in and return the 4 data bytes from the MaxDetect sensor.
* Return TRUE/FALSE depending on the checksum validity
*********************************************************************************
*/

static int maxDetectRead (const int pin, unsigned char buffer [4])
{
int i ;
unsigned int checksum ;
unsigned char localBuf [5] ;
struct timeval now, then, took ;

// See how long we took

gettimeofday (&then, NULL) ;

// Wake up the RHT03 by pulling the data line low, then high
// Low for 10mS, high for 40uS.

pinMode (pin, OUTPUT) ;
digitalWrite (pin, 0) ; delay (10) ;
digitalWrite (pin, 1) ; delayMicroseconds (40) ;
pinMode (pin, INPUT) ;

// Now wait for sensor to pull pin low

if (!maxDetectLowHighWait (pin))
return FALSE ;

// and read in 5 bytes (40 bits)

for (i = 0 ; i < 5 ; ++i)
localBuf [i] = maxDetectClockByte (pin) ;

checksum = 0 ;
for (i = 0 ; i < 4 ; ++i)
{
buffer [i] = localBuf [i] ;
checksum += localBuf [i] ;
}
checksum &= 0xFF ;

// See how long we took
gettimeofday (&now, NULL) ;
timersub (&now, &then, &took) ;

// Total time to do this should be:
// 10mS + 40µS - reset
// + 80µS + 80µS - sensor doing its low -> high thing
// + 40 * (50µS + 27µS (0) or 70µS (1) )
// = 15010µS
// so if we take more than that, we've had a scheduling interruption and the
// reading is probably bogus.

if ((took.tv_sec != 0) || (took.tv_usec > 16000))
return FALSE ;

return checksum == localBuf [4] ;
}


/*
* myReadRHT03:
* Read the Temperature & Humidity from an RHT03 sensor
* Values returned are *10, so 123 is 12.3.
*********************************************************************************
*/

static int myReadRHT03 (const int pin, int *temp, int *rh)
{
int result ;
unsigned char buffer [4] ;

// Read ...
result = maxDetectRead (pin, buffer) ;

if (!result)
return FALSE ;

*rh = (buffer [0] * 256 + buffer [1]) ;
*temp = (buffer [2] * 256 + buffer [3]) ;

if ((*temp & 0x8000) != 0) // Negative
{
*temp &= 0x7FFF ;
*temp = -*temp ;
}

// Discard obviously bogus readings - the checksum can't detect a 2-bit error
// (which does seem to happen - no realtime here)

if ((*rh > 999) || (*temp > 800) || (*temp < -400))
return FALSE ;

return TRUE ;
}


/*
* myAnalogRead:
*********************************************************************************
*/

static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
int piPin = node->fd ;
int chan = pin - node->pinBase ;
int temp = -9997 ;
int rh = -9997 ;
int try ;

if (chan > 1)
return -9999 ; // Bad parameters

for (try = 0 ; try < 10 ; ++try)
{
if (myReadRHT03 (piPin, &temp, &rh))
return chan == 0 ? temp : rh ;
}

return -9998 ;
}


/*
* rht03Setup:
* Create a new instance of an RHT03 temperature sensor.
*********************************************************************************
*/

int rht03Setup (const int pinBase, const int piPin)
{
struct wiringPiNodeStruct *node ;

if ((piPin & PI_GPIO_MASK) != 0) // Must be an on-board pin
return FALSE ;
// 2 pins - temperature and humidity

node = wiringPiNewNode (pinBase, 2) ;

node->fd = piPin ;
node->analogRead = myAnalogRead ;

return TRUE ;
}

+ 25
- 0
wiringPi/rht03.h View File

@@ -0,0 +1,25 @@
/*
* rht03.h:
* Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
* Copyright (c) 2016-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

extern int rht03Setup (const int pinBase, const int devicePin) ;

+ 41
- 24
wiringPi/softPwm.c View File

@@ -1,7 +1,7 @@
/*
* softPwm.c:
* Provide 2 channels of software driven PWM.
* Copyright (c) 2012-2014 Gordon Henderson
* Provide many channels of software driven PWM.
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -23,17 +23,18 @@
*/

#include <stdio.h>
#include <malloc.h>
#include <pthread.h>

#include "wiringPi.h"
#include "softPwm.h"

// MAX_PINS:
// This is more than the number of Pi pins because we can actually softPwm
// pins that are on GPIO expanders. It's not that efficient and more than 1 or
// 2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however...
// This is more than the number of Pi pins because we can actually softPwm.
// Once upon a time I let pins on gpio expanders be softPwm'd, but it's really
// really not a good thing.

#define MAX_PINS 1024
#define MAX_PINS 64

// The PWM Frequency is derived from the "pulse time" below. Essentially,
// the frequency is a function of the range and this pulse time.
@@ -44,7 +45,7 @@
// It's possible to get a higher frequency by lowering the pulse time,
// however CPU uage will skyrocket as wiringPi uses a hard-loop to time
// periods under 100µS - this is because the Linux timer calls are just
// accurate at all, and have an overhead.
// not accurate at all, and have an overhead.
//
// Another way to increase the frequency is to reduce the range - however
// that reduces the overall output accuracy...
@@ -63,7 +64,7 @@ static volatile int newPin = -1 ;
*********************************************************************************
*/

static PI_THREAD (softPwmThread)
static void *softPwmThread (void *arg)
{
int pin, mark, space ;
struct sched_param param ;
@@ -71,6 +72,9 @@ static PI_THREAD (softPwmThread)
param.sched_priority = sched_get_priority_max (SCHED_RR) ;
pthread_setschedparam (pthread_self (), SCHED_RR, &param) ;

pin = *((int *)arg) ;
free (arg) ;

pin = newPin ;
newPin = -1 ;

@@ -102,14 +106,15 @@ static PI_THREAD (softPwmThread)

void softPwmWrite (int pin, int value)
{
pin &= (MAX_PINS - 1) ;
/**/ if (value < 0)
value = 0 ;
else if (value > range [pin])
value = range [pin] ;
if (pin < MAX_PINS)
{
/**/ if (value < 0)
value = 0 ;
else if (value > range [pin])
value = range [pin] ;

marks [pin] = value ;
marks [pin] = value ;
}
}


@@ -123,21 +128,30 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)
{
int res ;
pthread_t myThread ;
int *passPin ;

if (pin >= MAX_PINS)
return -1 ;

if (range [pin] != 0) // Already running on this pin
return -1 ;

if (range <= 0)
if (pwmRange <= 0)
return -1 ;

passPin = malloc (sizeof (*passPin)) ;
if (passPin == NULL)
return -1 ;

pinMode (pin, OUTPUT) ;
digitalWrite (pin, LOW) ;
pinMode (pin, OUTPUT) ;

marks [pin] = initialValue ;
range [pin] = pwmRange ;

newPin = pin ;
res = pthread_create (&myThread, NULL, softPwmThread, NULL) ;
*passPin = pin ;
newPin = pin ;
res = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ;

while (newPin != -1)
delay (1) ;
@@ -156,11 +170,14 @@ int softPwmCreate (int pin, int initialValue, int pwmRange)

void softPwmStop (int pin)
{
if (range [pin] != 0)
if (pin < MAX_PINS)
{
pthread_cancel (threads [pin]) ;
pthread_join (threads [pin], NULL) ;
range [pin] = 0 ;
digitalWrite (pin, LOW) ;
if (range [pin] != 0)
{
pthread_cancel (threads [pin]) ;
pthread_join (threads [pin], NULL) ;
range [pin] = 0 ;
digitalWrite (pin, LOW) ;
}
}
}

+ 396
- 237
wiringPi/wiringPi.c
File diff suppressed because it is too large
View File


+ 61
- 31
wiringPi/wiringPi.h View File

@@ -1,7 +1,7 @@
/*
* wiringPi.h:
* Arduino like Wiring library for the Raspberry Pi.
* Copyright (c) 2012-2016 Gordon Henderson
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,12 +26,22 @@

// C doesn't have true/false by default and I can never remember which
// way round they are, so ...
// (and yes, I know about stdbool.h but I like capitals for these and I'm old)

#ifndef TRUE
# define TRUE (1==1)
# define FALSE (!TRUE)
#endif

// GCC warning suppressor

#define UNU __attribute__((unused))

// Mask for the bottom 64 pins which belong to the Raspberry Pi
// The others are available for the other devices

#define PI_GPIO_MASK (0xFFFFFFC0)

// Handy defines

// wiringPi modes
@@ -77,16 +87,19 @@
// Pi model types and version numbers
// Intended for the GPIO program Use at your own risk.

#define PI_MODEL_A 0
#define PI_MODEL_B 1
#define PI_MODEL_AP 2
#define PI_MODEL_BP 3
#define PI_MODEL_2 4
#define PI_ALPHA 5
#define PI_MODEL_CM 6
#define PI_MODEL_07 7
#define PI_MODEL_3 8
#define PI_MODEL_ZERO 9
#define PI_MODEL_A 0
#define PI_MODEL_B 1
#define PI_MODEL_AP 2
#define PI_MODEL_BP 3
#define PI_MODEL_2 4
#define PI_ALPHA 5
#define PI_MODEL_CM 6
#define PI_MODEL_07 7
#define PI_MODEL_3 8
#define PI_MODEL_ZERO 9
#define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12
#define PI_MODEL_3P 13

#define PI_VERSION_1 0
#define PI_VERSION_1_1 1
@@ -95,7 +108,7 @@

#define PI_MAKER_SONY 0
#define PI_MAKER_EGOMAN 1
#define PI_MAKER_MBEST 2
#define PI_MAKER_EMBEST 2
#define PI_MAKER_UNKNOWN 3

extern const char *piModelNames [16] ;
@@ -108,7 +121,7 @@ extern const int piMemorySize [ 8] ;

// Threads

#define PI_THREAD(X) void *X (void *dummy)
#define PI_THREAD(X) void *X (UNU void *dummy)

// Failure modes

@@ -135,19 +148,30 @@ struct wiringPiNodeStruct
unsigned int data2 ; // ditto
unsigned int data3 ; // ditto

void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ;
void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ;
int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ;
void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ;
void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ;
int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ;
//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ;
void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ;
void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;

struct wiringPiNodeStruct *next ;
} ;

extern struct wiringPiNodeStruct *wiringPiNodes ;

// Export variables for the hardware pointers

extern volatile unsigned int *_wiringPiGpio ;
extern volatile unsigned int *_wiringPiPwm ;
extern volatile unsigned int *_wiringPiClk ;
extern volatile unsigned int *_wiringPiPads ;
extern volatile unsigned int *_wiringPiTimer ;
extern volatile unsigned int *_wiringPiTimerIrqRaw ;


// Function prototypes
// c++ wrappers thanks to a comment by Nick Lott
@@ -168,19 +192,22 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ;
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ;
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;

extern void wiringPiVersion (int *major, int *minor) ;
extern int wiringPiSetup (void) ;
extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
extern int wiringPiSetupPhys (void) ;

extern void pinModeAlt (int pin, int mode) ;
extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ;
extern int digitalRead (int pin) ;
extern void digitalWrite (int pin, int value) ;
extern void pwmWrite (int pin, int value) ;
extern int analogRead (int pin) ;
extern void analogWrite (int pin, int value) ;
extern void pinModeAlt (int pin, int mode) ;
extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ;
extern int digitalRead (int pin) ;
extern void digitalWrite (int pin, int value) ;
extern unsigned int digitalRead8 (int pin) ;
extern void digitalWrite8 (int pin, int value) ;
extern void pwmWrite (int pin, int value) ;
extern int analogRead (int pin) ;
extern void analogWrite (int pin, int value) ;

// PiFace specifics
// (Deprecated)
@@ -190,19 +217,22 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio

// On-Board Raspberry Pi hardware specific stuff

extern int piBoardRev (void) ;
extern int piGpioLayout (void) ;
extern int piBoardRev (void) ; // Deprecated
extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ;
extern int wpiPinToGpio (int wpiPin) ;
extern int physPinToGpio (int physPin) ;
extern void setPadDrive (int group, int value) ;
extern int getAlt (int pin) ;
extern void pwmToneWrite (int pin, int freq) ;
extern void digitalWriteByte (int value) ;
extern unsigned int digitalReadByte (void) ;
extern void pwmSetMode (int mode) ;
extern void pwmSetRange (unsigned int range) ;
extern void pwmSetClock (int divisor) ;
extern void gpioClockSet (int pin, int freq) ;
extern unsigned int digitalReadByte (void) ;
extern unsigned int digitalReadByte2 (void) ;
extern void digitalWriteByte (int value) ;
extern void digitalWriteByte2 (int value) ;

// Interrupts
// (Also Pi hardware specific)


+ 2
- 1
wiringPi/wiringPiI2C.c View File

@@ -52,6 +52,7 @@
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>

#include "wiringPi.h"
#include "wiringPiI2C.h"
@@ -221,7 +222,7 @@ int wiringPiI2CSetup (const int devId)
int rev ;
const char *device ;

rev = piBoardRev () ;
rev = piGpioLayout () ;

if (rev == 1)
device = "/dev/i2c-0" ;


+ 5
- 4
wiringPi/wiringPiSPI.c View File

@@ -28,6 +28,7 @@
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>
#include <linux/spi/spidev.h>

#include "wiringPi.h"
@@ -38,10 +39,10 @@
// The SPI bus parameters
// Variables as they need to be passed as pointers later on

const static char *spiDev0 = "/dev/spidev0.0" ;
const static char *spiDev1 = "/dev/spidev0.1" ;
const static uint8_t spiBPW = 8 ;
const static uint16_t spiDelay = 0 ;
static const char *spiDev0 = "/dev/spidev0.0" ;
static const char *spiDev1 = "/dev/spidev0.1" ;
static const uint8_t spiBPW = 8 ;
static const uint16_t spiDelay = 0 ;

static uint32_t spiSpeeds [2] ;
static int spiFds [2] ;


+ 31
- 19
wiringPi/wiringSerial.c View File

@@ -49,24 +49,36 @@ int serialOpen (const char *device, const int baud)

switch (baud)
{
case 50: myBaud = B50 ; break ;
case 75: myBaud = B75 ; break ;
case 110: myBaud = B110 ; break ;
case 134: myBaud = B134 ; break ;
case 150: myBaud = B150 ; break ;
case 200: myBaud = B200 ; break ;
case 300: myBaud = B300 ; break ;
case 600: myBaud = B600 ; break ;
case 1200: myBaud = B1200 ; break ;
case 1800: myBaud = B1800 ; break ;
case 2400: myBaud = B2400 ; break ;
case 4800: myBaud = B4800 ; break ;
case 9600: myBaud = B9600 ; break ;
case 19200: myBaud = B19200 ; break ;
case 38400: myBaud = B38400 ; break ;
case 57600: myBaud = B57600 ; break ;
case 115200: myBaud = B115200 ; break ;
case 230400: myBaud = B230400 ; break ;
case 50: myBaud = B50 ; break ;
case 75: myBaud = B75 ; break ;
case 110: myBaud = B110 ; break ;
case 134: myBaud = B134 ; break ;
case 150: myBaud = B150 ; break ;
case 200: myBaud = B200 ; break ;
case 300: myBaud = B300 ; break ;
case 600: myBaud = B600 ; break ;
case 1200: myBaud = B1200 ; break ;
case 1800: myBaud = B1800 ; break ;
case 2400: myBaud = B2400 ; break ;
case 4800: myBaud = B4800 ; break ;
case 9600: myBaud = B9600 ; break ;
case 19200: myBaud = B19200 ; break ;
case 38400: myBaud = B38400 ; break ;
case 57600: myBaud = B57600 ; break ;
case 115200: myBaud = B115200 ; break ;
case 230400: myBaud = B230400 ; break ;
case 460800: myBaud = B460800 ; break ;
case 500000: myBaud = B500000 ; break ;
case 576000: myBaud = B576000 ; break ;
case 921600: myBaud = B921600 ; break ;
case 1000000: myBaud = B1000000 ; break ;
case 1152000: myBaud = B1152000 ; break ;
case 1500000: myBaud = B1500000 ; break ;
case 2000000: myBaud = B2000000 ; break ;
case 2500000: myBaud = B2500000 ; break ;
case 3000000: myBaud = B3000000 ; break ;
case 3500000: myBaud = B3500000 ; break ;
case 4000000: myBaud = B4000000 ; break ;

default:
return -2 ;
@@ -96,7 +108,7 @@ int serialOpen (const char *device, const int baud)
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)

tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;
tcsetattr (fd, TCSANOW, &options) ;

ioctl (fd, TIOCMGET, &status);



+ 177
- 9
wiringPi/wpiExtensions.c View File

@@ -55,6 +55,13 @@
#include "ads1115.h"
#include "sn3218.h"
#include "drcSerial.h"
#include "drcNet.h"
#include "../wiringPiD/drcNetCmd.h"
#include "pseudoPins.h"
#include "bmp180.h"
#include "htu21d.h"
#include "ds18b20.h"
#include "rht03.h"

#include "wpiExtensions.h"

@@ -130,12 +137,16 @@ static char *extractInt (char *progName, char *p, int *num)
/*
* extractStr:
* Check & return a string at the given location (prefixed by a :)
* Note: The string can be enclosed in []'s to escape colons. This is
* so we can handle IPv6 addresses which contain colons and the []'s is
* a common way to prepresent them.
*********************************************************************************
*/

static char *extractStr (char *progName, char *p, char **str)
{
char *q, *r ;
int quoted = FALSE ;

if (*p != ':')
{
@@ -145,21 +156,38 @@ static char *extractStr (char *progName, char *p, char **str)

++p ;

if (!isprint (*p))
if (*p == '[')
{
quoted = TRUE ;
++p ;
}

if (!isprint (*p)) // Is this needed?
{
verbError ("%s: character expected", progName) ;
return NULL ;
}

q = p ;
while ((*q != 0) && (*q != ':'))
++q ;
if (quoted)
{
while ((*q != 0) && (*q != ']'))
++q ;
}
else
{
while ((*q != 0) && (*q != ':'))
++q ;
}

*str = r = calloc (q - p + 2, 1) ; // Zeros it

while (p != q)
*r++ = *p++ ;

if (quoted) // Skip over the ] to the :
++p ;

return p ;
}

@@ -429,6 +457,87 @@ static int doExtensionPcf8591 (char *progName, int pinBase, char *params)


/*
* doExtensionPseudoPins:
* 64 Memory resident pseudo pins
* pseudoPins:base
*********************************************************************************
*/

static int doExtensionPseudoPins (UNU char *progName, int pinBase, UNU char *params)
{
pseudoPinsSetup (pinBase) ;

return TRUE ;
}


/*
* doExtensionBmp180:
* Analog Temp + Pressure
* bmp180:base
*********************************************************************************
*/

static int doExtensionBmp180 (UNU char *progName, int pinBase, UNU char *params)
{
bmp180Setup (pinBase) ;

return TRUE ;
}


/*
* doExtensionHtu21d:
* Analog humidity + Pressure
* htu21d:base
*********************************************************************************
*/

static int doExtensionHtu21d (UNU char *progName, int pinBase, UNU char *params)
{
htu21dSetup (pinBase) ;

return TRUE ;
}


/*
* doExtensionDs18b20:
* 1-Wire Temperature
* htu21d:base:serialNum
*********************************************************************************
*/

static int doExtensionDs18b20 (char *progName, int pinBase, char *params)
{
char *serialNum ;

if ((params = extractStr (progName, params, &serialNum)) == NULL)
return FALSE ;

return ds18b20Setup (pinBase, serialNum) ;
}


/*
* doExtensionRht03:
* Maxdetect 1-Wire Temperature & Humidity
* rht03:base:piPin
*********************************************************************************
*/

static int doExtensionRht03 (char *progName, int pinBase, char *params)
{
int piPin ;

if ((params = extractInt (progName, params, &piPin)) == NULL)
return FALSE ;

return rht03Setup (pinBase, piPin) ;
}


/*
* doExtensionMax31855:
* Analog IO
* max31855:base:spiChan
@@ -565,7 +674,7 @@ static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
*********************************************************************************
*/

static int doExtensionSn3218 (char *progName, int pinBase, char *params)
static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params)
{
sn3218Setup (pinBase) ;
return TRUE ;
@@ -631,9 +740,9 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
if ((params = extractInt (progName, params, &pins)) == NULL)
return FALSE ;

if ((pins < 1) || (pins > 100))
if ((pins < 1) || (pins > 1000))
{
verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ;
verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
return FALSE ;
}
@@ -661,6 +770,59 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
}


/*
* doExtensionDrcNet:
* Interface to a DRC Network system
* drcn:base:pins:ipAddress:port:password
*********************************************************************************
*/

static int doExtensionDrcNet (char *progName, int pinBase, char *params)
{
int pins ;
char *ipAddress, *port, *password ;
char pPort [1024] ;

if ((params = extractInt (progName, params, &pins)) == NULL)
return FALSE ;

if ((pins < 1) || (pins > 1000))
{
verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
return FALSE ;
}
if ((params = extractStr (progName, params, &ipAddress)) == NULL)
return FALSE ;

if (strlen (ipAddress) == 0)
{
verbError ("%s: ipAddress required", progName) ;
return FALSE ;
}

if ((params = extractStr (progName, params, &port)) == NULL)
return FALSE ;

if (strlen (port) == 0)
{
sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ;
port = pPort ;
}

if ((params = extractStr (progName, params, &password)) == NULL)
return FALSE ;

if (strlen (password) == 0)
{
verbError ("%s: password required", progName) ;
return FALSE ;
}

return drcSetupNet (pinBase, pins, ipAddress, port, password) ;
}



/*
* Function list
@@ -677,6 +839,11 @@ static struct extensionFunctionStruct extensionFunctions [] =
{ "sr595", &doExtensionSr595 },
{ "pcf8574", &doExtensionPcf8574 },
{ "pcf8591", &doExtensionPcf8591 },
{ "bmp180", &doExtensionBmp180 },
{ "pseudoPins", &doExtensionPseudoPins },
{ "htu21d", &doExtensionHtu21d },
{ "ds18b20", &doExtensionDs18b20 },
{ "rht03", &doExtensionRht03 },
{ "mcp3002", &doExtensionMcp3002 },
{ "mcp3004", &doExtensionMcp3004 },
{ "mcp4802", &doExtensionMcp4802 },
@@ -686,6 +853,7 @@ static struct extensionFunctionStruct extensionFunctions [] =
{ "max5322", &doExtensionMax5322 },
{ "sn3218", &doExtensionSn3218 },
{ "drcs", &doExtensionDrcS },
{ "drcn", &doExtensionDrcNet },
{ NULL, NULL },
} ;

@@ -703,7 +871,7 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors)
char *p ;
char *extension = extensionData ;
struct extensionFunctionStruct *extensionFn ;
unsigned pinBase = 0 ;
int pinBase = 0 ;

verbose = printErrors ;

@@ -755,6 +923,6 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors)
return extensionFn->function (progName, pinBase, p) ;
}

verbError ("%s: extension %s not found", progName, extension) ;
fprintf (stderr, "%s: extension %s not found", progName, extension) ;
return FALSE ;
}

+ 100
- 0
wiringPiD/Makefile View File

@@ -0,0 +1,100 @@
#
# Makefile:
# The wiringPiD utility:
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012-2017 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# A "wiring" library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################

DESTDIR?=/usr
PREFIX?=/local

ifneq ($V,1)
Q ?= @
endif

#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I$(DESTDIR)$(PREFIX)/include
CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe

LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib
LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt

# May not need to alter anything below this line
###############################################################################

SRC = wiringpid.c network.c runRemote.c daemonise.c

OBJ = $(SRC:.c=.o)

all: wiringpid

wiringpid: $(OBJ)
$Q echo [Link]
$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)

.c.o:
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@

.PHONY: clean
clean:
$Q echo "[Clean]"
$Q rm -f $(OBJ) wiringpid *~ core tags *.bak

.PHONY: tags
tags: $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)

.PHONY: install
install: wiringpid
$Q echo "[Install]"
$Q mkdir -p $(DESTDIR)$(PREFIX)/sbin
$Q cp wiringpid $(DESTDIR)$(PREFIX)/sbin
$Q chown root.root $(DESTDIR)$(PREFIX)/sbin/wiringpid

# $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man8
# $Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man8

.PHONY: install-deb
install-deb: gpio
$Q echo "[Install: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/man/man1
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/man/man1

.PHONY: uninstall
uninstall:
$Q echo "[UnInstall]"
$Q rm -f $(DESTDIR)$(PREFIX)/sbin/wiringpid
$Q rm -f $(DESTDIR)$(PREFIX)/man/man8/wiringpid.8

.PHONY: depend
depend:
makedepend -Y $(SRC)
# DO NOT DELETE

wiringpid.o: drcNetCmd.h network.h runRemote.h daemonise.h
network.o: network.h
runRemote.o: drcNetCmd.h network.h runRemote.h
daemonise.o: daemonise.h

+ 82
- 0
wiringPiD/daemonise.c View File

@@ -0,0 +1,82 @@
/*
* daemonise.c:
* Fairly generic "Turn the current process into a daemon" code.
*
* Copyright (c) 2016-2017 Gordon Henderson.
*********************************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <sys/stat.h>

#include "daemonise.h"

void daemonise (const char *pidFile)
{
pid_t pid ;
int i ;
FILE *fd ;

syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ;

// Fork from the parent

if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ;
exit (EXIT_FAILURE) ;
}

if (pid > 0) // Parent - terminate
exit (EXIT_SUCCESS) ;

// Now running on the child - become session leader

if (setsid() < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ;
exit (EXIT_FAILURE) ;
}

// Ignore a few signals

signal (SIGCHLD, SIG_IGN) ;
signal (SIGHUP, SIG_IGN) ;

// Fork again

if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ;
exit (EXIT_FAILURE) ;
}

if (pid > 0) // parent - terminate
exit (EXIT_SUCCESS) ;

// Tidying up - reset umask, change to / and close all files

umask (0) ;
chdir ("/") ;

for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i)
close (i) ;

// Write PID into /var/run

if (pidFile != NULL)
{
if ((fd = fopen (pidFile, "w")) == NULL)
{
syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ;
exit (EXIT_FAILURE) ;
}

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

+ 9
- 0
wiringPiD/daemonise.h View File

@@ -0,0 +1,9 @@
/*
* daemonise.h:
* Fairly generic "Turn the current process into a daemon" code.
*
* Copyright (c) 2016-2017 Gordon Henderson.
*********************************************************************************
*/

extern void daemonise (const char *pidFile) ;

+ 44
- 0
wiringPiD/drcNetCmd.h View File

@@ -0,0 +1,44 @@
/*
* drcNetCmd.c:
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#define DEFAULT_SERVER_PORT 6124

#define DRCN_PIN_MODE 1
#define DRCN_PULL_UP_DN 2

#define DRCN_DIGITAL_WRITE 3
#define DRCN_DIGITAL_WRITE8 4
#define DRCN_ANALOG_WRITE 5
#define DRCN_PWM_WRITE 6

#define DRCN_DIGITAL_READ 7
#define DRCN_DIGITAL_READ8 8
#define DRCN_ANALOG_READ 9


struct drcNetComStruct
{
uint32_t pin ;
uint32_t cmd ;
uint32_t data ;
} comDat ;


+ 330
- 0
wiringPiD/network.c View File

@@ -0,0 +1,330 @@
/*
* network.c:
* Part of wiringPiD
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <malloc.h>

#include <fcntl.h>
#include <crypt.h>

#include "network.h"

#define TRUE (1==1)
#define FALSE (!TRUE)

// Local data

#define SALT_LEN 16

static char salt [SALT_LEN + 1] ;
static char *returnedHash = NULL ;
static int serverFd = -1 ;

// Union for the server Socket Address

static union
{
struct sockaddr_in sin ;
struct sockaddr_in6 sin6 ;
} serverSockAddr ;

// and client address

static union
{
struct sockaddr_in sin ;
struct sockaddr_in6 sin6 ;
} clientSockAddr ;


/*
* getClientIP:
* Returns a pointer to a static string containing the clients IP address
*********************************************************************************
*/

char *getClientIP (void)
{
char buf [INET6_ADDRSTRLEN] ;
static char ipAddress [1024] ;

if (clientSockAddr.sin.sin_family == AF_INET) // IPv4
{
if (snprintf (ipAddress, 1024, "IPv4: %s",
inet_ntop (clientSockAddr.sin.sin_family, (void *)&clientSockAddr.sin.sin_addr, buf, sizeof (buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
else // IPv6
{
if (clientSockAddr.sin.sin_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&clientSockAddr.sin6.sin6_addr))
{
if (snprintf (ipAddress, 1024, "IPv4in6: %s",
inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
else
{
if (snprintf (ipAddress, 1024, "IPv6: %s",
inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
strcpy (ipAddress, "Too long") ;
}
}

return ipAddress ;
}



/*
* clientPstr: clientPrintf:
* Print over a network socket
*********************************************************************************
*/

static int clientPstr (int fd, char *s)
{
int len = strlen (s) ;
return (write (fd, s, len) == len) ? 0 : -1 ;
}

static int clientPrintf (const int fd, const char *message, ...)
{
va_list argp ;
char buffer [1024] ;

va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;

return clientPstr (fd, buffer) ;
}


/*
* sendGreeting:
* Send some text to the client device
*********************************************************************************
*/

int sendGreeting (int clientFd)
{
if (clientPrintf (clientFd, "200 Welcome to wiringPiD - http://wiringpi.com/\n") < 0)
return -1 ;

return clientPrintf (clientFd, "200 Connecting from: %s\n", getClientIP ()) ;
}


/*
* getSalt:
* Create a random 'salt' value for the password encryption process
*********************************************************************************
*/

static int getSalt (char drySalt [])
{
static const char *seaDog = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789/." ;

unsigned char wetSalt [SALT_LEN] ;
int i, fd ;

if ((fd = open ("/dev/urandom", O_RDONLY)) < 0)
return fd ;

if (read (fd, wetSalt, SALT_LEN) != SALT_LEN)
return -1 ;

close (fd) ;

for (i = 0 ; i < SALT_LEN ; ++i)
drySalt [i] = seaDog [wetSalt [i] & 63] ;
drySalt [SALT_LEN] = 0 ;

return 0 ;
}


/*
* sendChallenge:
* Create and send our salt (aka nonce) to the remote device
*********************************************************************************
*/

int sendChallenge (int clientFd)
{
if (getSalt (salt) < 0)
return -1 ;

return clientPrintf (clientFd, "Challenge %s\n", salt) ;
}


/*
* getResponse:
* Read the encrypted password from the remote device.
*********************************************************************************
*/


int getResponse (int clientFd)
{
char reply [1024] ;
int len ;

// Being sort of lazy about this. I'm expecting an SHA-512 hash back and these
// are exactly 86 characters long, so no reason not to, I guess...

len = 86 ;

if (setsockopt (clientFd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return -1 ;

len = recv (clientFd, reply, 86, 0) ;
if (len != 86)
return -1 ;

reply [len] = 0 ;

if ((returnedHash = malloc (len + 1)) == NULL)
return -1 ;

strcpy (returnedHash, reply) ;

return 0 ;
}


/*
* passwordMatch:
* See if there's a match. If not, we simply dump them.
*********************************************************************************
*/

int passwordMatch (const char *password)
{
char *encrypted ;
char salted [1024] ;

sprintf (salted, "$6$%s$", salt) ;

encrypted = crypt (password, salted) ;

// 20: $6$ then 16 characters of salt, then $
// 86 is the length of an SHA-512 hash

return strncmp (encrypted + 20, returnedHash, 86) == 0 ;
}


/*
* setupServer:
* Do what's needed to create a local server socket instance that can listen
* on both IPv4 and IPv6 interfaces.
*********************************************************************************
*/

int setupServer (int serverPort)
{
socklen_t clientSockAddrSize = sizeof (clientSockAddr) ;

int on = 1 ;
int family ;
socklen_t serverSockAddrSize ;
int clientFd ;

// Try to create an IPv6 socket

serverFd = socket (PF_INET6, SOCK_STREAM, 0) ;

// If it didn't work, then fall-back to IPv4.

if (serverFd < 0)
{
if ((serverFd = socket (PF_INET, SOCK_STREAM, 0)) < 0)
return -1 ;

family = AF_INET ;
serverSockAddrSize = sizeof (struct sockaddr_in) ;
}
else // We got an IPv6 socket
{
family = AF_INET6 ;
serverSockAddrSize = sizeof (struct sockaddr_in6) ;
}

if (setsockopt (serverFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
return -1 ;

// Setup the servers socket address - cope with IPv4 and v6.

memset (&serverSockAddr, 0, sizeof (serverSockAddr)) ;
switch (family)
{
case AF_INET:
serverSockAddr.sin.sin_family = AF_INET ;
serverSockAddr.sin.sin_addr.s_addr = htonl (INADDR_ANY) ;
serverSockAddr.sin.sin_port = htons (serverPort) ;
break;

case AF_INET6:
serverSockAddr.sin6.sin6_family = AF_INET6 ;
serverSockAddr.sin6.sin6_addr = in6addr_any ;
serverSockAddr.sin6.sin6_port = htons (serverPort) ;
}

// Bind, listen and accept

if (bind (serverFd, (struct sockaddr *)&serverSockAddr, serverSockAddrSize) < 0)
return -1 ;

if (listen (serverFd, 4) < 0) // Really only going to talk to one client at a time...
return -1 ;

if ((clientFd = accept (serverFd, (struct sockaddr *)&clientSockAddr, &clientSockAddrSize)) < 0)
return -1 ;

return clientFd ;
}


/*
* closeServer:
*********************************************************************************
*/

void closeServer (int clientFd)
{
if (serverFd != -1) close (serverFd) ;
if (clientFd != -1) close (clientFd) ;
serverFd = clientFd = -1 ;
}

+ 31
- 0
wiringPiD/network.h View File

@@ -0,0 +1,31 @@
/*
* network.h:
* Part of wiringPiD
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

extern char *getClientIP (void) ;
extern int getResponce (int clientFd) ;
extern int setupServer (int serverPort) ;
extern int sendGreeting (int clientFd) ;
extern int sendChallenge (int clientFd) ;
extern int getResponse (int clientFd) ;
extern int passwordMatch (const char *password) ;
extern void closeServer (int clientFd) ;

+ 126
- 0
wiringPiD/runRemote.c View File

@@ -0,0 +1,126 @@
/*
* runRemote.c:
* Run the remote commands passed over the network link.
*
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
//#include <stdarg.h>

#include <wiringPi.h>
#include <wpiExtensions.h>

#include "drcNetCmd.h"
#include "network.h"
#include "runRemote.h"



int noLocalPins = FALSE ;


void runRemoteCommands (int fd)
{
register uint32_t pin ;
int len ;
struct drcNetComStruct cmd ;

len = sizeof (struct drcNetComStruct) ;

if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
return ;

for (;;)
{
if (recv (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) // Probably remote hangup
return ;

pin = cmd.pin ;
if (noLocalPins && ((pin & PI_GPIO_MASK) == 0))
{
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
continue ;
}

switch (cmd.cmd)
{
case DRCN_PIN_MODE:
pinMode (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_PULL_UP_DN:
pullUpDnControl (pin, cmd.data) ;
break ;

case DRCN_PWM_WRITE:
pwmWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_DIGITAL_WRITE:
digitalWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_DIGITAL_WRITE8:
//digitalWrite8 (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_DIGITAL_READ:
cmd.data = digitalRead (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_DIGITAL_READ8:
//cmd.data = digitalRead8 (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_ANALOG_WRITE:
analogWrite (pin, cmd.data) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;

case DRCN_ANALOG_READ:
cmd.data = analogRead (pin) ;
if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
return ;
break ;
}
}

}

gpio/pins.c → wiringPiD/runRemote.h View File

@@ -1,7 +1,8 @@
/*
* pins.c:
* Just display a handy Pi pinnout diagram.
* Copyright (c) 2012-2015 Gordon Henderson
* runRemote.h:
* Run the remote commands passed over the network link.
*
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -21,13 +22,8 @@
***********************************************************************
*/

// Globals

#include <stdio.h>

void doPins (void)
{
printf ("The pins command has been deprecated - sorry. Please use the\n") ;
printf (" gpio readall\n") ;
printf ("command to get a list of the pinnouts for your Pi.\n") ;
}
extern int noLocalPins ;

extern void runRemoteCommands (int fd) ;

+ 382
- 0
wiringPiD/wiringpid.c View File

@@ -0,0 +1,382 @@
/*
* wiringPiD.c:
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>

#include <wiringPi.h>
#include <wpiExtensions.h>

#include "drcNetCmd.h"
#include "network.h"
#include "runRemote.h"
#include "daemonise.h"


#define PIDFILE "/var/run/wiringPiD.pid"


// Globals

static const char *usage = "[-h] [-d] [-g | -1 | -z] [[-x extension:pin:params] ...] password" ;
static int doDaemon = FALSE ;

//

static void logMsg (const char *message, ...)
{
va_list argp ;
char buffer [1024] ;

va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;

if (doDaemon)
syslog (LOG_DAEMON | LOG_INFO, "%s", buffer) ;
else
printf ("%s\n", buffer) ;
}


/*
* sigHandler:
* setupSigHandler:
* Somehing has happened that would normally terminate the program so try
* to close down nicely.
*********************************************************************************
*/

void sigHandler (int sig)
{
logMsg ("Exiting on signal %d: %s", sig, strsignal (sig)) ;
(void)unlink (PIDFILE) ;
exit (EXIT_FAILURE) ;
}

void setupSigHandler (void)
{
struct sigaction action ;

sigemptyset (&action.sa_mask) ;
action.sa_flags = 0 ;

// Ignore what we can

action.sa_handler = SIG_IGN ;

sigaction (SIGHUP, &action, NULL) ;
sigaction (SIGTTIN, &action, NULL) ;
sigaction (SIGTTOU, &action, NULL) ;

// Trap what we can to exit gracefully

action.sa_handler = sigHandler ;

sigaction (SIGINT, &action, NULL) ;
sigaction (SIGQUIT, &action, NULL) ;
sigaction (SIGILL, &action, NULL) ;
sigaction (SIGABRT, &action, NULL) ;
sigaction (SIGFPE, &action, NULL) ;
sigaction (SIGSEGV, &action, NULL) ;
sigaction (SIGPIPE, &action, NULL) ;
sigaction (SIGALRM, &action, NULL) ;
sigaction (SIGTERM, &action, NULL) ;
sigaction (SIGUSR1, &action, NULL) ;
sigaction (SIGUSR2, &action, NULL) ;
sigaction (SIGCHLD, &action, NULL) ;
sigaction (SIGTSTP, &action, NULL) ;
sigaction (SIGBUS, &action, NULL) ;
}


/*
* The works...
*********************************************************************************
*/

int main (int argc, char *argv [])
{
int clientFd ;
char *p, *password ;
int i ;
int port = DEFAULT_SERVER_PORT ;
int wpiSetup = 0 ;

if (argc < 2)
{
fprintf (stderr, "Usage: %s %s\n", argv [0], usage) ;
exit (EXIT_FAILURE) ;
}

// Help?

if (strcasecmp (argv [1], "-h") == 0)
{
printf ("Usage: %s %s\n", argv [0], usage) ;
return 0 ;
}

// Daemonize?
// Must come before the other args as e.g. some extensions
// open files which get closed on daemonise...

if (strcasecmp (argv [1], "-d") == 0)
{
if (geteuid () != 0)
{
fprintf (stderr, "%s: Must be root to run as a daemon.\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}

doDaemon = TRUE ;
daemonise (PIDFILE) ;

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
}

// Scan all other arguments

while (*argv [1] == '-')
{

// Look for wiringPi setup arguments:
// Same as the gpio command and rtb.

// -g - bcm_gpio

if (strcasecmp (argv [1], "-g") == 0)
{
if (wpiSetup == 0)
{
logMsg ("BCM_GPIO mode selected") ;
wiringPiSetupGpio () ;
}

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
++wpiSetup ;
continue ;
}

// -1 - physical pins

if (strcasecmp (argv [1], "-1") == 0)
{
if (wpiSetup == 0)
{
logMsg ("GPIO-PHYS mode selected") ;
wiringPiSetupPhys () ;
}

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
++wpiSetup ;
continue ;
}

// -z - no wiringPi - blocks remotes accessing local pins

if (strcasecmp (argv [1], "-z") == 0)
{
if (wpiSetup == 0)
logMsg ("No GPIO mode selected") ;

for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
noLocalPins = TRUE ;
++wpiSetup ;
continue ;
}

// -p to select the port

if (strcasecmp (argv [1], "-p") == 0)
{
if (argc < 3)
{
logMsg ("-p missing extension port") ;
exit (EXIT_FAILURE) ;
}

logMsg ("Setting port to: %s", argv [2]) ;

port = atoi (argv [2]) ;
if ((port < 1) || (port > 65535))
{
logMsg ("Invalid server port: %d", port) ;
exit (EXIT_FAILURE) ;
}

// Shift args down by 2

for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
argc -= 2 ;

continue ;
}

// Check for -x argument to load in a new extension
// -x extension:base:args
// Can load many modules to extend the daemon.

if (strcasecmp (argv [1], "-x") == 0)
{
if (argc < 3)
{
logMsg ("-x missing extension name:data:etc.") ;
exit (EXIT_FAILURE) ;
}

logMsg ("Loading extension: %s", argv [2]) ;

if (!loadWPiExtension (argv [0], argv [2], TRUE))
{
logMsg ("Extension load failed: %s", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}

// Shift args down by 2

for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
argc -= 2 ;

continue ;
}

logMsg ("Invalid parameter: %s", argv [1]) ;
exit (EXIT_FAILURE) ;
}

// Default to wiringPi mode

if (wpiSetup == 0)
{
logMsg ("WiringPi GPIO mode selected") ;
wiringPiSetup () ;
}

// Finally, should just be one arg left - the password...

if (argc != 2)
{
logMsg ("No password supplied") ;
exit (EXIT_FAILURE) ;
}

if (strlen (argv [1]) < 6)
{
logMsg ("Password too short - at least 6 chars, not %d", strlen (argv [1])) ;
exit (EXIT_FAILURE) ;
}

if ((password = malloc (strlen (argv [1]) + 1)) == NULL)
{
logMsg ("Out of memory") ;
exit (EXIT_FAILURE) ;
}
strcpy (password, argv [1]) ;

// Wipe out the password on the command-line in a vague attempt to try to
// hide it from snoopers

for (p = argv [1] ; *p ; ++p)
*p = ' ' ;

setupSigHandler () ;
// Enter our big loop

for (;;)
{

if (!doDaemon)
printf ("-=-\nWaiting for a new connection...\n") ;

if ((clientFd = setupServer (port)) < 0)
{
logMsg ("Unable to setup server: %s", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}

logMsg ("New connection from: %s.", getClientIP ()) ;

if (!doDaemon)
printf ("Sending Greeting.\n") ;

if (sendGreeting (clientFd) < 0)
{
logMsg ("Unable to send greeting message: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}

if (!doDaemon)
printf ("Sending Challenge.\n") ;

if (sendChallenge (clientFd) < 0)
{
logMsg ("Unable to send challenge message: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}

if (!doDaemon)
printf ("Waiting for response.\n") ;

if (getResponse (clientFd) < 0)
{
logMsg ("Connection closed waiting for response: %s", strerror (errno)) ;
closeServer (clientFd) ;
continue ;
}

if (!passwordMatch (password))
{
logMsg ("Password failure") ;
closeServer (clientFd) ;
continue ;
}

logMsg ("Password OK - Starting") ;

runRemoteCommands (clientFd) ;
closeServer (clientFd) ;
}

return 0 ;
}

Loading…
Cancel
Save