first commit
This commit is contained in:
165
wiringPi/COPYING.LESSER
Normal file
165
wiringPi/COPYING.LESSER
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
244
wiringPi/Makefile
Normal file
244
wiringPi/Makefile
Normal file
@@ -0,0 +1,244 @@
|
||||
#
|
||||
# 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 -Wextra -Winline $(INCLUDE) -pipe -fPIC
|
||||
#CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Wconversion -Winline $(INCLUDE) -pipe -fPIC
|
||||
|
||||
LIBS = -lm -lpthread -lrt -lcrypt
|
||||
|
||||
ifeq ($(BOARD),)
|
||||
BOARD = orangepioneplus-h6
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepi2giot)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_2G_IOT
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepipc2-h5)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PC2
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepiprime-h5)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PRIME
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepizeroplus-h5)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(BOARD), "orangepiwin-a64" "orangepiwinplus-a64"),)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_WIN
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(BOARD), "orangepione-h3" "orangepilite-h3" "orangepipc-h3" "orangepiplus-h3" "orangepipcplus-h3" "orangepiplus2e-h3"),)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_H3
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(BOARD), "orangepizero-h2" "orangepir1-h2"),)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(BOARD), "orangepioneplus-h6" "orangepilite2-h6"),)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_LITE2
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepi3-h6)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_3
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepizero2-h616)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO2
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepizeroplus2h3)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H3
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepizeroplus2h5)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H5
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepirk3399)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_RK3399
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepi4)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepi4-lts)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4_LTS
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepi800)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_800
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), orangepir1plus-rk3328)
|
||||
EXTRA_CFLAGS = -DCONFIG_ORANGEPI_R1PLUS
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_ORANGEPI
|
||||
|
||||
###############################################################################
|
||||
|
||||
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 \
|
||||
w25q64.c \
|
||||
oled.c OrangePi.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) $(OBJ) $(LIBS)
|
||||
|
||||
.c.o:
|
||||
$Q echo [Compile] $<
|
||||
$Q $(CC) -c $(EXTRA_CFLAGS) $(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 $(CURDIR)/../debian-template/wiringPi/usr/include
|
||||
$Q install -m 0644 $(HEADERS) $(CURDIR)/../debian-template/wiringPi/usr/include
|
||||
$Q echo "[Install Dynamic Lib: deb]"
|
||||
install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/lib
|
||||
install -m 0755 libwiringPi.so.$(VERSION) $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION)
|
||||
ln -sf $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) $(CURDIR)/../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
|
||||
w25q64.o: wiringPi.h wiringPiSPI.h w25q64.h
|
||||
oled.o: wiringPi.h wiringPiSPI.h oled.h font.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
|
||||
2733
wiringPi/OrangePi.c
Normal file
2733
wiringPi/OrangePi.c
Normal file
File diff suppressed because it is too large
Load Diff
286
wiringPi/OrangePi.h
Normal file
286
wiringPi/OrangePi.h
Normal file
@@ -0,0 +1,286 @@
|
||||
#ifndef _ORANGEPI_H
|
||||
#define _ORANGEPI_H
|
||||
|
||||
#ifdef CONFIG_ORANGEPI_2G_IOT
|
||||
/********** OrangePi 2G-IOT *************/
|
||||
/*
|
||||
* GPIOA_BASE 0x20930000
|
||||
* GPIOB_BASE 0x20931000
|
||||
* GPIOC_BASE 0x11A08000
|
||||
* GPIOD_BASE 0x20932000
|
||||
*/
|
||||
|
||||
/********* local data ************/
|
||||
#define GPIOA_BASE 0x20930000
|
||||
#define GPIOB_BASE 0x20931000
|
||||
#define GPIOC_BASE 0x11A08000
|
||||
#define GPIOD_BASE 0x20932000
|
||||
#define GPIO_NUM (0x80)
|
||||
#define GPIO_BIT(x) (1UL << (x))
|
||||
|
||||
#define OEN_VAL_REGISTER (0x00)
|
||||
#define OEN_SET_OUT_REGISTER (0x04)
|
||||
#define SET_IN_REGISTER (0x08)
|
||||
#define VAL_REGISTER (0x0C)
|
||||
#define SET_REGISTER (0x10)
|
||||
#define CLR_REGISTER (0x14)
|
||||
|
||||
#define MEM_INFO (512)
|
||||
#define MAP_SIZE_L (4 * 4096)
|
||||
|
||||
#endif /* CONFIG_ORANGEPI_2G_IOT */
|
||||
|
||||
#if CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_PRIME
|
||||
/************** OrangePi H5 ***********************/
|
||||
#define GPIOA_BASE (0x01C20000)
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BASE_MAP (0x01C20800)
|
||||
#define MEM_INFO (1024)
|
||||
#define GPIOL_BASE (0x01F02c00)
|
||||
#define GPIOL_BASE_MAP (0x01F02000)
|
||||
#define MAP_SIZE_L (4096 * 2)
|
||||
#define GPIO_PWM_OP (0x01C21000)
|
||||
#endif
|
||||
|
||||
/************** OrangePi A64 ***********************/
|
||||
#ifdef CONFIG_ORANGEPI_WIN
|
||||
#define GPIOA_BASE (0x01C20000)
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BASE_MAP (0x01C20800)
|
||||
#define MEM_INFO (1024)
|
||||
#define GPIOL_BASE (0x01F02c00)
|
||||
#define GPIOL_BASE_MAP (0x01F02000)
|
||||
#define MAP_SIZE_L (4096 * 2)
|
||||
#define GPIO_PWM_OP (0x01C21000)
|
||||
#endif
|
||||
|
||||
/************** OrangePi H3 ***********************/
|
||||
#if CONFIG_ORANGEPI_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZERO
|
||||
#define GPIOA_BASE (0x01C20000)
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BASE_MAP (0x01C20800)
|
||||
#define MEM_INFO (1024)
|
||||
#define GPIOL_BASE (0x01F02c00)
|
||||
#define GPIOL_BASE_MAP (0x01F02000)
|
||||
#define MAP_SIZE_L (4096 * 2)
|
||||
#define GPIO_PWM_OP (0x01C21000)
|
||||
#endif
|
||||
|
||||
/*********** OrangePi LITE2/OnePlus/PC3 *************/
|
||||
#if CONFIG_ORANGEPI_LITE2 || CONFIG_ORANGEPI_3
|
||||
#define GPIOA_BASE (0x0300B000)
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BASE_MAP (0x0300B000)
|
||||
#define MEM_INFO (1024)
|
||||
#define GPIOL_BASE (0x07022000)
|
||||
#define GPIOL_BASE_MAP (0x07022000)
|
||||
#define MAP_SIZE_L (4096 * 1)
|
||||
#define GPIO_PWM_OP (0x0300A000)
|
||||
#endif
|
||||
|
||||
/*********** OrangePi H616 *************/
|
||||
#if CONFIG_ORANGEPI_ZERO2
|
||||
#define GPIOA_BASE (0x0300B000)
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BASE_MAP (0x0300B000)
|
||||
#define MEM_INFO (1024)
|
||||
#define GPIOL_BASE (0x07022000)
|
||||
#define GPIOL_BASE_MAP (0x07022000)
|
||||
#define MAP_SIZE_L (4096 * 1)
|
||||
#define GPIO_PWM_OP (0x0300A000)
|
||||
#endif
|
||||
|
||||
/*********** OrangePi RK3399 *************/
|
||||
#if CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || CONFIG_ORANGEPI_4_LTS || CONFIG_ORANGEPI_800
|
||||
|
||||
#define GPIO1_BASE 0xff730000
|
||||
#define GPIO2_BASE 0xff780000
|
||||
#define GPIO4_BASE 0xff790000
|
||||
#define GPIO_NUM (0x40)
|
||||
#define GPIO_BIT(x) (1UL << (x))
|
||||
#define GPIO_SWPORTA_DR_OFFSET 0x00
|
||||
#define GPIO_SWPORTA_DDR_OFFSET 0x04
|
||||
#define GPIO_EXT_PORTA_OFFSET 0x50
|
||||
|
||||
#define RK3399_GRF_GPIO2_3_4_P_OFFSET 0x00040U
|
||||
#define RK3399_PMUGRF_GPIO0_1_P_OFFSET 0x00040U
|
||||
|
||||
#define PMUGRF_BASE 0xff320000
|
||||
#define PMUGRF_GPIO1A_IOMUX 0x00010
|
||||
#define PMUGRF_GPIO1B_IOMUX 0x00014
|
||||
#define PMUGRF_GPIO1C_IOMUX 0x00018
|
||||
#define PMUGRF_GPIO1D_IOMUX 0x0001c
|
||||
|
||||
#define GRF_BASE 0xff77e000
|
||||
#define GRF_GPIO2A_IOMUX_OFFSET 0x00
|
||||
#define GRF_GPIO2B_IOMUX_OFFSET 0x04
|
||||
#define GRF_GPIO2C_IOMUX_OFFSET 0x08
|
||||
#define GRF_GPIO2D_IOMUX_OFFSET 0x0c
|
||||
|
||||
#define GRF_GPIO4A_IOMUX_OFFSET 0x20
|
||||
#define GRF_GPIO4B_IOMUX_OFFSET 0x24
|
||||
#define GRF_GPIO4C_IOMUX_OFFSET 0x28
|
||||
#define GRF_GPIO4D_IOMUX_OFFSET 0x2c
|
||||
|
||||
|
||||
#define CRU_BASE 0xff760000
|
||||
#define PMUCRU_BASE 0xff750000
|
||||
#define CRU_CLKGATE_CON31_OFFSET 0x037c //bit 3 4 5
|
||||
#define PMUCRU_CLKGATE_CON1_OFFSET 0x0104
|
||||
|
||||
#define MEM_INFO (2048)
|
||||
#define MAP_SIZE_L (4*1024)
|
||||
|
||||
extern volatile unsigned int *gpio2_base;
|
||||
extern volatile unsigned int *grf_base;
|
||||
extern volatile unsigned int *cru_base;
|
||||
extern volatile unsigned int *pmucru_base;
|
||||
extern volatile unsigned int *pmugrf_base;
|
||||
extern volatile unsigned int *gpio1_base;
|
||||
extern volatile unsigned int *gpio4_base;
|
||||
|
||||
#endif /* CONFIG_ORANGEPI_RK3399 */
|
||||
//csy 2019.1.8
|
||||
|
||||
|
||||
/*********** OrangePi R1PLUS *************/
|
||||
#if CONFIG_ORANGEPI_R1PLUS
|
||||
|
||||
#define GPIO2_BASE 0xff230000
|
||||
#define GPIO3_BASE 0xff240000
|
||||
#define GPIO_NUM (0x40)
|
||||
|
||||
#define GPIO_SWPORTA_DR_OFFSET 0x00
|
||||
#define GPIO_SWPORTA_DDR_OFFSET 0x04
|
||||
#define GPIO_EXT_PORTA_OFFSET 0x50
|
||||
|
||||
#define GRF_BASE 0xff100000
|
||||
#define GRF_GPIO2A_IOMUX_OFFSET 0x20
|
||||
#define GRF_GPIO2BL_IOMUX_OFFSET 0x24
|
||||
#define GRF_GPIO2BH_IOMUX_OFFSET 0x28
|
||||
#define GRF_GPIO2CL_IOMUX_OFFSET 0x2c
|
||||
#define GRF_GPIO2CH_IOMUX_OFFSET 0x30
|
||||
#define GRF_GPIO2D_IOMUX_OFFSET 0x34
|
||||
|
||||
#define GRF_GPIO3AL_IOMUX_OFFSET 0x38
|
||||
#define GRF_GPIO3AH_IOMUX_OFFSET 0x3c
|
||||
#define GRF_GPIO3BL_IOMUX_OFFSET 0x40
|
||||
#define GRF_GPIO3BH_IOMUX_OFFSET 0x44
|
||||
#define GRF_GPIO3C_IOMUX_OFFSET 0x48
|
||||
#define GRF_GPIO3D_IOMUX_OFFSET 0x4c
|
||||
|
||||
#define CRU_BASE 0xff440000
|
||||
#define CRU_CLKGATE_CON16_OFFSET 0x0240 //bit 7 8 9 10 9877
|
||||
|
||||
#define MEM_INFO (2048)
|
||||
#define MAP_SIZE_L (4*1024)
|
||||
|
||||
extern volatile unsigned int *gpio2_base;
|
||||
extern volatile unsigned int *gpio3_base;
|
||||
extern volatile unsigned int *cru_base;
|
||||
extern volatile unsigned int *grf_base;
|
||||
|
||||
|
||||
#endif /* CONFIG_ORANGEPI_R1PLUS */
|
||||
//FG 2020.11.26
|
||||
|
||||
|
||||
|
||||
/****************** Global data *********************/
|
||||
/* Current version */
|
||||
#define PI_MAKER_ORANGEPI 4
|
||||
#define MAX_PIN_NUM GPIO_NUM
|
||||
#define MAP_SIZE MAP_SIZE_L
|
||||
#define MAP_MASK (MAP_SIZE - 1)
|
||||
#define PI_GPIO_MASK (~(GPIO_NUM - 1))
|
||||
#define GPIO_BASE GPIOA_BASE
|
||||
#define ORANGEPI_MEM_INFO MEM_INFO
|
||||
#define GPIO_PWM GPIO_PWM_OP
|
||||
|
||||
|
||||
//sunxi_pwm
|
||||
#define SUNXI_PWM_BASE (0x01c21400)
|
||||
#define SUNXI_PWM_CTRL_REG (SUNXI_PWM_BASE)
|
||||
#define SUNXI_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4)
|
||||
#define SUNXI_PWM_CH1_PERIOD (SUNXI_PWM_BASE + 0x8)
|
||||
|
||||
#define SUNXI_PWM_CH0_EN (1 << 4)
|
||||
#define SUNXI_PWM_CH0_ACT_STA (1 << 5)
|
||||
#define SUNXI_PWM_SCLK_CH0_GATING (1 << 6)
|
||||
#define SUNXI_PWM_CH0_MS_MODE (1 << 7) //pulse mode
|
||||
#define SUNXI_PWM_CH0_PUL_START (1 << 8)
|
||||
|
||||
#define PWM_CLK_DIV_120 0
|
||||
#define PWM_CLK_DIV_180 1
|
||||
#define PWM_CLK_DIV_240 2
|
||||
#define PWM_CLK_DIV_360 3
|
||||
#define PWM_CLK_DIV_480 4
|
||||
#define PWM_CLK_DIV_12K 8
|
||||
#define PWM_CLK_DIV_24K 9
|
||||
#define PWM_CLK_DIV_36K 10
|
||||
#define PWM_CLK_DIV_48K 11
|
||||
#define PWM_CLK_DIV_72K 12
|
||||
|
||||
#define SUNXI_PUD_OFF 0
|
||||
#define SUNXI_PUD_UP 1
|
||||
#define SUNXI_PUD_DOWN 2
|
||||
|
||||
extern int pinToGpioOrangePi[64];
|
||||
extern int physToGpioOrangePi[64];
|
||||
extern int physToPinOrangePi[64];
|
||||
extern int physToWpiOrangePi[64];
|
||||
extern volatile unsigned int *OrangePi_gpio;
|
||||
extern volatile unsigned int *OrangePi_gpioC;
|
||||
|
||||
extern int pinToGpioR3[64];
|
||||
extern int physToGpioR3[64];
|
||||
extern int physToPinR3[64];
|
||||
extern int pwmmode;
|
||||
|
||||
extern unsigned int readR(unsigned int addr);
|
||||
extern void writeR(unsigned int val, unsigned int addr);
|
||||
extern int OrangePi_set_gpio_mode(int pin, int mode);
|
||||
extern int OrangePi_set_gpio_pullUpDnControl(int pin, int pud);
|
||||
#if !(defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_2G_IOT)
|
||||
extern int OrangePi_set_gpio_alt(int pin, int mode);
|
||||
#endif
|
||||
extern int OrangePi_get_gpio_mode(int pin);
|
||||
extern int isOrangePi_2G_IOT(void);
|
||||
extern int isOrangePi(void);
|
||||
extern unsigned int readR(unsigned int addr);
|
||||
extern void writeR(unsigned int val, unsigned int addr);
|
||||
extern int OrangePi_digitalWrite(int pin, int value);
|
||||
extern int OrangePi_digitalRead(int pin);
|
||||
|
||||
extern void print_pwm_reg(void);
|
||||
extern void sunxi_pwm_set_enable(int en);
|
||||
extern void sunxi_pwm_set_mode(int mode);
|
||||
extern void sunxi_pwm_set_clk(int clk);
|
||||
extern int sunxi_pwm_get_period(void);
|
||||
extern int sunxi_pwm_get_act(void);
|
||||
extern void sunxi_pwm_set_period(int period_cys);
|
||||
extern void sunxi_pwm_set_act(int act_cys);
|
||||
|
||||
|
||||
#ifdef CONFIG_ORANGEPI
|
||||
extern const char *piModelNames[6];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ORANGEPI_2G_IOT
|
||||
extern int ORANGEPI_PIN_MASK[4][32];
|
||||
#elif CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_PRIME
|
||||
extern int ORANGEPI_PIN_MASK[9][32];
|
||||
#elif CONFIG_ORANGEPI_WIN
|
||||
extern int ORANGEPI_PIN_MASK[12][32];
|
||||
#elif CONFIG_ORANGEPI_H3
|
||||
extern int ORANGEPI_PIN_MASK[9][32];
|
||||
#elif CONFIG_ORANGEPI_ZERO || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5
|
||||
extern int ORANGEPI_PIN_MASK[12][32];
|
||||
#elif CONFIG_ORANGEPI_RK3399
|
||||
extern int ORANGEPI_PIN_MASK[5][32];
|
||||
#elif CONFIG_ORANGEPI_R1PLUS
|
||||
extern int ORANGEPI_PIN_MASK[5][32];
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
293
wiringPi/ads1115.c
Normal file
293
wiringPi/ads1115.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* ads1115.c:
|
||||
* Extend wiringPi with the ADS1115 I2C 16-bit ADC
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************
|
||||
* We're going to work in a hybrid mode to fit in with the wiringPi way of
|
||||
* doing things, so there will be 4 analog pin which read the 4 single-ended
|
||||
* channels as usual, also some fake digitalOutputs - these are the control
|
||||
* registers that allow the user to put it into single/diff mode, set the
|
||||
* gain and data rates.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
|
||||
#include "ads1115.h"
|
||||
|
||||
// Bits in the config register (it's a 16-bit register)
|
||||
|
||||
#define CONFIG_OS_MASK (0x8000) // Operational Status Register
|
||||
#define CONFIG_OS_SINGLE (0x8000) // Write - Starts a single-conversion
|
||||
// Read 1 = Conversion complete
|
||||
|
||||
// The multiplexor
|
||||
|
||||
#define CONFIG_MUX_MASK (0x7000)
|
||||
|
||||
// Differential modes
|
||||
|
||||
#define CONFIG_MUX_DIFF_0_1 (0x0000) // Pos = AIN0, Neg = AIN1 (default)
|
||||
#define CONFIG_MUX_DIFF_0_3 (0x1000) // Pos = AIN0, Neg = AIN3
|
||||
#define CONFIG_MUX_DIFF_1_3 (0x2000) // Pos = AIN1, Neg = AIN3
|
||||
#define CONFIG_MUX_DIFF_2_3 (0x3000) // Pos = AIN2, Neg = AIN3 (2nd differential channel)
|
||||
|
||||
// Single-ended modes
|
||||
|
||||
#define CONFIG_MUX_SINGLE_0 (0x4000) // AIN0
|
||||
#define CONFIG_MUX_SINGLE_1 (0x5000) // AIN1
|
||||
#define CONFIG_MUX_SINGLE_2 (0x6000) // AIN2
|
||||
#define CONFIG_MUX_SINGLE_3 (0x7000) // AIN3
|
||||
|
||||
// Programmable Gain Amplifier
|
||||
|
||||
#define CONFIG_PGA_MASK (0x0E00)
|
||||
#define CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
|
||||
#define CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1
|
||||
#define CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default)
|
||||
#define CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4
|
||||
#define CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8
|
||||
#define CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16
|
||||
|
||||
#define CONFIG_MODE (0x0100) // 0 is continuous, 1 is single-shot (default)
|
||||
|
||||
// Data Rate
|
||||
|
||||
#define CONFIG_DR_MASK (0x00E0)
|
||||
#define CONFIG_DR_8SPS (0x0000) // 8 samples per second
|
||||
#define CONFIG_DR_16SPS (0x0020) // 16 samples per second
|
||||
#define CONFIG_DR_32SPS (0x0040) // 32 samples per second
|
||||
#define CONFIG_DR_64SPS (0x0060) // 64 samples per second
|
||||
#define CONFIG_DR_128SPS (0x0080) // 128 samples per second (default)
|
||||
#define CONFIG_DR_475SPS (0x00A0) // 475 samples per second
|
||||
#define CONFIG_DR_860SPS (0x00C0) // 860 samples per second
|
||||
|
||||
// Comparator mode
|
||||
|
||||
#define CONFIG_CMODE_MASK (0x0010)
|
||||
#define CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
|
||||
#define CONFIG_CMODE_WINDOW (0x0010) // Window comparator
|
||||
|
||||
// Comparator polarity - the polarity of the output alert/rdy pin
|
||||
|
||||
#define CONFIG_CPOL_MASK (0x0008)
|
||||
#define CONFIG_CPOL_ACTVLOW (0x0000) // Active low (default)
|
||||
#define CONFIG_CPOL_ACTVHI (0x0008) // Active high
|
||||
|
||||
// Latching comparator - does the alert/rdy pin latch
|
||||
|
||||
#define CONFIG_CLAT_MASK (0x0004)
|
||||
#define CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
|
||||
#define CONFIG_CLAT_LATCH (0x0004) // Latching comparator
|
||||
|
||||
// Comparitor queue
|
||||
|
||||
#define CONFIG_CQUE_MASK (0x0003)
|
||||
#define CONFIG_CQUE_1CONV (0x0000) // Assert after one conversions
|
||||
#define CONFIG_CQUE_2CONV (0x0001) // Assert after two conversions
|
||||
#define CONFIG_CQUE_4CONV (0x0002) // Assert after four conversions
|
||||
#define CONFIG_CQUE_NONE (0x0003) // Disable the comparator (default)
|
||||
|
||||
#define CONFIG_DEFAULT (0x8583) // From the datasheet
|
||||
|
||||
|
||||
static const uint16_t dataRates [8] =
|
||||
{
|
||||
CONFIG_DR_8SPS, CONFIG_DR_16SPS, CONFIG_DR_32SPS, CONFIG_DR_64SPS, CONFIG_DR_128SPS, CONFIG_DR_475SPS, CONFIG_DR_860SPS
|
||||
} ;
|
||||
|
||||
static const uint16_t gains [6] =
|
||||
{
|
||||
CONFIG_PGA_6_144V, CONFIG_PGA_4_096V, CONFIG_PGA_2_048V, CONFIG_PGA_1_024V, CONFIG_PGA_0_512V, CONFIG_PGA_0_256V
|
||||
} ;
|
||||
|
||||
|
||||
/*
|
||||
* analogRead:
|
||||
* Pin is the channel to sample on the device.
|
||||
* Channels 0-3 are single ended inputs,
|
||||
* channels 4-7 are the various differential combinations.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int chan = pin - node->pinBase ;
|
||||
int16_t result ;
|
||||
uint16_t config = CONFIG_DEFAULT ;
|
||||
|
||||
chan &= 7 ;
|
||||
|
||||
// Setup the configuration register
|
||||
|
||||
// Set PGA/voltage range
|
||||
|
||||
config &= ~CONFIG_PGA_MASK ;
|
||||
config |= node->data0 ;
|
||||
|
||||
// Set sample speed
|
||||
|
||||
config &= ~CONFIG_DR_MASK ;
|
||||
config |= node->data1 ;
|
||||
|
||||
// Set single-ended channel or differential mode
|
||||
|
||||
config &= ~CONFIG_MUX_MASK ;
|
||||
|
||||
switch (chan)
|
||||
{
|
||||
case 0: config |= CONFIG_MUX_SINGLE_0 ; break ;
|
||||
case 1: config |= CONFIG_MUX_SINGLE_1 ; break ;
|
||||
case 2: config |= CONFIG_MUX_SINGLE_2 ; break ;
|
||||
case 3: config |= CONFIG_MUX_SINGLE_3 ; break ;
|
||||
|
||||
case 4: config |= CONFIG_MUX_DIFF_0_1 ; break ;
|
||||
case 5: config |= CONFIG_MUX_DIFF_2_3 ; break ;
|
||||
case 6: config |= CONFIG_MUX_DIFF_0_3 ; break ;
|
||||
case 7: config |= CONFIG_MUX_DIFF_1_3 ; break ;
|
||||
}
|
||||
|
||||
// Start a single conversion
|
||||
|
||||
config |= CONFIG_OS_SINGLE ;
|
||||
config = __bswap_16 (config) ;
|
||||
wiringPiI2CWriteReg16 (node->fd, 1, config) ;
|
||||
|
||||
// Wait for the conversion to complete
|
||||
|
||||
for (;;)
|
||||
{
|
||||
result = wiringPiI2CReadReg16 (node->fd, 1) ;
|
||||
result = __bswap_16 (result) ;
|
||||
if ((result & CONFIG_OS_MASK) != 0)
|
||||
break ;
|
||||
delayMicroseconds (100) ;
|
||||
}
|
||||
|
||||
result = wiringPiI2CReadReg16 (node->fd, 0) ;
|
||||
result = __bswap_16 (result) ;
|
||||
|
||||
// Sometimes with a 0v input on a single-ended channel the internal 0v reference
|
||||
// can be higher than the input, so you get a negative result...
|
||||
|
||||
if ( (chan < 4) && (result < 0) )
|
||||
return 0 ;
|
||||
else
|
||||
return (int)result ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* digitalWrite:
|
||||
* It may seem odd to have a digital write here, but it's the best way
|
||||
* to pass paramters into the chip in the wiringPi way of things.
|
||||
* We have 2 digital registers:
|
||||
* 0 is the gain control
|
||||
* 1 is the data rate control
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data)
|
||||
{
|
||||
int chan = pin - node->pinBase ;
|
||||
chan &= 3 ;
|
||||
|
||||
if (chan == 0) // Gain Control
|
||||
{
|
||||
if ( (data < 0) || (data > 6) ) // Use default if out of range
|
||||
data = 2 ;
|
||||
node->data0 = gains [data] ;
|
||||
}
|
||||
else // Data rate control
|
||||
{
|
||||
if ( (data < 0) || (data > 7) ) // Use default if out of range
|
||||
data = 4 ;
|
||||
node->data1 = dataRates [data] ; // Bugfix 0-1 by "Eric de jong (gm)" <ericdejong@gmx.net> - Thanks.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analogWrite:
|
||||
* We're using this to write to the 2 comparitor threshold registers.
|
||||
* We could use a digitalWrite here but as it's an analog comparison
|
||||
* then it feels better to do it this way.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int data)
|
||||
{
|
||||
int chan = pin - node->pinBase ;
|
||||
int reg ;
|
||||
int16_t ndata ;
|
||||
|
||||
chan &= 3 ;
|
||||
|
||||
reg = chan + 2 ;
|
||||
|
||||
/**/ if (data < -32767)
|
||||
ndata = -32767 ;
|
||||
else if (data > 32767)
|
||||
ndata = 32767 ;
|
||||
else
|
||||
ndata = (int16_t)data ;
|
||||
|
||||
ndata = __bswap_16 (ndata) ;
|
||||
wiringPiI2CWriteReg16 (node->fd, reg, data) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ads1115Setup:
|
||||
* Create a new wiringPi device node for an ads1115 on the Pi's
|
||||
* I2C interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int ads1115Setup (const int pinBase, int i2cAddr)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
int fd ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddr)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->data0 = CONFIG_PGA_4_096V ; // Gain in data0
|
||||
node->data1 = CONFIG_DR_128SPS ; // Samples/sec in data1
|
||||
node->analogRead = myAnalogRead ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
55
wiringPi/ads1115.h
Normal file
55
wiringPi/ads1115.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* ads1115.c:
|
||||
* Extend wiringPi with the ADS1115 I2C 16-bit ADC
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
// Constants for some of the internal functions
|
||||
|
||||
// Gain
|
||||
|
||||
#define ADS1115_GAIN_6 0
|
||||
#define ADS1115_GAIN_4 1
|
||||
#define ADS1115_GAIN_2 2
|
||||
#define ADS1115_GAIN_1 3
|
||||
#define ADS1115_GAIN_HALF 4
|
||||
#define ADS1115_GAIN_QUARTER 5
|
||||
|
||||
// Data rate
|
||||
|
||||
#define ADS1115_DR_8 0
|
||||
#define ADS1115_DR_16 1
|
||||
#define ADS1115_DR_32 2
|
||||
#define ADS1115_DR_64 3
|
||||
#define ADS1115_DR_128 4
|
||||
#define ADS1115_DR_250 5
|
||||
#define ADS1115_DR_475 6
|
||||
#define ADS1115_DR_860 7
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int ads1115Setup (int pinBase, int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
237
wiringPi/bmp180.c
Normal file
237
wiringPi/bmp180.c
Normal 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
wiringPi/bmp180.h
Normal file
34
wiringPi/bmp180.h
Normal 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
wiringPi/drcNet.c
Normal file
405
wiringPi/drcNet.c
Normal 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 [1034] ;
|
||||
|
||||
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
wiringPi/drcNet.h
Normal file
42
wiringPi/drcNet.h
Normal 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
|
||||
196
wiringPi/drcSerial.c
Normal file
196
wiringPi/drcSerial.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* drcSerial.c:
|
||||
* Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
|
||||
* Copyright (c) 2013-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 <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringSerial.h"
|
||||
|
||||
#include "drcSerial.h"
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
* Change the pin mode on the remote DRC device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
/**/ if (mode == OUTPUT)
|
||||
serialPutchar (node->fd, 'o') ; // Input
|
||||
else if (mode == PWM_OUTPUT)
|
||||
serialPutchar (node->fd, 'p') ; // PWM
|
||||
else
|
||||
serialPutchar (node->fd, 'i') ; // Default to input
|
||||
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPullUpDnControl:
|
||||
* ATmegas only have pull-up's on of off. No pull-downs.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
|
||||
// Force pin into input mode
|
||||
|
||||
serialPutchar (node->fd, 'i' ) ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
|
||||
/**/ if (mode == PUD_UP)
|
||||
{
|
||||
serialPutchar (node->fd, '1') ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
}
|
||||
else if (mode == PUD_OFF)
|
||||
{
|
||||
serialPutchar (node->fd, '0') ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
serialPutchar (node->fd, value == 0 ? '0' : '1') ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPwmWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
serialPutchar (node->fd, 'v') ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
serialPutchar (node->fd, value & 0xFF) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int vHi, vLo ;
|
||||
|
||||
serialPutchar (node->fd, 'a') ;
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
vHi = serialGetchar (node->fd) ;
|
||||
vLo = serialGetchar (node->fd) ;
|
||||
|
||||
return (vHi << 8) | vLo ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
serialPutchar (node->fd, 'r') ; // Send read command
|
||||
serialPutchar (node->fd, pin - node->pinBase) ;
|
||||
return (serialGetchar (node->fd) == '0') ? 0 : 1 ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* drcSetup:
|
||||
* Create a new instance of an DRC GPIO interface.
|
||||
* Could be a variable nunber of pins here - we might not know in advance
|
||||
* if it's an ATmega with 14 pins, or something with less or more!
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud)
|
||||
{
|
||||
int fd ;
|
||||
int ok, tries ;
|
||||
time_t then ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = serialOpen (device, baud)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
delay (10) ; // May need longer if it's an Uno that reboots on the open...
|
||||
|
||||
// Flush any pending input
|
||||
|
||||
while (serialDataAvail (fd))
|
||||
(void)serialGetchar (fd) ;
|
||||
|
||||
ok = FALSE ;
|
||||
for (tries = 1 ; (tries < 5) && (!ok) ; ++tries)
|
||||
{
|
||||
serialPutchar (fd, '@') ; // Ping
|
||||
then = time (NULL) + 2 ;
|
||||
while (time (NULL) < then)
|
||||
if (serialDataAvail (fd))
|
||||
{
|
||||
if (serialGetchar (fd) == '@')
|
||||
{
|
||||
ok = TRUE ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
serialClose (fd) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
node = wiringPiNewNode (pinBase, numPins) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->pullUpDnControl = myPullUpDnControl ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->pwmWrite = myPwmWrite ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/drcSerial.h
Normal file
33
wiringPi/drcSerial.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* drcSerial.h:
|
||||
* Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
|
||||
* Copyright (c) 2013 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 drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
146
wiringPi/ds18b20.c
Normal file
146
wiringPi/ds18b20.c
Normal 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
wiringPi/ds18b20.h
Normal file
34
wiringPi/ds18b20.h
Normal 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
|
||||
1808
wiringPi/font.h
Normal file
1808
wiringPi/font.h
Normal file
File diff suppressed because it is too large
Load Diff
150
wiringPi/htu21d.c
Normal file
150
wiringPi/htu21d.c
Normal 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
wiringPi/htu21d.h
Normal file
34
wiringPi/htu21d.h
Normal 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
|
||||
99
wiringPi/max31855.c
Normal file
99
wiringPi/max31855.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* max31855.c:
|
||||
* Extend wiringPi with the max31855 SPI Analog to Digital convertor
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
|
||||
#include "max31855.h"
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
uint32_t spiData ;
|
||||
int temp ;
|
||||
int chan = pin - node->pinBase ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, (unsigned char *)&spiData, 4) ;
|
||||
|
||||
spiData = __bswap_32(spiData) ;
|
||||
|
||||
switch (chan)
|
||||
{
|
||||
case 0: // Existing read - return raw value * 4
|
||||
spiData >>= 18 ;
|
||||
temp = spiData & 0x1FFF ; // Bottom 13 bits
|
||||
if ((spiData & 0x2000) != 0) // Negative
|
||||
temp = -temp ;
|
||||
|
||||
return temp ;
|
||||
|
||||
case 1: // Return error bits
|
||||
return spiData & 0x7 ;
|
||||
|
||||
case 2: // Return temp in C * 10
|
||||
spiData >>= 18 ;
|
||||
temp = spiData & 0x1FFF ; // Bottom 13 bits
|
||||
if ((spiData & 0x2000) != 0) // Negative
|
||||
temp = -temp ;
|
||||
|
||||
return (int)((((double)temp * 25) + 0.5) / 10.0) ;
|
||||
|
||||
case 3: // Return temp in F * 10
|
||||
spiData >>= 18 ;
|
||||
temp = spiData & 0x1FFF ; // Bottom 13 bits
|
||||
if ((spiData & 0x2000) != 0) // Negative
|
||||
temp = -temp ;
|
||||
|
||||
return (int)((((((double)temp * 0.25 * 9.0 / 5.0) + 32.0) * 100.0) + 0.5) / 10.0) ;
|
||||
|
||||
default: // Who knows...
|
||||
return 0 ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* max31855Setup:
|
||||
* Create a new wiringPi device node for an max31855 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int max31855Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 5000000) < 0) // 5MHz - prob 4 on the Pi
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 4) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/max31855.h
Normal file
33
wiringPi/max31855.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* max31855.c:
|
||||
* Extend wiringPi with the MAX31855 SPI Thermocouple driver
|
||||
* Copyright (c) 2012-2013 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 max31855Setup (int pinBase, int spiChannel) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
84
wiringPi/max5322.c
Normal file
84
wiringPi/max5322.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* max5322.c:
|
||||
* Extend wiringPi with the MAX5322 SPI Digital to Analog convertor
|
||||
* Copyright (c) 2012-2013 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 <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
|
||||
#include "max5322.h"
|
||||
|
||||
/*
|
||||
* myAnalogWrite:
|
||||
* Write analog value on the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
unsigned char spiData [2] ;
|
||||
unsigned char chanBits, dataBits ;
|
||||
int chan = pin - node->pinBase ;
|
||||
|
||||
if (chan == 0)
|
||||
chanBits = 0b01000000 ;
|
||||
else
|
||||
chanBits = 0b01010000 ;
|
||||
|
||||
chanBits |= ((value >> 12) & 0x0F) ;
|
||||
dataBits = ((value ) & 0xFF) ;
|
||||
|
||||
spiData [0] = chanBits ;
|
||||
spiData [1] = dataBits ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, spiData, 2) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* max5322Setup:
|
||||
* Create a new wiringPi device node for an max5322 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int max5322Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
unsigned char spiData [2] ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 8000000) < 0) // 10MHz Max
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 2) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
// Enable both DACs
|
||||
|
||||
spiData [0] = 0b11100000 ;
|
||||
spiData [1] = 0 ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, spiData, 2) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/max5322.h
Normal file
33
wiringPi/max5322.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* max5322.h:
|
||||
* Extend wiringPi with the MAX5322 SPI Digital to Analog convertor
|
||||
* Copyright (c) 2012-2013 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 max5322Setup (int pinBase, int spiChannel) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
149
wiringPi/mcp23008.c
Normal file
149
wiringPi/mcp23008.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* mcp23008.c:
|
||||
* Extend wiringPi with the MCP 23008 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
#include "mcp23x0817.h"
|
||||
|
||||
#include "mcp23008.h"
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
reg = MCP23x08_IODIR ;
|
||||
mask = 1 << (pin - node->pinBase) ;
|
||||
old = wiringPiI2CReadReg8 (node->fd, reg) ;
|
||||
|
||||
if (mode == OUTPUT)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPullUpDnControl:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
reg = MCP23x08_GPPU ;
|
||||
mask = 1 << (pin - node->pinBase) ;
|
||||
|
||||
old = wiringPiI2CReadReg8 (node->fd, reg) ;
|
||||
|
||||
if (mode == PUD_UP)
|
||||
old |= mask ;
|
||||
else
|
||||
old &= (~mask) ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
bit = 1 << ((pin - node->pinBase) & 7) ;
|
||||
|
||||
old = node->data2 ;
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, MCP23x08_GPIO, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value ;
|
||||
|
||||
mask = 1 << ((pin - node->pinBase) & 7) ;
|
||||
value = wiringPiI2CReadReg8 (node->fd, MCP23x08_GPIO) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp23008Setup:
|
||||
* Create a new instance of an MCP23008 I2C GPIO interface. We know it
|
||||
* has 8 pins, so all we need to know here is the I2C address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp23008Setup (const int pinBase, const int i2cAddress)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->pullUpDnControl = myPullUpDnControl ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp23008.h
Normal file
33
wiringPi/mcp23008.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 23008.h:
|
||||
* Extend wiringPi with the MCP 23008 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 mcp23008Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
164
wiringPi/mcp23016.c
Normal file
164
wiringPi/mcp23016.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* mcp23016.c:
|
||||
* Extend wiringPi with the MCP 23016 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
#include "mcp23016.h"
|
||||
|
||||
#include "mcp23016reg.h"
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
reg = MCP23016_IODIR0 ;
|
||||
else
|
||||
{
|
||||
reg = MCP23016_IODIR1 ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
old = wiringPiI2CReadReg8 (node->fd, reg) ;
|
||||
|
||||
if (mode == OUTPUT)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
pin -= node->pinBase ; // Pin now 0-15
|
||||
|
||||
bit = 1 << (pin & 7) ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
{
|
||||
old = node->data2 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, MCP23016_GP0, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
else // Bank B
|
||||
{
|
||||
old = node->data3 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, MCP23016_GP1, old) ;
|
||||
node->data3 = old ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value, gpio ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
gpio = MCP23016_GP0 ;
|
||||
else
|
||||
{
|
||||
gpio = MCP23016_GP1 ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
value = wiringPiI2CReadReg8 (node->fd, gpio) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp23016Setup:
|
||||
* Create a new instance of an MCP23016 I2C GPIO interface. We know it
|
||||
* has 16 pins, so all we need to know here is the I2C address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp23016Setup (const int pinBase, const int i2cAddress)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ;
|
||||
wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 16) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ;
|
||||
node->data3 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp23016.h
Normal file
33
wiringPi/mcp23016.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* mcp23016.h:
|
||||
* Extend wiringPi with the MCP 23016 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 mcp23016Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
48
wiringPi/mcp23016reg.h
Normal file
48
wiringPi/mcp23016reg.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* mcp23016:
|
||||
* Copyright (c) 2012-2013 Gordon Henderson
|
||||
*
|
||||
* Header file for code using the MCP23016 GPIO expander
|
||||
* chip.
|
||||
***********************************************************************
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
// MCP23016 Registers
|
||||
|
||||
#define MCP23016_GP0 0x00
|
||||
#define MCP23016_GP1 0x01
|
||||
#define MCP23016_OLAT0 0x02
|
||||
#define MCP23016_OLAT1 0x03
|
||||
#define MCP23016_IPOL0 0x04
|
||||
#define MCP23016_IPOL1 0x05
|
||||
#define MCP23016_IODIR0 0x06
|
||||
#define MCP23016_IODIR1 0x07
|
||||
#define MCP23016_INTCAP0 0x08
|
||||
#define MCP23016_INTCAP1 0x09
|
||||
#define MCP23016_IOCON0 0x0A
|
||||
#define MCP23016_IOCON1 0x0B
|
||||
|
||||
// Bits in the IOCON register
|
||||
|
||||
#define IOCON_IARES 0x01
|
||||
|
||||
// Default initialisation mode
|
||||
|
||||
#define IOCON_INIT 0
|
||||
195
wiringPi/mcp23017.c
Normal file
195
wiringPi/mcp23017.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* mcp23017.c:
|
||||
* Extend wiringPi with the MCP 23017 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
#include "mcp23x0817.h"
|
||||
|
||||
#include "mcp23017.h"
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
reg = MCP23x17_IODIRA ;
|
||||
else
|
||||
{
|
||||
reg = MCP23x17_IODIRB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
old = wiringPiI2CReadReg8 (node->fd, reg) ;
|
||||
|
||||
if (mode == OUTPUT)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPullUpDnControl:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
reg = MCP23x17_GPPUA ;
|
||||
else
|
||||
{
|
||||
reg = MCP23x17_GPPUB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
old = wiringPiI2CReadReg8 (node->fd, reg) ;
|
||||
|
||||
if (mode == PUD_UP)
|
||||
old |= mask ;
|
||||
else
|
||||
old &= (~mask) ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
pin -= node->pinBase ; // Pin now 0-15
|
||||
|
||||
bit = 1 << (pin & 7) ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
{
|
||||
old = node->data2 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
else // Bank B
|
||||
{
|
||||
old = node->data3 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ;
|
||||
node->data3 = old ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value, gpio ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
gpio = MCP23x17_GPIOA ;
|
||||
else
|
||||
{
|
||||
gpio = MCP23x17_GPIOB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
value = wiringPiI2CReadReg8 (node->fd, gpio) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp23017Setup:
|
||||
* Create a new instance of an MCP23017 I2C GPIO interface. We know it
|
||||
* has 16 pins, so all we need to know here is the I2C address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp23017Setup (const int pinBase, const int i2cAddress)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 16) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->pullUpDnControl = myPullUpDnControl ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ;
|
||||
node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp23017.h
Normal file
33
wiringPi/mcp23017.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 23017.h:
|
||||
* Extend wiringPi with the MCP 23017 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 mcp23017Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
188
wiringPi/mcp23s08.c
Normal file
188
wiringPi/mcp23s08.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* mcp23s08.c:
|
||||
* Extend wiringPi with the MCP 23s08 SPI GPIO expander chip
|
||||
* Copyright (c) 2013 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 "wiringPi.h"
|
||||
#include "wiringPiSPI.h"
|
||||
#include "mcp23x0817.h"
|
||||
|
||||
#include "mcp23s08.h"
|
||||
|
||||
#define MCP_SPEED 4000000
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* writeByte:
|
||||
* Write a byte to a register on the MCP23s08 on the SPI bus.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t spiData [4] ;
|
||||
|
||||
spiData [0] = CMD_WRITE | ((devId & 7) << 1) ;
|
||||
spiData [1] = reg ;
|
||||
spiData [2] = data ;
|
||||
|
||||
wiringPiSPIDataRW (spiPort, spiData, 3) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* readByte:
|
||||
* Read a byte from a register on the MCP23s08 on the SPI bus.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg)
|
||||
{
|
||||
uint8_t spiData [4] ;
|
||||
|
||||
spiData [0] = CMD_READ | ((devId & 7) << 1) ;
|
||||
spiData [1] = reg ;
|
||||
|
||||
wiringPiSPIDataRW (spiPort, spiData, 3) ;
|
||||
|
||||
return spiData [2] ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
reg = MCP23x08_IODIR ;
|
||||
mask = 1 << (pin - node->pinBase) ;
|
||||
old = readByte (node->data0, node->data1, reg) ;
|
||||
|
||||
if (mode == OUTPUT)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
writeByte (node->data0, node->data1, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPullUpDnControl:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
reg = MCP23x08_GPPU ;
|
||||
mask = 1 << (pin - node->pinBase) ;
|
||||
|
||||
old = readByte (node->data0, node->data1, reg) ;
|
||||
|
||||
if (mode == PUD_UP)
|
||||
old |= mask ;
|
||||
else
|
||||
old &= (~mask) ;
|
||||
|
||||
writeByte (node->data0, node->data1, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
bit = 1 << ((pin - node->pinBase) & 7) ;
|
||||
|
||||
old = node->data2 ;
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
writeByte (node->data0, node->data1, MCP23x08_GPIO, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value ;
|
||||
|
||||
mask = 1 << ((pin - node->pinBase) & 7) ;
|
||||
value = readByte (node->data0, node->data1, MCP23x08_GPIO) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp23s08Setup:
|
||||
* Create a new instance of an MCP23s08 SPI GPIO interface. We know it
|
||||
* has 8 pins, so all we need to know here is the SPI address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp23s08Setup (const int pinBase, const int spiPort, const int devId)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0)
|
||||
return FALSE ;
|
||||
|
||||
writeByte (spiPort, devId, MCP23x08_IOCON, IOCON_INIT) ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->data0 = spiPort ;
|
||||
node->data1 = devId ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->pullUpDnControl = myPullUpDnControl ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = readByte (spiPort, devId, MCP23x08_OLAT) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp23s08.h
Normal file
33
wiringPi/mcp23s08.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 23s08.h:
|
||||
* Extend wiringPi with the MCP 23s08 SPI GPIO expander chip
|
||||
* Copyright (c) 2013 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 mcp23s08Setup (const int pinBase, const int spiPort, const int devId) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
235
wiringPi/mcp23s17.c
Normal file
235
wiringPi/mcp23s17.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* mcp23s17.c:
|
||||
* Extend wiringPi with the MCP 23s17 SPI GPIO expander chip
|
||||
* Copyright (c) 2013 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 "wiringPi.h"
|
||||
#include "wiringPiSPI.h"
|
||||
#include "mcp23x0817.h"
|
||||
|
||||
#include "mcp23s17.h"
|
||||
|
||||
#define MCP_SPEED 4000000
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* writeByte:
|
||||
* Write a byte to a register on the MCP23s17 on the SPI bus.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t spiData [4] ;
|
||||
|
||||
spiData [0] = CMD_WRITE | ((devId & 7) << 1) ;
|
||||
spiData [1] = reg ;
|
||||
spiData [2] = data ;
|
||||
|
||||
wiringPiSPIDataRW (spiPort, spiData, 3) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* readByte:
|
||||
* Read a byte from a register on the MCP23s17 on the SPI bus.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg)
|
||||
{
|
||||
uint8_t spiData [4] ;
|
||||
|
||||
spiData [0] = CMD_READ | ((devId & 7) << 1) ;
|
||||
spiData [1] = reg ;
|
||||
|
||||
wiringPiSPIDataRW (spiPort, spiData, 3) ;
|
||||
|
||||
return spiData [2] ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
reg = MCP23x17_IODIRA ;
|
||||
else
|
||||
{
|
||||
reg = MCP23x17_IODIRB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
old = readByte (node->data0, node->data1, reg) ;
|
||||
|
||||
if (mode == OUTPUT)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
writeByte (node->data0, node->data1, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myPullUpDnControl:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int mask, old, reg ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
reg = MCP23x17_GPPUA ;
|
||||
else
|
||||
{
|
||||
reg = MCP23x17_GPPUB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
old = readByte (node->data0, node->data1, reg) ;
|
||||
|
||||
if (mode == PUD_UP)
|
||||
old |= mask ;
|
||||
else
|
||||
old &= (~mask) ;
|
||||
|
||||
writeByte (node->data0, node->data1, reg, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
pin -= node->pinBase ; // Pin now 0-15
|
||||
|
||||
bit = 1 << (pin & 7) ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
{
|
||||
old = node->data2 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
writeByte (node->data0, node->data1, MCP23x17_GPIOA, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
else // Bank B
|
||||
{
|
||||
old = node->data3 ;
|
||||
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
writeByte (node->data0, node->data1, MCP23x17_GPIOB, old) ;
|
||||
node->data3 = old ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value, gpio ;
|
||||
|
||||
pin -= node->pinBase ;
|
||||
|
||||
if (pin < 8) // Bank A
|
||||
gpio = MCP23x17_GPIOA ;
|
||||
else
|
||||
{
|
||||
gpio = MCP23x17_GPIOB ;
|
||||
pin &= 0x07 ;
|
||||
}
|
||||
|
||||
mask = 1 << pin ;
|
||||
value = readByte (node->data0, node->data1, gpio) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp23s17Setup:
|
||||
* Create a new instance of an MCP23s17 SPI GPIO interface. We know it
|
||||
* has 16 pins, so all we need to know here is the SPI address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp23s17Setup (const int pinBase, const int spiPort, const int devId)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0)
|
||||
return FALSE ;
|
||||
|
||||
writeByte (spiPort, devId, MCP23x17_IOCON, IOCON_INIT | IOCON_HAEN) ;
|
||||
writeByte (spiPort, devId, MCP23x17_IOCONB, IOCON_INIT | IOCON_HAEN) ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 16) ;
|
||||
|
||||
node->data0 = spiPort ;
|
||||
node->data1 = devId ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->pullUpDnControl = myPullUpDnControl ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = readByte (spiPort, devId, MCP23x17_OLATA) ;
|
||||
node->data3 = readByte (spiPort, devId, MCP23x17_OLATB) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp23s17.h
Normal file
33
wiringPi/mcp23s17.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 23s17.h:
|
||||
* Extend wiringPi with the MCP 23s17 SPI GPIO expander chip
|
||||
* Copyright (c) 2013 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 mcp23s17Setup (int pinBase, int spiPort, int devId) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
73
wiringPi/mcp23x08.h
Normal file
73
wiringPi/mcp23x08.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* mcp23x17:
|
||||
* Copyright (c) 2012-2013 Gordon Henderson
|
||||
*
|
||||
* Header file for code using the MCP23x17 GPIO expander chip.
|
||||
* This comes in 2 flavours: MCP23017 which has an I2C interface,
|
||||
* an the MXP23S17 which has an SPI interface.
|
||||
***********************************************************************
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
// MCP23x17 Registers
|
||||
|
||||
#define IODIRA 0x00
|
||||
#define IPOLA 0x02
|
||||
#define GPINTENA 0x04
|
||||
#define DEFVALA 0x06
|
||||
#define INTCONA 0x08
|
||||
#define IOCON 0x0A
|
||||
#define GPPUA 0x0C
|
||||
#define INTFA 0x0E
|
||||
#define INTCAPA 0x10
|
||||
#define GPIOA 0x12
|
||||
#define OLATA 0x14
|
||||
|
||||
#define IODIRB 0x01
|
||||
#define IPOLB 0x03
|
||||
#define GPINTENB 0x05
|
||||
#define DEFVALB 0x07
|
||||
#define INTCONB 0x09
|
||||
#define IOCONB 0x0B
|
||||
#define GPPUB 0x0D
|
||||
#define INTFB 0x0F
|
||||
#define INTCAPB 0x11
|
||||
#define GPIOB 0x13
|
||||
#define OLATB 0x15
|
||||
|
||||
// Bits in the IOCON register
|
||||
|
||||
#define IOCON_UNUSED 0x01
|
||||
#define IOCON_INTPOL 0x02
|
||||
#define IOCON_ODR 0x04
|
||||
#define IOCON_HAEN 0x08
|
||||
#define IOCON_DISSLW 0x10
|
||||
#define IOCON_SEQOP 0x20
|
||||
#define IOCON_MIRROR 0x40
|
||||
#define IOCON_BANK_MODE 0x80
|
||||
|
||||
// Default initialisation mode
|
||||
|
||||
#define IOCON_INIT (IOCON_SEQOP)
|
||||
|
||||
// SPI Command codes
|
||||
|
||||
#define CMD_WRITE 0x40
|
||||
#define CMD_READ 0x41
|
||||
87
wiringPi/mcp23x0817.h
Normal file
87
wiringPi/mcp23x0817.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* mcp23xxx:
|
||||
* Copyright (c) 2012-2013 Gordon Henderson
|
||||
*
|
||||
* Header file for code using the MCP23x08 and 17 GPIO expander
|
||||
* chips.
|
||||
* This comes in 2 flavours: MCP230xx (08/17) which has an I2C
|
||||
* interface, and the MXP23Sxx (08/17) which has an SPI interface.
|
||||
***********************************************************************
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
// MCP23x08 Registers
|
||||
|
||||
#define MCP23x08_IODIR 0x00
|
||||
#define MCP23x08_IPOL 0x01
|
||||
#define MCP23x08_GPINTEN 0x02
|
||||
#define MCP23x08_DEFVAL 0x03
|
||||
#define MCP23x08_INTCON 0x04
|
||||
#define MCP23x08_IOCON 0x05
|
||||
#define MCP23x08_GPPU 0x06
|
||||
#define MCP23x08_INTF 0x07
|
||||
#define MCP23x08_INTCAP 0x08
|
||||
#define MCP23x08_GPIO 0x09
|
||||
#define MCP23x08_OLAT 0x0A
|
||||
|
||||
// MCP23x17 Registers
|
||||
|
||||
#define MCP23x17_IODIRA 0x00
|
||||
#define MCP23x17_IPOLA 0x02
|
||||
#define MCP23x17_GPINTENA 0x04
|
||||
#define MCP23x17_DEFVALA 0x06
|
||||
#define MCP23x17_INTCONA 0x08
|
||||
#define MCP23x17_IOCON 0x0A
|
||||
#define MCP23x17_GPPUA 0x0C
|
||||
#define MCP23x17_INTFA 0x0E
|
||||
#define MCP23x17_INTCAPA 0x10
|
||||
#define MCP23x17_GPIOA 0x12
|
||||
#define MCP23x17_OLATA 0x14
|
||||
|
||||
#define MCP23x17_IODIRB 0x01
|
||||
#define MCP23x17_IPOLB 0x03
|
||||
#define MCP23x17_GPINTENB 0x05
|
||||
#define MCP23x17_DEFVALB 0x07
|
||||
#define MCP23x17_INTCONB 0x09
|
||||
#define MCP23x17_IOCONB 0x0B
|
||||
#define MCP23x17_GPPUB 0x0D
|
||||
#define MCP23x17_INTFB 0x0F
|
||||
#define MCP23x17_INTCAPB 0x11
|
||||
#define MCP23x17_GPIOB 0x13
|
||||
#define MCP23x17_OLATB 0x15
|
||||
|
||||
// Bits in the IOCON register
|
||||
|
||||
#define IOCON_UNUSED 0x01
|
||||
#define IOCON_INTPOL 0x02
|
||||
#define IOCON_ODR 0x04
|
||||
#define IOCON_HAEN 0x08
|
||||
#define IOCON_DISSLW 0x10
|
||||
#define IOCON_SEQOP 0x20
|
||||
#define IOCON_MIRROR 0x40
|
||||
#define IOCON_BANK_MODE 0x80
|
||||
|
||||
// Default initialisation mode
|
||||
|
||||
#define IOCON_INIT (IOCON_SEQOP)
|
||||
|
||||
// SPI Command codes
|
||||
|
||||
#define CMD_WRITE 0x40
|
||||
#define CMD_READ 0x41
|
||||
76
wiringPi/mcp3002.c
Normal file
76
wiringPi/mcp3002.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* mcp3002.c:
|
||||
* Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
|
||||
* Copyright (c) 2012-2013 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 <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
|
||||
#include "mcp3002.h"
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
* Return the analog value of the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
unsigned char spiData [2] ;
|
||||
unsigned char chanBits ;
|
||||
int chan = pin - node->pinBase ;
|
||||
|
||||
if (chan == 0)
|
||||
chanBits = 0b11010000 ;
|
||||
else
|
||||
chanBits = 0b11110000 ;
|
||||
|
||||
spiData [0] = chanBits ;
|
||||
spiData [1] = 0 ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, spiData, 2) ;
|
||||
|
||||
return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp3002Setup:
|
||||
* Create a new wiringPi device node for an mcp3002 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp3002Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 1000000) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 2) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp3002.h
Normal file
33
wiringPi/mcp3002.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* mcp3002.c:
|
||||
* Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
|
||||
* Copyright (c) 2012-2013 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 mcp3002Setup (int pinBase, int spiChannel) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
76
wiringPi/mcp3004.c
Normal file
76
wiringPi/mcp3004.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* mcp3004.c:
|
||||
* Extend wiringPi with the MCP3004 SPI Analog to Digital convertor
|
||||
* Copyright (c) 2012-2013 Gordon Henderson
|
||||
*
|
||||
* Thanks also to "ShorTie" on IRC for some remote debugging help!
|
||||
***********************************************************************
|
||||
* 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 <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
|
||||
#include "mcp3004.h"
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
* Return the analog value of the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
unsigned char spiData [3] ;
|
||||
unsigned char chanBits ;
|
||||
int chan = pin - node->pinBase ;
|
||||
|
||||
chanBits = 0b10000000 | (chan << 4) ;
|
||||
|
||||
spiData [0] = 1 ; // Start bit
|
||||
spiData [1] = chanBits ;
|
||||
spiData [2] = 0 ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, spiData, 3) ;
|
||||
|
||||
return ((spiData [1] << 8) | spiData [2]) & 0x3FF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp3004Setup:
|
||||
* Create a new wiringPi device node for an mcp3004 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp3004Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 1000000) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp3004.h
Normal file
33
wiringPi/mcp3004.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* mcp3004.c:
|
||||
* Extend wiringPi with the MCP3004 SPI Analog to Digital convertor
|
||||
* Copyright (c) 2012-2013 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 mcp3004Setup (int pinBase, int spiChannel) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
125
wiringPi/mcp3422.c
Normal file
125
wiringPi/mcp3422.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* mcp3422.c:
|
||||
* Extend wiringPi with the MCP3422/3/4 I2C ADC chip
|
||||
* This code assumes single-ended mode only.
|
||||
* Tested on actual hardware: 20th Feb 2016.
|
||||
* Copyright (c) 2013-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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
|
||||
#include "mcp3422.h"
|
||||
|
||||
|
||||
/*
|
||||
* waitForConversion:
|
||||
* Common code to wait for the ADC to finish conversion
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void waitForConversion (int fd, unsigned char *buffer, int n)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if ( read (fd, buffer, n) ){;}
|
||||
if ((buffer [n-1] & 0x80) == 0)
|
||||
break ;
|
||||
delay (1) ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
* Read a channel from the device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
|
||||
{
|
||||
unsigned char config ;
|
||||
unsigned char buffer [4] ;
|
||||
int value = 0 ;
|
||||
int realChan = (chan & 3) - node->pinBase ;
|
||||
|
||||
// One-shot mode, trigger plus the other configs.
|
||||
|
||||
config = 0x80 | (realChan << 5) | (node->data0 << 2) | (node->data1) ;
|
||||
|
||||
wiringPiI2CWrite (node->fd, config) ;
|
||||
|
||||
switch (node->data0) // Sample rate
|
||||
{
|
||||
case MCP3422_SR_3_75: // 18 bits
|
||||
waitForConversion (node->fd, &buffer [0], 4) ;
|
||||
value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [2] ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_15: // 16 bits
|
||||
waitForConversion (node->fd, buffer, 3) ;
|
||||
value = (buffer [0] << 8) | buffer [1] ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_60: // 14 bits
|
||||
waitForConversion (node->fd, buffer, 3) ;
|
||||
value = ((buffer [0] & 0x3F) << 8) | buffer [1] ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_240: // 12 bits - default
|
||||
waitForConversion (node->fd, buffer, 3) ;
|
||||
value = ((buffer [0] & 0x0F) << 8) | buffer [1] ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return value ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp3422Setup:
|
||||
* Create a new wiringPi device node for the mcp3422
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 4) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->data0 = sampleRate ;
|
||||
node->data1 = gain ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
43
wiringPi/mcp3422.h
Normal file
43
wiringPi/mcp3422.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* mcp3422.h:
|
||||
* Extend wiringPi with the MCP3422/3/4 I2C ADC chip
|
||||
***********************************************************************
|
||||
* 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 MCP3422_SR_240 0
|
||||
#define MCP3422_SR_60 1
|
||||
#define MCP3422_SR_15 2
|
||||
#define MCP3422_SR_3_75 3
|
||||
|
||||
#define MCP3422_GAIN_1 0
|
||||
#define MCP3422_GAIN_2 1
|
||||
#define MCP3422_GAIN_4 2
|
||||
#define MCP3422_GAIN_8 3
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
76
wiringPi/mcp4802.c
Normal file
76
wiringPi/mcp4802.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* mcp4802.c:
|
||||
* Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
|
||||
* Copyright (c) 2012-2013 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 <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
|
||||
#include "mcp4802.h"
|
||||
|
||||
/*
|
||||
* myAnalogWrite:
|
||||
* Write analog value on the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
unsigned char spiData [2] ;
|
||||
unsigned char chanBits, dataBits ;
|
||||
int chan = pin - node->pinBase ;
|
||||
|
||||
if (chan == 0)
|
||||
chanBits = 0x30 ;
|
||||
else
|
||||
chanBits = 0xB0 ;
|
||||
|
||||
chanBits |= ((value >> 4) & 0x0F) ;
|
||||
dataBits = ((value << 4) & 0xF0) ;
|
||||
|
||||
spiData [0] = chanBits ;
|
||||
spiData [1] = dataBits ;
|
||||
|
||||
wiringPiSPIDataRW (node->fd, spiData, 2) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* mcp4802Setup:
|
||||
* Create a new wiringPi device node for an mcp4802 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp4802Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 1000000) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 2) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/mcp4802.h
Normal file
33
wiringPi/mcp4802.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* mcp4802.c:
|
||||
* Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
|
||||
* Copyright (c) 2012-2013 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 mcp4802Setup (int pinBase, int spiChannel) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
20
wiringPi/noMoreStatic
Normal file
20
wiringPi/noMoreStatic
Normal 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.
|
||||
163
wiringPi/oled.c
Normal file
163
wiringPi/oled.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Vladimir Komendantskiy
|
||||
* MIT License
|
||||
*
|
||||
* OLED is a 128x64 dot matrix display driver and controller by Solomon
|
||||
* Systech. It is used by HelTec display modules.
|
||||
*
|
||||
* Reference:
|
||||
*
|
||||
* [1] OLED Advance Information. 128x64 Dot Matrix Segment/Common
|
||||
* Driver with Controller. (Solomon Systech)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// real-time features
|
||||
#include <sys/mman.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "oled.h"
|
||||
#include "font.h"
|
||||
#include <wiringPiI2C.h>
|
||||
|
||||
|
||||
int oled_close(struct display_info *disp) {
|
||||
if (close(disp->file) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup(int status, void *disp) {
|
||||
oled_close((struct display_info *)disp);
|
||||
}
|
||||
|
||||
int oled_open(struct display_info *disp, char *filename) {
|
||||
|
||||
disp->file = wiringPiI2CSetupInterface (filename, disp->address);
|
||||
if (disp->file < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write commands and data to /dev/i2c*
|
||||
int oled_send(struct display_info *disp, struct sized_array *payload) {
|
||||
if (write(disp->file, payload->array, payload->size) != payload->size)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int oled_init(struct display_info *disp) {
|
||||
struct sched_param sch;
|
||||
int status = 0;
|
||||
struct sized_array payload;
|
||||
|
||||
// sch.sched_priority = 49;
|
||||
//
|
||||
// status = sched_setscheduler(0, SCHED_FIFO, &sch);
|
||||
// if (status < 0)
|
||||
// return status;
|
||||
//
|
||||
// status = mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
// if (status < 0)
|
||||
// return status;
|
||||
|
||||
payload.size = sizeof(display_config);
|
||||
payload.array = display_config;
|
||||
|
||||
status = oled_send(disp, &payload);
|
||||
if (status < 0)
|
||||
return 666;
|
||||
|
||||
memset(disp->buffer, 0, sizeof(disp->buffer));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// send buffer to oled (show)
|
||||
int oled_send_buffer(struct display_info *disp) {
|
||||
struct sized_array payload;
|
||||
uint8_t packet[129];
|
||||
int index;
|
||||
|
||||
for (index = 0; index < 8; index++) {
|
||||
packet[0] = OLED_CTRL_BYTE_DATA_STREAM;
|
||||
memcpy(packet + 1, disp->buffer[index], 128);
|
||||
payload.size = 129;
|
||||
payload.array = packet;
|
||||
oled_send(disp, &payload);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// clear screen
|
||||
void oled_clear(struct display_info *disp) {
|
||||
memset(disp->buffer, 0, sizeof(disp->buffer));
|
||||
oled_send_buffer(disp);
|
||||
}
|
||||
|
||||
// put string to one of the 8 pages (128x8 px)
|
||||
void oled_putstr(struct display_info *disp, uint8_t line, uint8_t *str) {
|
||||
uint8_t a;
|
||||
int slen = strlen(str);
|
||||
uint8_t fwidth = disp->font.width;
|
||||
uint8_t foffset = disp->font.offset;
|
||||
uint8_t fspacing = disp->font.spacing;
|
||||
int i=0;
|
||||
|
||||
for (i=0; i<slen; i++) {
|
||||
a=(uint8_t)str[i];
|
||||
if (i >= 128/fwidth)
|
||||
break; // no text wrap
|
||||
memcpy(disp->buffer[line] + i*fwidth + fspacing, &disp->font.data[(a-foffset) * fwidth], fwidth);
|
||||
}
|
||||
}
|
||||
|
||||
// put one pixel at xy, on=1|0 (turn on|off pixel)
|
||||
void oled_putpixel(struct display_info *disp, uint8_t x, uint8_t y, uint8_t on) {
|
||||
uint8_t pageId = y / 8;
|
||||
uint8_t bitOffset = y % 8;
|
||||
if (x < 128-2) {
|
||||
if (on == 1)
|
||||
disp->buffer[pageId][x] |= (1<<bitOffset);
|
||||
else
|
||||
disp->buffer[pageId][x] &= ~(1<<bitOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// put string to the buffer at xy
|
||||
void oled_putstrto(struct display_info *disp, uint8_t x, uint8_t y, char *str) {
|
||||
uint8_t a;
|
||||
int slen = strlen(str);
|
||||
uint8_t fwidth = disp->font.width;
|
||||
uint8_t fheight = disp->font.height;
|
||||
uint8_t foffset = disp->font.offset;
|
||||
uint8_t fspacing = disp->font.spacing;
|
||||
int i=0;
|
||||
int j=0;
|
||||
int k=0;
|
||||
|
||||
for (k=0; k<slen; k++) {
|
||||
a=(uint8_t)str[k];
|
||||
for (i=0; i<fwidth; i++) {
|
||||
for (j=0; j<fheight; j++) {
|
||||
if (((disp->font.data[(a-foffset)*fwidth + i] >> j) & 0x01))
|
||||
oled_putpixel(disp, x+i, y+j, 1);
|
||||
else
|
||||
oled_putpixel(disp, x+i, y+j, 0);
|
||||
}
|
||||
}
|
||||
x+=fwidth+fspacing;
|
||||
}
|
||||
}
|
||||
|
||||
127
wiringPi/oled.h
Normal file
127
wiringPi/oled.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Vladimir Komendantskiy
|
||||
* MIT License
|
||||
*
|
||||
* IOCTL interface to SSD1306 modules.
|
||||
*
|
||||
* Command sequences are sourced from an Arduino library by Sonal Pinto.
|
||||
*/
|
||||
|
||||
#ifndef OLED_H
|
||||
#define OLED_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "font.h"
|
||||
|
||||
#define OLED_I2C_ADDR 0x3c
|
||||
|
||||
// Control byte
|
||||
#define OLED_CTRL_BYTE_CMD_SINGLE 0x80
|
||||
#define OLED_CTRL_BYTE_CMD_STREAM 0x00
|
||||
#define OLED_CTRL_BYTE_DATA_STREAM 0x40
|
||||
// Fundamental commands (page 28)
|
||||
#define OLED_CMD_SET_CONTRAST 0x81
|
||||
#define OLED_CMD_DISPLAY_RAM 0xA4
|
||||
#define OLED_CMD_DISPLAY_ALLON 0xA5
|
||||
#define OLED_CMD_DISPLAY_NORMAL 0xA6
|
||||
#define OLED_CMD_DISPLAY_INVERTED 0xA7
|
||||
#define OLED_CMD_DISPLAY_OFF 0xAE
|
||||
#define OLED_CMD_DISPLAY_ON 0xAF
|
||||
// Addressing Command Table (page 30)
|
||||
#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20
|
||||
#define OLED_CMD_SET_COLUMN_RANGE 0x21
|
||||
#define OLED_CMD_SET_PAGE_RANGE 0x22
|
||||
// Hardware Config (page 31)
|
||||
#define OLED_CMD_SET_DISPLAY_START_LINE 0x40
|
||||
#define OLED_CMD_SET_SEGMENT_REMAP 0xA1
|
||||
#define OLED_CMD_SET_MUX_RATIO 0xA8
|
||||
#define OLED_CMD_SET_COM_SCAN_MODE 0xC8
|
||||
#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3
|
||||
#define OLED_CMD_SET_COM_PIN_MAP 0xDA
|
||||
#define OLED_CMD_NOP 0xE3
|
||||
// Timing and Driving Scheme (page 32)
|
||||
#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5
|
||||
#define OLED_CMD_SET_PRECHARGE 0xD9
|
||||
#define OLED_CMD_SET_VCOMH_DESELCT 0xDB
|
||||
// Charge Pump (page 62)
|
||||
#define OLED_CMD_SET_CHARGE_PUMP 0x8D
|
||||
// SH1106 Display
|
||||
#define OLED_SET_PAGE_ADDRESS 0xB0
|
||||
|
||||
|
||||
static const unsigned char display_config[] = {
|
||||
OLED_CTRL_BYTE_CMD_STREAM,
|
||||
OLED_CMD_DISPLAY_OFF,
|
||||
|
||||
OLED_SET_PAGE_ADDRESS,
|
||||
0x02, /*set lower column address*/
|
||||
0x10, /*set higher column address*/
|
||||
|
||||
OLED_CMD_SET_MUX_RATIO, 0x3F,
|
||||
// Set the display offset to 0
|
||||
OLED_CMD_SET_DISPLAY_OFFSET, 0x00,
|
||||
// Display start line to 0
|
||||
OLED_CMD_SET_DISPLAY_START_LINE,
|
||||
// Mirror the x-axis. In case you set it up such that the pins are north.
|
||||
// 0xA0 - in case pins are south - default
|
||||
OLED_CMD_SET_SEGMENT_REMAP,
|
||||
// Mirror the y-axis. In case you set it up such that the pins are north.
|
||||
// 0xC0 - in case pins are south - default
|
||||
OLED_CMD_SET_COM_SCAN_MODE,
|
||||
// Default - alternate COM pin map
|
||||
OLED_CMD_SET_COM_PIN_MAP, 0x12,
|
||||
// set contrast
|
||||
OLED_CMD_SET_CONTRAST, 0x7F,
|
||||
// Set display to enable rendering from GDDRAM (Graphic Display Data RAM)
|
||||
OLED_CMD_DISPLAY_RAM,
|
||||
// Normal mode!
|
||||
OLED_CMD_DISPLAY_NORMAL,
|
||||
// Default oscillator clock
|
||||
OLED_CMD_SET_DISPLAY_CLK_DIV, 0x80,
|
||||
// Enable the charge pump
|
||||
OLED_CMD_SET_CHARGE_PUMP, 0x14,
|
||||
// Set precharge cycles to high cap type
|
||||
OLED_CMD_SET_PRECHARGE, 0x22,
|
||||
// Set the V_COMH deselect volatage to max
|
||||
OLED_CMD_SET_VCOMH_DESELCT, 0x30,
|
||||
// Horizonatal addressing mode - same as the KS108 GLCD
|
||||
OLED_CMD_SET_MEMORY_ADDR_MODE, 0x00,
|
||||
// Turn the Display ON
|
||||
OLED_CMD_DISPLAY_ON
|
||||
};
|
||||
|
||||
static const unsigned char display_draw[] = {
|
||||
OLED_CTRL_BYTE_CMD_STREAM,
|
||||
// column 0 to 127
|
||||
OLED_CMD_SET_COLUMN_RANGE,
|
||||
0x00,
|
||||
0x7F,
|
||||
// page 0 to 7
|
||||
OLED_CMD_SET_PAGE_RANGE,
|
||||
0x00,
|
||||
0x07
|
||||
};
|
||||
|
||||
struct display_info {
|
||||
int address;
|
||||
int file;
|
||||
struct font_info font;
|
||||
uint8_t buffer[8][128];
|
||||
};
|
||||
|
||||
struct sized_array {
|
||||
int size;
|
||||
const uint8_t* array;
|
||||
};
|
||||
|
||||
extern int oled_close (struct display_info* disp);
|
||||
extern int oled_open (struct display_info* disp, char* filename);
|
||||
extern int oled_send (struct display_info* disp, struct sized_array* payload);
|
||||
extern int oled_init (struct display_info* disp);
|
||||
extern int oled_send_buffer (struct display_info* disp);
|
||||
extern void oled_clear(struct display_info *disp);
|
||||
extern void oled_putstr(struct display_info *disp, uint8_t line, uint8_t *str);
|
||||
extern void oled_putpixel(struct display_info *disp, uint8_t x, uint8_t y, uint8_t on);
|
||||
extern void oled_putstrto(struct display_info *disp, uint8_t x, uint8_t y, char *str);
|
||||
|
||||
#endif // OLED_H
|
||||
126
wiringPi/pcf8574.c
Normal file
126
wiringPi/pcf8574.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* pcf8574.c:
|
||||
* Extend wiringPi with the PCF8574 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
|
||||
#include "pcf8574.h"
|
||||
|
||||
|
||||
/*
|
||||
* myPinMode:
|
||||
* The PCF8574 is an odd chip - the pins are effectively bi-directional,
|
||||
* however the pins should be drven high when used as an input pin...
|
||||
* So, we're effectively copying digitalWrite...
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
bit = 1 << ((pin - node->pinBase) & 7) ;
|
||||
|
||||
old = node->data2 ;
|
||||
if (mode == OUTPUT)
|
||||
old &= (~bit) ; // Write bit to 0
|
||||
else
|
||||
old |= bit ; // Write bit to 1
|
||||
|
||||
wiringPiI2CWrite (node->fd, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int bit, old ;
|
||||
|
||||
bit = 1 << ((pin - node->pinBase) & 7) ;
|
||||
|
||||
old = node->data2 ;
|
||||
if (value == LOW)
|
||||
old &= (~bit) ;
|
||||
else
|
||||
old |= bit ;
|
||||
|
||||
wiringPiI2CWrite (node->fd, old) ;
|
||||
node->data2 = old ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int mask, value ;
|
||||
|
||||
mask = 1 << ((pin - node->pinBase) & 7) ;
|
||||
value = wiringPiI2CRead (node->fd) ;
|
||||
|
||||
if ((value & mask) == 0)
|
||||
return LOW ;
|
||||
else
|
||||
return HIGH ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pcf8574Setup:
|
||||
* Create a new instance of a PCF8574 I2C GPIO interface. We know it
|
||||
* has 8 pins, so all we need to know here is the I2C address and the
|
||||
* user-defined pin base.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int pcf8574Setup (const int pinBase, const int i2cAddress)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = wiringPiI2CRead (fd) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/pcf8574.h
Normal file
33
wiringPi/pcf8574.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* pcf8574.h:
|
||||
* Extend wiringPi with the PCF8574 I2C GPIO expander chip
|
||||
* Copyright (c) 2013 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 pcf8574Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
90
wiringPi/pcf8591.c
Normal file
90
wiringPi/pcf8591.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* pcf8591.c:
|
||||
* Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip
|
||||
* The chip has 1 8-bit DAC and 4 x 8-bit ADCs
|
||||
* Copyright (c) 2013 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 "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
|
||||
#include "pcf8591.h"
|
||||
|
||||
|
||||
/*
|
||||
* myAnalogWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int value)
|
||||
{
|
||||
unsigned char b [2] ;
|
||||
b [0] = 0x40 ;
|
||||
b [1] = value & 0xFF ;
|
||||
if ( write (node->fd, b, 2) ){;}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
||||
{
|
||||
int x ;
|
||||
|
||||
wiringPiI2CWrite (node->fd, 0x40 | ((pin - node->pinBase) & 3)) ;
|
||||
|
||||
x = wiringPiI2CRead (node->fd) ; // Throw away the first read
|
||||
x = wiringPiI2CRead (node->fd) ;
|
||||
|
||||
return x ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pcf8591Setup:
|
||||
* 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 pcf8591Setup (const int pinBase, const int i2cAddress)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 4) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/pcf8591.h
Normal file
33
wiringPi/pcf8591.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* pcf8591.h:
|
||||
* Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip
|
||||
* Copyright (c) 2013 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 pcf8591Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
51
wiringPi/piHiPri.c
Normal file
51
wiringPi/piHiPri.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* piHiPri:
|
||||
* Simple way to get your program running at high priority
|
||||
* with realtime schedulling.
|
||||
*
|
||||
* Copyright (c) 2012 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 <sched.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
|
||||
/*
|
||||
* piHiPri:
|
||||
* Attempt to set a high priority schedulling for the running program
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int piHiPri (const int pri)
|
||||
{
|
||||
struct sched_param sched ;
|
||||
|
||||
memset (&sched, 0, sizeof(sched)) ;
|
||||
|
||||
if (pri > sched_get_priority_max (SCHED_RR))
|
||||
sched.sched_priority = sched_get_priority_max (SCHED_RR) ;
|
||||
else
|
||||
sched.sched_priority = pri ;
|
||||
|
||||
return sched_setscheduler (0, SCHED_RR, &sched) ;
|
||||
}
|
||||
63
wiringPi/piThread.c
Normal file
63
wiringPi/piThread.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* piThread.c:
|
||||
* Provide a simplified interface to pthreads
|
||||
*
|
||||
* Copyright (c) 2012 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 <pthread.h>
|
||||
#include "wiringPi.h"
|
||||
|
||||
static pthread_mutex_t piMutexes [4] ;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* piThreadCreate:
|
||||
* Create and start a thread
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int piThreadCreate (void *(*fn)(void *))
|
||||
{
|
||||
pthread_t myThread ;
|
||||
|
||||
return pthread_create (&myThread, NULL, fn, NULL) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* piLock: piUnlock:
|
||||
* Activate/Deactivate a mutex.
|
||||
* We're keeping things simple here and only tracking 4 mutexes which
|
||||
* is more than enough for out entry-level pthread programming
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void piLock (int key)
|
||||
{
|
||||
pthread_mutex_lock (&piMutexes [key]) ;
|
||||
}
|
||||
|
||||
void piUnlock (int key)
|
||||
{
|
||||
pthread_mutex_unlock (&piMutexes [key]) ;
|
||||
}
|
||||
|
||||
95
wiringPi/pseudoPins.c
Normal file
95
wiringPi/pseudoPins.c
Normal 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
wiringPi/pseudoPins.h
Normal file
26
wiringPi/pseudoPins.h
Normal 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) ;
|
||||
256
wiringPi/rht03.c
Normal file
256
wiringPi/rht03.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#ifdef CONFIG_ORANGEPI
|
||||
#include "OrangePi.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
wiringPi/rht03.h
Normal file
25
wiringPi/rht03.h
Normal 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) ;
|
||||
75
wiringPi/sn3218.c
Normal file
75
wiringPi/sn3218.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* sn3218.c:
|
||||
* Extend wiringPi with the SN3218 I2C LEd Driver
|
||||
* Copyright (c) 2012-2013 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 <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
|
||||
#include "sn3218.h"
|
||||
|
||||
/*
|
||||
* myAnalogWrite:
|
||||
* Write analog value on the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
int fd = node->fd ;
|
||||
int chan = 0x01 + (pin - node->pinBase) ;
|
||||
|
||||
wiringPiI2CWriteReg8 (fd, chan, value & 0xFF) ; // Value
|
||||
wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update
|
||||
}
|
||||
|
||||
/*
|
||||
* sn3218Setup:
|
||||
* Create a new wiringPi device node for an sn3218 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int sn3218Setup (const int pinBase)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (0x54)) < 0)
|
||||
return FALSE ;
|
||||
|
||||
// Setup the chip - initialise all 18 LEDs to off
|
||||
|
||||
//wiringPiI2CWriteReg8 (fd, 0x17, 0) ; // Reset
|
||||
wiringPiI2CWriteReg8 (fd, 0x00, 1) ; // Not Shutdown
|
||||
wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ; // Enable LEDs 0- 5
|
||||
wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ; // Enable LEDs 6-11
|
||||
wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ; // Enable LEDs 12-17
|
||||
wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update
|
||||
|
||||
node = wiringPiNewNode (pinBase, 18) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
33
wiringPi/sn3218.h
Normal file
33
wiringPi/sn3218.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* sn3218.c:
|
||||
* Extend wiringPi with the SN3218 I2C LED driver board.
|
||||
* Copyright (c) 2012-2013 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 sn3218Setup (int pinBase) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
183
wiringPi/softPwm.c
Normal file
183
wiringPi/softPwm.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* softPwm.c:
|
||||
* 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/
|
||||
*
|
||||
* 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 <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.
|
||||
// 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 64
|
||||
|
||||
// The PWM Frequency is derived from the "pulse time" below. Essentially,
|
||||
// the frequency is a function of the range and this pulse time.
|
||||
// The total period will be range * pulse time in µS, so a pulse time
|
||||
// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 µS
|
||||
// which is a frequency of 100Hz.
|
||||
//
|
||||
// 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
|
||||
// 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...
|
||||
|
||||
#define PULSE_TIME 100
|
||||
|
||||
static volatile int marks [MAX_PINS] ;
|
||||
static volatile int range [MAX_PINS] ;
|
||||
static volatile pthread_t threads [MAX_PINS] ;
|
||||
static volatile int newPin = -1 ;
|
||||
|
||||
|
||||
/*
|
||||
* softPwmThread:
|
||||
* Thread to do the actual PWM output
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void *softPwmThread (void *arg)
|
||||
{
|
||||
int pin, mark, space ;
|
||||
struct sched_param param ;
|
||||
|
||||
param.sched_priority = sched_get_priority_max (SCHED_RR) ;
|
||||
pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ;
|
||||
|
||||
pin = *((int *)arg) ;
|
||||
free (arg) ;
|
||||
|
||||
pin = newPin ;
|
||||
newPin = -1 ;
|
||||
|
||||
piHiPri (90) ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
mark = marks [pin] ;
|
||||
space = range [pin] - mark ;
|
||||
|
||||
if (mark != 0)
|
||||
digitalWrite (pin, HIGH) ;
|
||||
delayMicroseconds (mark * 100) ;
|
||||
|
||||
if (space != 0)
|
||||
digitalWrite (pin, LOW) ;
|
||||
delayMicroseconds (space * 100) ;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softPwmWrite:
|
||||
* Write a PWM value to the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softPwmWrite (int pin, int value)
|
||||
{
|
||||
if (pin < MAX_PINS)
|
||||
{
|
||||
/**/ if (value < 0)
|
||||
value = 0 ;
|
||||
else if (value > range [pin])
|
||||
value = range [pin] ;
|
||||
|
||||
marks [pin] = value ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softPwmCreate:
|
||||
* Create a new softPWM thread.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
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 (pwmRange <= 0)
|
||||
return -1 ;
|
||||
|
||||
passPin = malloc (sizeof (*passPin)) ;
|
||||
if (passPin == NULL)
|
||||
return -1 ;
|
||||
|
||||
digitalWrite (pin, LOW) ;
|
||||
pinMode (pin, OUTPUT) ;
|
||||
|
||||
marks [pin] = initialValue ;
|
||||
range [pin] = pwmRange ;
|
||||
|
||||
*passPin = pin ;
|
||||
newPin = pin ;
|
||||
res = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ;
|
||||
|
||||
while (newPin != -1)
|
||||
delay (1) ;
|
||||
|
||||
threads [pin] = myThread ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softPwmStop:
|
||||
* Stop an existing softPWM thread
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softPwmStop (int pin)
|
||||
{
|
||||
if (pin < MAX_PINS)
|
||||
{
|
||||
if (range [pin] != 0)
|
||||
{
|
||||
pthread_cancel (threads [pin]) ;
|
||||
pthread_join (threads [pin], NULL) ;
|
||||
range [pin] = 0 ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
wiringPi/softPwm.h
Normal file
35
wiringPi/softPwm.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* softPwm.h:
|
||||
* Provide 2 channels of software driven PWM.
|
||||
* Copyright (c) 2012 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 softPwmCreate (int pin, int value, int range) ;
|
||||
extern void softPwmWrite (int pin, int value) ;
|
||||
extern void softPwmStop (int pin) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
211
wiringPi/softServo.c
Normal file
211
wiringPi/softServo.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* softServo.c:
|
||||
* Provide N channels of software driven PWM suitable for RC
|
||||
* servo motors.
|
||||
* Copyright (c) 2012 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 <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "softServo.h"
|
||||
|
||||
// RC Servo motors are a bit of an oddity - designed in the days when
|
||||
// radio control was experimental and people were tryin to make
|
||||
// things as simple as possible as it was all very expensive...
|
||||
//
|
||||
// So... To drive an RC Servo motor, you need to send it a modified PWM
|
||||
// signal - it needs anything from 1ms to 2ms - with 1ms meaning
|
||||
// to move the server fully left, and 2ms meaning to move it fully
|
||||
// right. Then you need a long gap before sending the next pulse.
|
||||
// The reason for this is that you send a multiplexed stream of these
|
||||
// pulses up the radio signal into the reciever which de-multiplexes
|
||||
// them into the signals for each individual servo. Typically there
|
||||
// might be 8 channels, so you need at least 8 "slots" of 2mS pulses
|
||||
// meaning the entire frame must fit into a 16mS slot - which would
|
||||
// then be repeated...
|
||||
//
|
||||
// In practice we have a total slot width of about 20mS - so we're sending 50
|
||||
// updates per second to each servo.
|
||||
//
|
||||
// In this code, we don't need to be too fussy about the gap as we're not doing
|
||||
// the multipexing, but it does need to be at least 10mS, and preferably 16
|
||||
// from what I've been able to determine.
|
||||
|
||||
// WARNING:
|
||||
// This code is really experimental. It was written in response to some people
|
||||
// asking for a servo driver, however while it works, there is too much
|
||||
// jitter to successfully drive a small servo - I have tried it with a micro
|
||||
// servo and it worked, but the servo ran hot due to the jitter in the signal
|
||||
// being sent to it.
|
||||
//
|
||||
// If you want servo control for the Pi, then use the servoblaster kernel
|
||||
// module.
|
||||
|
||||
#define MAX_SERVOS 8
|
||||
|
||||
static int pinMap [MAX_SERVOS] ; // Keep track of our pins
|
||||
static int pulseWidth [MAX_SERVOS] ; // microseconds
|
||||
|
||||
|
||||
/*
|
||||
* softServoThread:
|
||||
* Thread to do the actual Servo PWM output
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static PI_THREAD (softServoThread)
|
||||
{
|
||||
register int i, j, k, m, tmp ;
|
||||
int lastDelay, pin, servo ;
|
||||
|
||||
int myDelays [MAX_SERVOS] ;
|
||||
int myPins [MAX_SERVOS] ;
|
||||
|
||||
struct timeval tNow, tStart, tPeriod, tGap, tTotal ;
|
||||
struct timespec tNs ;
|
||||
|
||||
tTotal.tv_sec = 0 ;
|
||||
tTotal.tv_usec = 8000 ;
|
||||
|
||||
piHiPri (50) ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
gettimeofday (&tStart, NULL) ;
|
||||
|
||||
memcpy (myDelays, pulseWidth, sizeof (myDelays)) ;
|
||||
memcpy (myPins, pinMap, sizeof (myPins)) ;
|
||||
|
||||
// Sort the delays (& pins), shortest first
|
||||
|
||||
for (m = MAX_SERVOS / 2 ; m > 0 ; m /= 2 )
|
||||
for (j = m ; j < MAX_SERVOS ; ++j)
|
||||
for (i = j - m ; i >= 0 ; i -= m)
|
||||
{
|
||||
k = i + m ;
|
||||
if (myDelays [k] >= myDelays [i])
|
||||
break ;
|
||||
else // Swap
|
||||
{
|
||||
tmp = myDelays [i] ; myDelays [i] = myDelays [k] ; myDelays [k] = tmp ;
|
||||
tmp = myPins [i] ; myPins [i] = myPins [k] ; myPins [k] = tmp ;
|
||||
}
|
||||
}
|
||||
|
||||
// All on
|
||||
|
||||
lastDelay = 0 ;
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
{
|
||||
if ((pin = myPins [servo]) == -1)
|
||||
continue ;
|
||||
|
||||
digitalWrite (pin, HIGH) ;
|
||||
myDelays [servo] = myDelays [servo] - lastDelay ;
|
||||
lastDelay += myDelays [servo] ;
|
||||
}
|
||||
|
||||
// Now loop, turning them all off as required
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
{
|
||||
if ((pin = myPins [servo]) == -1)
|
||||
continue ;
|
||||
|
||||
delayMicroseconds (myDelays [servo]) ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
}
|
||||
|
||||
// Wait until the end of an 8mS time-slot
|
||||
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
timersub (&tNow, &tStart, &tPeriod) ;
|
||||
timersub (&tTotal, &tPeriod, &tGap) ;
|
||||
tNs.tv_sec = tGap.tv_sec ;
|
||||
tNs.tv_nsec = tGap.tv_usec * 1000 ;
|
||||
nanosleep (&tNs, NULL) ;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softServoWrite:
|
||||
* Write a Servo value to the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softServoWrite (int servoPin, int value)
|
||||
{
|
||||
int servo ;
|
||||
|
||||
servoPin &= 63 ;
|
||||
|
||||
/**/ if (value < -250)
|
||||
value = -250 ;
|
||||
else if (value > 1250)
|
||||
value = 1250 ;
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
if (pinMap [servo] == servoPin)
|
||||
pulseWidth [servo] = value + 1000 ; // uS
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softServoSetup:
|
||||
* Setup the software servo system
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7)
|
||||
{
|
||||
int servo ;
|
||||
|
||||
if (p0 != -1) { pinMode (p0, OUTPUT) ; digitalWrite (p0, LOW) ; }
|
||||
if (p1 != -1) { pinMode (p1, OUTPUT) ; digitalWrite (p1, LOW) ; }
|
||||
if (p2 != -1) { pinMode (p2, OUTPUT) ; digitalWrite (p2, LOW) ; }
|
||||
if (p3 != -1) { pinMode (p3, OUTPUT) ; digitalWrite (p3, LOW) ; }
|
||||
if (p4 != -1) { pinMode (p4, OUTPUT) ; digitalWrite (p4, LOW) ; }
|
||||
if (p5 != -1) { pinMode (p5, OUTPUT) ; digitalWrite (p5, LOW) ; }
|
||||
if (p6 != -1) { pinMode (p6, OUTPUT) ; digitalWrite (p6, LOW) ; }
|
||||
if (p7 != -1) { pinMode (p7, OUTPUT) ; digitalWrite (p7, LOW) ; }
|
||||
|
||||
pinMap [0] = p0 ;
|
||||
pinMap [1] = p1 ;
|
||||
pinMap [2] = p2 ;
|
||||
pinMap [3] = p3 ;
|
||||
pinMap [4] = p4 ;
|
||||
pinMap [5] = p5 ;
|
||||
pinMap [6] = p6 ;
|
||||
pinMap [7] = p7 ;
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
pulseWidth [servo] = 1500 ; // Mid point
|
||||
|
||||
return piThreadCreate (softServoThread) ;
|
||||
}
|
||||
35
wiringPi/softServo.h
Normal file
35
wiringPi/softServo.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* softServo.h:
|
||||
* Provide N channels of software driven PWM suitable for RC
|
||||
* servo motors.
|
||||
* Copyright (c) 2012 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 void softServoWrite (int pin, int value) ;
|
||||
extern int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
150
wiringPi/softTone.c
Normal file
150
wiringPi/softTone.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* softTone.c:
|
||||
* For that authentic retro sound...
|
||||
* Er... A little experiment to produce tones out of a Pi using
|
||||
* one (or 2) GPIO pins and a piezeo "speaker" element.
|
||||
* (Or a high impedance speaker, but don'y blame me if you blow-up
|
||||
* the GPIO pins!)
|
||||
* Copyright (c) 2012 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 <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "softTone.h"
|
||||
|
||||
#define MAX_PINS 64
|
||||
|
||||
#define PULSE_TIME 100
|
||||
|
||||
static int freqs [MAX_PINS] ;
|
||||
static pthread_t threads [MAX_PINS] ;
|
||||
|
||||
static int newPin = -1 ;
|
||||
|
||||
|
||||
/*
|
||||
* softToneThread:
|
||||
* Thread to do the actual PWM output
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static PI_THREAD (softToneThread)
|
||||
{
|
||||
int pin, freq, halfPeriod ;
|
||||
struct sched_param param ;
|
||||
|
||||
param.sched_priority = sched_get_priority_max (SCHED_RR) ;
|
||||
pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ;
|
||||
|
||||
pin = newPin ;
|
||||
newPin = -1 ;
|
||||
|
||||
piHiPri (50) ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
freq = freqs [pin] ;
|
||||
if (freq == 0)
|
||||
delay (1) ;
|
||||
else
|
||||
{
|
||||
halfPeriod = 500000 / freq ;
|
||||
|
||||
digitalWrite (pin, HIGH) ;
|
||||
delayMicroseconds (halfPeriod) ;
|
||||
|
||||
digitalWrite (pin, LOW) ;
|
||||
delayMicroseconds (halfPeriod) ;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softToneWrite:
|
||||
* Write a frequency value to the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softToneWrite (int pin, int freq)
|
||||
{
|
||||
pin &= 63 ;
|
||||
|
||||
/**/ if (freq < 0)
|
||||
freq = 0 ;
|
||||
else if (freq > 5000) // Max 5KHz
|
||||
freq = 5000 ;
|
||||
|
||||
freqs [pin] = freq ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softToneCreate:
|
||||
* Create a new tone thread.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int softToneCreate (int pin)
|
||||
{
|
||||
int res ;
|
||||
pthread_t myThread ;
|
||||
|
||||
pinMode (pin, OUTPUT) ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
|
||||
if (threads [pin] != 0)
|
||||
return -1 ;
|
||||
|
||||
freqs [pin] = 0 ;
|
||||
|
||||
newPin = pin ;
|
||||
res = pthread_create (&myThread, NULL, softToneThread, NULL) ;
|
||||
|
||||
while (newPin != -1)
|
||||
delay (1) ;
|
||||
|
||||
threads [pin] = myThread ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softToneStop:
|
||||
* Stop an existing softTone thread
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softToneStop (int pin)
|
||||
{
|
||||
if (threads [pin] != 0)
|
||||
{
|
||||
pthread_cancel (threads [pin]) ;
|
||||
pthread_join (threads [pin], NULL) ;
|
||||
threads [pin] = 0 ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
}
|
||||
}
|
||||
39
wiringPi/softTone.h
Normal file
39
wiringPi/softTone.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* softTone.c:
|
||||
* For that authentic retro sound...
|
||||
* Er... A little experiment to produce tones out of a Pi using
|
||||
* one (or 2) GPIO pins and a piezeo "speaker" element.
|
||||
* (Or a high impedance speaker, but don'y blame me if you blow-up
|
||||
* the GPIO pins!)
|
||||
* Copyright (c) 2012 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 softToneCreate (int pin) ;
|
||||
extern void softToneStop (int pin) ;
|
||||
extern void softToneWrite (int pin, int freq) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
109
wiringPi/sr595.c
Normal file
109
wiringPi/sr595.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* sr595.c:
|
||||
* Extend wiringPi with the 74x595 shift register as a GPIO
|
||||
* expander chip.
|
||||
* Note that the code can cope with a number of 595's
|
||||
* daisy-chained together - up to 4 for now as we're storing
|
||||
* the output "register" in a single unsigned int.
|
||||
*
|
||||
* Copyright (c) 2013 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 "wiringPi.h"
|
||||
|
||||
#include "sr595.h"
|
||||
|
||||
|
||||
/*
|
||||
* myDigitalWrite:
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
||||
{
|
||||
unsigned int mask ;
|
||||
int dataPin, clockPin, latchPin ;
|
||||
int bit, bits, output ;
|
||||
|
||||
pin -= node->pinBase ; // Normalise pin number
|
||||
bits = node->pinMax - node->pinBase + 1 ; // ie. number of clock pulses
|
||||
dataPin = node->data0 ;
|
||||
clockPin = node->data1 ;
|
||||
latchPin = node->data2 ;
|
||||
output = node->data3 ;
|
||||
|
||||
mask = 1 << pin ;
|
||||
|
||||
if (value == LOW)
|
||||
output &= (~mask) ;
|
||||
else
|
||||
output |= mask ;
|
||||
|
||||
node->data3 = output ;
|
||||
|
||||
// A low -> high latch transition copies the latch to the output pins
|
||||
|
||||
digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ;
|
||||
for (bit = bits - 1 ; bit >= 0 ; --bit)
|
||||
{
|
||||
digitalWrite (dataPin, output & (1 << bit)) ;
|
||||
|
||||
digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ;
|
||||
digitalWrite (clockPin, LOW) ; delayMicroseconds (1) ;
|
||||
}
|
||||
digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sr595Setup:
|
||||
* Create a new instance of a 74x595 shift register GPIO expander.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int sr595Setup (const int pinBase, const int numPins,
|
||||
const int dataPin, const int clockPin, const int latchPin)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, numPins) ;
|
||||
|
||||
node->data0 = dataPin ;
|
||||
node->data1 = clockPin ;
|
||||
node->data2 = latchPin ;
|
||||
node->data3 = 0 ; // Output register
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
|
||||
// Initialise the underlying hardware
|
||||
|
||||
digitalWrite (dataPin, LOW) ;
|
||||
digitalWrite (clockPin, LOW) ;
|
||||
digitalWrite (latchPin, HIGH) ;
|
||||
|
||||
pinMode (dataPin, OUTPUT) ;
|
||||
pinMode (clockPin, OUTPUT) ;
|
||||
pinMode (latchPin, OUTPUT) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
34
wiringPi/sr595.h
Normal file
34
wiringPi/sr595.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* sr595.h:
|
||||
* Extend wiringPi with the 74x595 shift registers.
|
||||
* Copyright (c) 2013 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 sr595Setup (const int pinBase, const int numPins,
|
||||
const int dataPin, const int clockPin, const int latchPin) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
362
wiringPi/w25q64.c
Normal file
362
wiringPi/w25q64.c
Normal file
@@ -0,0 +1,362 @@
|
||||
//
|
||||
// Flash Memory W25Q64 Access Library for RaspberryPi
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiSPI.h>
|
||||
#include "w25q64.h"
|
||||
|
||||
#define SPI_SLAVE_SEL_PIN 10 // チップセレクトピン番号
|
||||
#define MAX_BLOCKSIZE 128 // ブロック総数
|
||||
#define MAX_SECTORSIZE 2048 // 総セクタ数
|
||||
|
||||
#define CMD_WRIRE_ENABLE 0x06
|
||||
#define CMD_WRITE_DISABLE 0x04
|
||||
#define CMD_READ_STATUS_R1 0x05
|
||||
#define CMD_READ_STATUS_R2 0x35
|
||||
#define CMD_WRITE_STATUS_R 0x01 // 未実装
|
||||
#define CMD_PAGE_PROGRAM 0x02
|
||||
#define CMD_QUAD_PAGE_PROGRAM 0x32 // 未実装
|
||||
#define CMD_BLOCK_ERASE64KB 0xd8
|
||||
#define CMD_BLOCK_ERASE32KB 0x52
|
||||
#define CMD_SECTOR_ERASE 0x20
|
||||
#define CMD_CHIP_ERASE 0xC7
|
||||
#define CMD_ERASE_SUPPEND 0x75 // 未実装
|
||||
#define CMD_ERASE_RESUME 0x7A // 未実装
|
||||
#define CMD_POWER_DOWN 0xB9
|
||||
#define CMD_HIGH_PERFORM_MODE 0xA3 // 未実装
|
||||
#define CMD_CNT_READ_MODE_RST 0xFF // 未実装
|
||||
#define CMD_RELEASE_PDOWN_ID 0xAB // 未実装
|
||||
#define CMD_MANUFACURER_ID 0x90
|
||||
#define CMD_READ_UNIQUE_ID 0x4B
|
||||
#define CMD_JEDEC_ID 0x9f
|
||||
|
||||
#define CMD_READ_DATA 0x03
|
||||
#define CMD_FAST_READ 0x0B
|
||||
#define CMD_READ_DUAL_OUTPUT 0x3B // 未実装
|
||||
#define CMD_READ_DUAL_IO 0xBB // 未実装
|
||||
#define CMD_READ_QUAD_OUTPUT 0x6B // 未実装
|
||||
#define CMD_READ_QUAD_IO 0xEB // 未実装
|
||||
#define CMD_WORD_READ 0xE3 // 未実装
|
||||
|
||||
#define SR1_BUSY_MASK 0x01
|
||||
#define SR1_WEN_MASK 0x02
|
||||
|
||||
//#define SPI_CHANNEL 0 // /dev/spidev0.0
|
||||
#define SPI_CHANNEL 1 // /dev/spidev0.1
|
||||
|
||||
//static uint8_t cspin ;
|
||||
static uint8_t _spich;
|
||||
|
||||
void spcDump(char *id,int rc, uint8_t *data,int len) {
|
||||
int i;
|
||||
printf("[%s] = %d\n",id,rc);
|
||||
for(i=0;i<len;i++) {
|
||||
printf("%0x ",data[i]);
|
||||
if ( (i % 10) == 9) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//
|
||||
// フラッシュメモリ W25Q64の利用開始
|
||||
//
|
||||
//void W25Q64_begin(uint8_t cs) {
|
||||
void W25Q64_begin(uint8_t spich) {
|
||||
_spich = spich;
|
||||
}
|
||||
|
||||
//
|
||||
// ステータスレジスタ1の値取得
|
||||
// 戻り値: ステータスレジスタ1の値
|
||||
//
|
||||
uint8_t W25Q64_readStatusReg1(void) {
|
||||
uint8_t data[2];
|
||||
int rc;
|
||||
data[0] = CMD_READ_STATUS_R1;
|
||||
data[1] = 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("readStatusReg1",rc,data,2);
|
||||
return data[1];
|
||||
}
|
||||
|
||||
//
|
||||
// ステータスレジスタ2の値取得
|
||||
// 戻り値: ステータスレジスタ2の値
|
||||
//
|
||||
uint8_t W25Q64_readStatusReg2(void) {
|
||||
uint8_t data[2];
|
||||
int rc;
|
||||
data[0] = CMD_READ_STATUS_R2;
|
||||
data[1] = 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("readStatusReg2",rc,data,2);
|
||||
return data[1];
|
||||
}
|
||||
|
||||
//
|
||||
// JEDEC ID(Manufacture, Memory Type,Capacity)の取得
|
||||
// d(out) :Manufacture, Memory Type,Capacityの3バイトを格納する
|
||||
//
|
||||
void W25Q64_readManufacturer(uint8_t* d) {
|
||||
uint8_t data[4];
|
||||
int rc;
|
||||
memset(data,0,sizeof(data));
|
||||
data[0] = CMD_JEDEC_ID;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("readManufacturer",rc,data,4);
|
||||
memcpy(d,&data[1],3);
|
||||
}
|
||||
|
||||
//
|
||||
// Unique IDの取得
|
||||
// d(out): Unique ID 7バイトを返す
|
||||
//
|
||||
void W25Q64_readUniqieID(uint8_t* d) {
|
||||
uint8_t data[12];
|
||||
int rc;
|
||||
memset(data,0,sizeof(data));
|
||||
data[0] = CMD_READ_UNIQUE_ID;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("readUniqieID",rc,data,12);
|
||||
memcpy(d,&data[5],7);
|
||||
}
|
||||
|
||||
//
|
||||
// 書込み等の処理中チェック
|
||||
// 戻り値: true:作業 、false:アイドル中
|
||||
//
|
||||
bool W25Q64_IsBusy() {
|
||||
uint8_t data[2];
|
||||
int rc;
|
||||
data[0] = CMD_READ_STATUS_R1;
|
||||
data[1] = 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("IsBusy",rc,data,2);
|
||||
uint8_t r1;
|
||||
r1 = data[1];
|
||||
if(r1 & SR1_BUSY_MASK)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// パワーダウン指定
|
||||
//
|
||||
void W25Q64_powerDown(void) {
|
||||
uint8_t data[1];
|
||||
int rc;
|
||||
data[0] = CMD_POWER_DOWN;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("powerDown",rc,data,1);
|
||||
}
|
||||
|
||||
//
|
||||
// 書込み許可設定
|
||||
//
|
||||
void W25Q64_WriteEnable(void) {
|
||||
uint8_t data[1];
|
||||
int rc;
|
||||
data[0] = CMD_WRIRE_ENABLE;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("WriteEnable",rc,data,1);
|
||||
}
|
||||
|
||||
//
|
||||
// 書込み禁止設定
|
||||
//
|
||||
void W25Q64_WriteDisable(void) {
|
||||
uint8_t data[1];
|
||||
int rc;
|
||||
data[0] = CMD_WRITE_DISABLE;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
// spcDump("WriteDisable",rc,data,1);
|
||||
}
|
||||
|
||||
//
|
||||
// データの読み込み
|
||||
// addr(in): 読込開始アドレス (24ビット 0x000000 - 0xFFFFFF)
|
||||
// n(in):読込データ数
|
||||
//
|
||||
uint16_t W25Q64_read(uint32_t addr,uint8_t *buf,uint16_t n){
|
||||
uint8_t *data;
|
||||
int rc;
|
||||
|
||||
data = (char*)malloc(n+4);
|
||||
data[0] = CMD_READ_DATA;
|
||||
data[1] = (addr>>16) & 0xFF; // A23-A16
|
||||
data[2] = (addr>>8) & 0xFF; // A15-A08
|
||||
data[3] = addr & 0xFF; // A07-A00
|
||||
rc = wiringPiSPIDataRW (_spich,data,n+4);
|
||||
// spcDump("read",rc,data,rc);
|
||||
memcpy(buf,&data[4],n);
|
||||
free(data);
|
||||
return rc-4;
|
||||
}
|
||||
|
||||
//
|
||||
// 高速データの読み込み
|
||||
// addr(in): 読込開始アドレス (24ビット 0x00000 - 0xFFFFF)
|
||||
// n(in):読込データ数
|
||||
//
|
||||
uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n) {
|
||||
uint8_t *data;
|
||||
int rc;
|
||||
|
||||
data = (char*)malloc(n+5);
|
||||
data[0] = CMD_FAST_READ;
|
||||
data[1] = (addr>>16) & 0xFF; // A23-A16
|
||||
data[2] = (addr>>8) & 0xFF; // A15-A08
|
||||
data[3] = addr & 0xFF; // A07-A00
|
||||
data[4] = 0;
|
||||
rc = wiringPiSPIDataRW (_spich,data,n+5);
|
||||
// spcDump("fastread",rc,data,rc);
|
||||
memcpy(buf,&data[5],n);
|
||||
return rc-5;
|
||||
}
|
||||
|
||||
//
|
||||
// セクタ単位消去(4kb空間単位でデータの消去を行う)
|
||||
// sect_no(in) セクタ番号(0 - 2048)
|
||||
// flgwait(in) true:処理待ちを行う false:待ち無し
|
||||
// 戻り値: true:正常終了 false:失敗
|
||||
// 補足: データシートでは消去に通常 30ms 、最大400msかかると記載されている
|
||||
// アドレス23ビットのうち上位 11ビットがセクタ番号の相当する。下位12ビットはセクタ内アドレスとなる。
|
||||
//
|
||||
bool W25Q64_eraseSector(uint16_t sect_no, bool flgwait) {
|
||||
uint8_t data[4];
|
||||
int rc;
|
||||
uint32_t addr = sect_no;
|
||||
addr<<=12;
|
||||
|
||||
W25Q64_WriteEnable();
|
||||
data[0] = CMD_SECTOR_ERASE;
|
||||
data[1] = (addr>>16) & 0xff;
|
||||
data[2] = (addr>>8) & 0xff;
|
||||
data[3] = addr & 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
|
||||
// 処理待ち
|
||||
while(W25Q64_IsBusy() & flgwait) {
|
||||
delay(10);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// 64KBブロック単位消去(64kb空間単位でデータの消去を行う)
|
||||
// blk_no(in) ブロック番号(0 - 127)
|
||||
// flgwait(in) true:処理待ちを行う false:待ち無し
|
||||
// 戻り値: true:正常終了 false:失敗
|
||||
// 補足: データシートでは消去に通常 150ms 、最大1000msかかると記載されている
|
||||
// アドレス23ビットのうち上位 7ビットがブロックの相当する。下位16ビットはブロック内アドレスとなる。
|
||||
//
|
||||
bool W25Q64_erase64Block(uint16_t blk_no, bool flgwait) {
|
||||
uint8_t data[4];
|
||||
int rc;
|
||||
uint32_t addr = blk_no;
|
||||
addr<<=16;
|
||||
|
||||
W25Q64_WriteEnable();
|
||||
data[0] = CMD_BLOCK_ERASE64KB;
|
||||
data[1] = (addr>>16) & 0xff;
|
||||
data[2] = (addr>>8) & 0xff;
|
||||
data[3] = addr & 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
|
||||
// 処理待ち
|
||||
while(W25Q64_IsBusy() & flgwait) {
|
||||
delay(50);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// 32KBブロック単位消去(32kb空間単位でデータの消去を行う)
|
||||
// blk_no(in) ブロック番号(0 - 255)
|
||||
// flgwait(in) true:処理待ちを行う false:待ち無し
|
||||
// 戻り値: true:正常終了 false:失敗
|
||||
// 補足: データシートでは消去に通常 120ms 、最大800msかかると記載されている
|
||||
// アドレス23ビットのうち上位 8ビットがブロックの相当する。下位15ビットはブロック内アドレスとなる。
|
||||
//
|
||||
bool W25Q64_erase32Block(uint16_t blk_no, bool flgwait) {
|
||||
uint8_t data[4];
|
||||
int rc;
|
||||
uint32_t addr = blk_no;
|
||||
addr<<=15;
|
||||
|
||||
W25Q64_WriteEnable();
|
||||
data[0] = CMD_BLOCK_ERASE32KB;
|
||||
data[1] = (addr>>16) & 0xff;
|
||||
data[2] = (addr>>8) & 0xff;
|
||||
data[3] = addr & 0xff;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
|
||||
// 処理待ち
|
||||
while(W25Q64_IsBusy() & flgwait) {
|
||||
delay(50);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// 全領域の消去
|
||||
// flgwait(in) true:処理待ちを行う false:待ち無し
|
||||
// 戻り値: true:正常終了 false:失敗
|
||||
// 補足: データシートでは消去に通常 15s 、最大30sかかると記載されている
|
||||
//
|
||||
bool W25Q64_eraseAll(bool flgwait) {
|
||||
uint8_t data[1];
|
||||
int rc;
|
||||
|
||||
W25Q64_WriteEnable();
|
||||
data[0] = CMD_CHIP_ERASE;
|
||||
rc = wiringPiSPIDataRW (_spich,data,sizeof(data));
|
||||
|
||||
// 処理待ち
|
||||
while(W25Q64_IsBusy() & flgwait) {
|
||||
delay(500);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// データの書き込み
|
||||
// sect_no(in) : セクタ番号(0x00 - 0x7FF)
|
||||
// inaddr(in) : セクタ内アドレス(0x00-0xFFF)
|
||||
// data(in) : 書込みデータ格納アドレス
|
||||
// n(in) : 書込みバイト数(0~256)
|
||||
//
|
||||
uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, uint8_t* buf, uint8_t n) {
|
||||
// uint8_t data[4];
|
||||
uint8_t *data;
|
||||
int rc;
|
||||
|
||||
uint32_t addr = sect_no;
|
||||
int i;
|
||||
addr<<=12;
|
||||
addr += inaddr;
|
||||
|
||||
W25Q64_WriteEnable();
|
||||
|
||||
if (W25Q64_IsBusy()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = (char*)malloc(n+4);
|
||||
data[0] = CMD_PAGE_PROGRAM;
|
||||
data[1] = (addr>>16) & 0xff;
|
||||
data[2] = (addr>>8) & 0xff;
|
||||
data[3] = addr & 0xFF;
|
||||
memcpy(&data[4],buf,n);
|
||||
rc = wiringPiSPIDataRW (_spich,data,n+4);
|
||||
// spcDump("pageWrite",rc,buf,n);
|
||||
|
||||
while(W25Q64_IsBusy()) ;
|
||||
free(data);
|
||||
return rc;
|
||||
}
|
||||
36
wiringPi/w25q64.h
Normal file
36
wiringPi/w25q64.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//#include <arduino.h>
|
||||
//#include <SPI.h>
|
||||
|
||||
// フラッシュメモリ W25Q64の利用開始
|
||||
void W25Q64_begin(uint8_t cs);
|
||||
// ステータスレジスタ1の値取得
|
||||
uint8_t W25Q64_readStatusReg1(void);
|
||||
// ステータスレジスタ2の値取得
|
||||
uint8_t W25Q64_readStatusReg2();
|
||||
// JEDEC ID(Manufacture, Memory Type,Capacity)の取得
|
||||
void W25Q64_readManufacturer(uint8_t* d);
|
||||
// Unique IDの取得
|
||||
void W25Q64_readUniqieID(uint8_t* d);
|
||||
// 書込み等の処理中チェック
|
||||
bool W25Q64_IsBusy();
|
||||
// パワーダウン指定
|
||||
void W25Q64_powerDown(void);
|
||||
// 書込み許可設定
|
||||
void W25Q64_WriteEnable(void);
|
||||
// 書込み禁止設定
|
||||
void W25Q64_WriteDisable(void);
|
||||
// データの読み込み
|
||||
uint16_t W25Q64_read(uint32_t addr,uint8_t *buf,uint16_t n);
|
||||
// 高速データの読み込み
|
||||
uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n);
|
||||
// セクタ単位消去
|
||||
bool W25Q64_eraseSector(uint16_t sect_no, bool flgwait);
|
||||
// 64KBブロック単位消去
|
||||
bool W25Q64_erase64Block(uint16_t blk_no, bool flgwait);
|
||||
// 32KBブロック単位消去
|
||||
bool W25Q64_erase32Block(uint16_t blk_no, bool flgwait);
|
||||
// 全領域の消去
|
||||
bool W25Q64_eraseAll(bool flgwait);
|
||||
// データの書き込み
|
||||
uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, uint8_t* data, uint8_t n);
|
||||
|
||||
2698
wiringPi/wiringPi.c
Normal file
2698
wiringPi/wiringPi.c
Normal file
File diff suppressed because it is too large
Load Diff
283
wiringPi/wiringPi.h
Normal file
283
wiringPi/wiringPi.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* wiringPi.h:
|
||||
* Arduino like Wiring library for the Raspberry Pi.
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __WIRING_PI_H__
|
||||
#define __WIRING_PI_H__
|
||||
|
||||
// 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
|
||||
|
||||
#ifndef CONFIG_ORANGEPI
|
||||
#define PI_GPIO_MASK (0xFFFFFFC0)
|
||||
#endif
|
||||
|
||||
// Handy defines
|
||||
|
||||
#ifdef CONFIG_ORANGEPI
|
||||
#define ORANGEPI 8888
|
||||
|
||||
extern int wiringPiDebug;
|
||||
|
||||
//#define CONFIG_ORANGEPI 1
|
||||
//#define CONFIG_ORANGEPI_H3 1
|
||||
#endif
|
||||
|
||||
// wiringPi modes
|
||||
|
||||
#define WPI_MODE_PINS 0
|
||||
#define WPI_MODE_GPIO 1
|
||||
#define WPI_MODE_GPIO_SYS 2
|
||||
#define WPI_MODE_PHYS 3
|
||||
#define WPI_MODE_PIFACE 4
|
||||
#define WPI_MODE_UNINITIALISED -1
|
||||
|
||||
// Pin modes
|
||||
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
#define PWM_OUTPUT 2
|
||||
#define GPIO_CLOCK 3
|
||||
#define SOFT_PWM_OUTPUT 4
|
||||
#define SOFT_TONE_OUTPUT 5
|
||||
#define PWM_TONE_OUTPUT 6
|
||||
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
// Pull up/down/none
|
||||
|
||||
#define PUD_OFF 0
|
||||
#define PUD_DOWN 1
|
||||
#define PUD_UP 2
|
||||
|
||||
// PWM
|
||||
|
||||
#define PWM_MODE_MS 0
|
||||
#define PWM_MODE_BAL 1
|
||||
|
||||
// Interrupt levels
|
||||
|
||||
#define INT_EDGE_SETUP 0
|
||||
#define INT_EDGE_FALLING 1
|
||||
#define INT_EDGE_RISING 2
|
||||
#define INT_EDGE_BOTH 3
|
||||
|
||||
// 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_CM3 10
|
||||
#define PI_MODEL_ZERO_W 12
|
||||
#define PI_MODEL_3P 13
|
||||
#define PI_MODEL_ORANGEPI 14
|
||||
|
||||
#define PI_VERSION_1 0
|
||||
#define PI_VERSION_1_1 1
|
||||
#define PI_VERSION_1_2 2
|
||||
#define PI_VERSION_2 3
|
||||
|
||||
#define PI_MAKER_SONY 0
|
||||
#define PI_MAKER_EGOMAN 1
|
||||
#define PI_MAKER_EMBEST 2
|
||||
#define PI_MAKER_UNKNOWN 3
|
||||
|
||||
#ifndef CONFIG_ORANGEPI
|
||||
extern const char *piModelNames [16] ;
|
||||
#endif
|
||||
|
||||
extern const char *piRevisionNames [16] ;
|
||||
extern const char *piMakerNames [16] ;
|
||||
extern const int piMemorySize [ 8] ;
|
||||
|
||||
|
||||
// Intended for the GPIO program Use at your own risk.
|
||||
|
||||
// Threads
|
||||
|
||||
#define PI_THREAD(X) void *X (UNU void *dummy)
|
||||
|
||||
// Failure modes
|
||||
|
||||
#define WPI_FATAL (1==1)
|
||||
#define WPI_ALMOST (1==2)
|
||||
|
||||
|
||||
// wiringPiNodeStruct:
|
||||
// This describes additional device nodes in the extended wiringPi
|
||||
// 2.0 scheme of things.
|
||||
// It's a simple linked list for now, but will hopefully migrate to
|
||||
// a binary tree for efficiency reasons - but then again, the chances
|
||||
// of more than 1 or 2 devices being added are fairly slim, so who
|
||||
// knows....
|
||||
|
||||
struct wiringPiNodeStruct
|
||||
{
|
||||
int pinBase ;
|
||||
int pinMax ;
|
||||
|
||||
int fd ; // Node specific
|
||||
unsigned int data0 ; // ditto
|
||||
unsigned int data1 ; // ditto
|
||||
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) ;
|
||||
//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
|
||||
// (and others on the Raspberry Pi forums)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Data
|
||||
|
||||
// Internal
|
||||
|
||||
#ifdef CONFIG_ORANGEPI
|
||||
extern void piGpioLayoutOops (const char *why);
|
||||
#endif
|
||||
|
||||
extern int wiringPiFailure (int fatal, const char *message, ...) ;
|
||||
|
||||
// Core wiringPi functions
|
||||
|
||||
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 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)
|
||||
|
||||
extern int wiringPiSetupPiFace (void) ;
|
||||
extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only
|
||||
|
||||
// On-Board Raspberry Pi hardware specific stuff
|
||||
|
||||
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 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)
|
||||
|
||||
extern int waitForInterrupt (int pin, int mS) ;
|
||||
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
|
||||
|
||||
// Threads
|
||||
|
||||
extern int piThreadCreate (void *(*fn)(void *)) ;
|
||||
extern void piLock (int key) ;
|
||||
extern void piUnlock (int key) ;
|
||||
|
||||
// Schedulling priority
|
||||
|
||||
extern int piHiPri (const int pri) ;
|
||||
|
||||
// Extras from arduino land
|
||||
|
||||
extern void delay (unsigned int howLong) ;
|
||||
extern void delayMicroseconds (unsigned int howLong) ;
|
||||
extern unsigned int millis (void) ;
|
||||
extern unsigned int micros (void) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
233
wiringPi/wiringPiI2C.c
Normal file
233
wiringPi/wiringPiI2C.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* wiringPiI2C.c:
|
||||
* Simplified I2C access routines
|
||||
* Copyright (c) 2013 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Notes:
|
||||
* The Linux I2C code is actually the same (almost) as the SMBus code.
|
||||
* SMBus is System Management Bus - and in essentially I2C with some
|
||||
* additional functionality added, and stricter controls on the electrical
|
||||
* specifications, etc. however I2C does work well with it and the
|
||||
* protocols work over both.
|
||||
*
|
||||
* I'm directly including the SMBus functions here as some Linux distros
|
||||
* lack the correct header files, and also some header files are GPLv2
|
||||
* rather than the LGPL that wiringPi is released under - presumably because
|
||||
* originally no-one expected I2C/SMBus to be used outside the kernel -
|
||||
* however enter the Raspberry Pi with people now taking directly to I2C
|
||||
* devices without going via the kernel...
|
||||
*
|
||||
* This may ultimately reduce the flexibility of this code, but it won't be
|
||||
* hard to maintain it and keep it current, should things change.
|
||||
*
|
||||
* Information here gained from: kernel/Documentation/i2c/dev-interface
|
||||
* as well as other online resources.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <asm/ioctl.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringPiI2C.h"
|
||||
|
||||
// I2C definitions
|
||||
|
||||
#define I2C_SLAVE 0x0703
|
||||
#define I2C_SMBUS 0x0720 /* SMBus-level access */
|
||||
|
||||
#define I2C_SMBUS_READ 1
|
||||
#define I2C_SMBUS_WRITE 0
|
||||
|
||||
// SMBus transaction types
|
||||
|
||||
#define I2C_SMBUS_QUICK 0
|
||||
#define I2C_SMBUS_BYTE 1
|
||||
#define I2C_SMBUS_BYTE_DATA 2
|
||||
#define I2C_SMBUS_WORD_DATA 3
|
||||
#define I2C_SMBUS_PROC_CALL 4
|
||||
#define I2C_SMBUS_BLOCK_DATA 5
|
||||
#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
|
||||
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
|
||||
#define I2C_SMBUS_I2C_BLOCK_DATA 8
|
||||
|
||||
// SMBus messages
|
||||
|
||||
#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
|
||||
#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
|
||||
|
||||
// Structures used in the ioctl() calls
|
||||
|
||||
union i2c_smbus_data
|
||||
{
|
||||
uint8_t byte ;
|
||||
uint16_t word ;
|
||||
uint8_t block [I2C_SMBUS_BLOCK_MAX + 2] ; // block [0] is used for length + one more for PEC
|
||||
} ;
|
||||
|
||||
struct i2c_smbus_ioctl_data
|
||||
{
|
||||
char read_write ;
|
||||
uint8_t command ;
|
||||
int size ;
|
||||
union i2c_smbus_data *data ;
|
||||
} ;
|
||||
|
||||
static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data)
|
||||
{
|
||||
struct i2c_smbus_ioctl_data args ;
|
||||
|
||||
args.read_write = rw ;
|
||||
args.command = command ;
|
||||
args.size = size ;
|
||||
args.data = data ;
|
||||
return ioctl (fd, I2C_SMBUS, &args) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CRead:
|
||||
* Simple device read
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CRead (int fd)
|
||||
{
|
||||
union i2c_smbus_data data ;
|
||||
|
||||
if (i2c_smbus_access (fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data))
|
||||
return -1 ;
|
||||
else
|
||||
return data.byte & 0xFF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CReadReg8: wiringPiI2CReadReg16:
|
||||
* Read an 8 or 16-bit value from a regsiter on the device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CReadReg8 (int fd, int reg)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
|
||||
if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data))
|
||||
return -1 ;
|
||||
else
|
||||
return data.byte & 0xFF ;
|
||||
}
|
||||
|
||||
int wiringPiI2CReadReg16 (int fd, int reg)
|
||||
{
|
||||
union i2c_smbus_data data;
|
||||
|
||||
if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data))
|
||||
return -1 ;
|
||||
else
|
||||
return data.word & 0xFFFF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CWrite:
|
||||
* Simple device write
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CWrite (int fd, int data)
|
||||
{
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CWriteReg8: wiringPiI2CWriteReg16:
|
||||
* Write an 8 or 16-bit value to the given register
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CWriteReg8 (int fd, int reg, int value)
|
||||
{
|
||||
union i2c_smbus_data data ;
|
||||
|
||||
data.byte = value ;
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ;
|
||||
}
|
||||
|
||||
int wiringPiI2CWriteReg16 (int fd, int reg, int value)
|
||||
{
|
||||
union i2c_smbus_data data ;
|
||||
|
||||
data.word = value ;
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CSetupInterface:
|
||||
* Undocumented access to set the interface explicitly - might be used
|
||||
* for the Pi's 2nd I2C interface...
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CSetupInterface (const char *device, int devId)
|
||||
{
|
||||
int fd ;
|
||||
|
||||
if ((fd = open (device, O_RDWR)) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ;
|
||||
|
||||
if (ioctl (fd, I2C_SLAVE, devId) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "Unable to select I2C device: %s\n", strerror (errno)) ;
|
||||
|
||||
return fd ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiI2CSetup:
|
||||
* Open the I2C device, and regsiter the target device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CSetup (const int devId)
|
||||
{
|
||||
int rev ;
|
||||
const char *device ;
|
||||
|
||||
rev = piGpioLayout () ;
|
||||
|
||||
if (rev == 1)
|
||||
device = "/dev/i2c-0" ;
|
||||
else
|
||||
device = "/dev/i2c-1" ;
|
||||
|
||||
return wiringPiI2CSetupInterface (device, devId) ;
|
||||
}
|
||||
42
wiringPi/wiringPiI2C.h
Normal file
42
wiringPi/wiringPiI2C.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* wiringPiI2C.h:
|
||||
* Simplified I2C access routines
|
||||
* Copyright (c) 2013 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 wiringPiI2CRead (int fd) ;
|
||||
extern int wiringPiI2CReadReg8 (int fd, int reg) ;
|
||||
extern int wiringPiI2CReadReg16 (int fd, int reg) ;
|
||||
|
||||
extern int wiringPiI2CWrite (int fd, int data) ;
|
||||
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
|
||||
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
|
||||
|
||||
extern int wiringPiI2CSetupInterface (const char *device, int devId) ;
|
||||
extern int wiringPiI2CSetup (const int devId) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
145
wiringPi/wiringPiSPI.c
Normal file
145
wiringPi/wiringPiSPI.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* wiringPiSPI.c:
|
||||
* Simplified SPI access routines
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <asm/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
#include "wiringPiSPI.h"
|
||||
|
||||
|
||||
// The SPI bus parameters
|
||||
// Variables as they need to be passed as pointers later on
|
||||
|
||||
static const uint8_t spiBPW = 8 ;
|
||||
static const uint16_t spiDelay = 0 ;
|
||||
|
||||
static uint32_t spiSpeeds [2] ;
|
||||
static int spiFds [2] ;
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSPIGetFd:
|
||||
* Return the file-descriptor for the given channel
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiSPIGetFd (int channel)
|
||||
{
|
||||
return spiFds [channel & 1] ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSPIDataRW:
|
||||
* Write and Read a block of data over the SPI bus.
|
||||
* Note the data ia being read into the transmit buffer, so will
|
||||
* overwrite it!
|
||||
* This is also a full-duplex operation.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
|
||||
{
|
||||
struct spi_ioc_transfer spi ;
|
||||
|
||||
channel &= 1 ;
|
||||
|
||||
// Mentioned in spidev.h but not used in the original kernel documentation
|
||||
// test program )-:
|
||||
|
||||
memset (&spi, 0, sizeof (spi)) ;
|
||||
|
||||
spi.tx_buf = (unsigned long)data ;
|
||||
spi.rx_buf = (unsigned long)data ;
|
||||
spi.len = len ;
|
||||
spi.delay_usecs = spiDelay ;
|
||||
spi.speed_hz = spiSpeeds [channel] ;
|
||||
spi.bits_per_word = spiBPW ;
|
||||
|
||||
return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSPISetupMode:
|
||||
* Open the SPI device, and set it up, with the mode, etc.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void getDevice(char* spidev, int channel, int port) {
|
||||
sprintf(spidev, "/dev/spidev%i.%i", channel, port);
|
||||
}
|
||||
|
||||
int wiringPiSPISetupMode (int channel, int port, int speed, int mode)
|
||||
{
|
||||
int fd ;
|
||||
|
||||
mode &= 3 ; // Mode is 0, 1, 2 or 3
|
||||
channel &= 1 ; // Channel is 0 or 1
|
||||
|
||||
static char spidev[14];
|
||||
|
||||
getDevice(spidev, channel, port);
|
||||
printf("Opening device %s\n", spidev);
|
||||
|
||||
if ((fd = open (spidev, O_RDWR)) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ;
|
||||
|
||||
spiSpeeds [channel] = speed ;
|
||||
spiFds [channel] = fd ;
|
||||
|
||||
// Set SPI parameters.
|
||||
|
||||
if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ;
|
||||
|
||||
if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "SPI BPW Change failure: %s\n", strerror (errno)) ;
|
||||
|
||||
if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ;
|
||||
|
||||
return fd ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSPISetup:
|
||||
* Open the SPI device, and set it up, etc. in the default MODE 0
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiSPISetup (int channel, int speed)
|
||||
{
|
||||
return wiringPiSPISetupMode (channel, 0, speed, 0) ;
|
||||
}
|
||||
36
wiringPi/wiringPiSPI.h
Normal file
36
wiringPi/wiringPiSPI.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* wiringPiSPI.h:
|
||||
* Simplified SPI access routines
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int wiringPiSPIGetFd (int channel) ;
|
||||
int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
|
||||
int wiringPiSPISetupMode (int channel, int port, int speed, int mode) ;
|
||||
int wiringPiSPISetup (int channel, int speed) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
231
wiringPi/wiringSerial.c
Normal file
231
wiringPi/wiringSerial.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* wiringSerial.c:
|
||||
* Handle a serial port
|
||||
***********************************************************************
|
||||
* 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 <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "wiringSerial.h"
|
||||
|
||||
/*
|
||||
* serialOpen:
|
||||
* Open and initialise the serial port, setting all the right
|
||||
* port parameters - or as many as are required - hopefully!
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialOpen (const char *device, const int baud)
|
||||
{
|
||||
struct termios options ;
|
||||
speed_t myBaud ;
|
||||
int status, fd ;
|
||||
|
||||
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 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 ;
|
||||
}
|
||||
|
||||
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
|
||||
return -1 ;
|
||||
|
||||
fcntl (fd, F_SETFL, O_RDWR) ;
|
||||
|
||||
// Get and modify current options:
|
||||
|
||||
tcgetattr (fd, &options) ;
|
||||
|
||||
cfmakeraw (&options) ;
|
||||
cfsetispeed (&options, myBaud) ;
|
||||
cfsetospeed (&options, myBaud) ;
|
||||
|
||||
options.c_cflag |= (CLOCAL | CREAD) ;
|
||||
options.c_cflag &= ~PARENB ;
|
||||
options.c_cflag &= ~CSTOPB ;
|
||||
options.c_cflag &= ~CSIZE ;
|
||||
options.c_cflag |= CS8 ;
|
||||
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
|
||||
options.c_oflag &= ~OPOST ;
|
||||
|
||||
options.c_cc [VMIN] = 0 ;
|
||||
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
|
||||
|
||||
tcsetattr (fd, TCSANOW, &options) ;
|
||||
|
||||
ioctl (fd, TIOCMGET, &status);
|
||||
|
||||
status |= TIOCM_DTR ;
|
||||
status |= TIOCM_RTS ;
|
||||
|
||||
ioctl (fd, TIOCMSET, &status);
|
||||
|
||||
usleep (10000) ; // 10mS
|
||||
|
||||
return fd ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialFlush:
|
||||
* Flush the serial buffers (both tx & rx)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialFlush (const int fd)
|
||||
{
|
||||
tcflush (fd, TCIOFLUSH) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialClose:
|
||||
* Release the serial port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialClose (const int fd)
|
||||
{
|
||||
close (fd) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialPutchar:
|
||||
* Send a single character to the serial port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPutchar (const int fd, const unsigned char c)
|
||||
{
|
||||
int ret;
|
||||
ret = write (fd, &c, 1) ;
|
||||
if (ret < 0)
|
||||
printf("Serial Putchar Error\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialPuts:
|
||||
* Send a string to the serial port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPuts (const int fd, const char *s)
|
||||
{
|
||||
int ret;
|
||||
ret = write (fd, s, strlen (s));
|
||||
if (ret < 0)
|
||||
printf("Serial Puts Error\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* serialPrintf:
|
||||
* Printf over Serial
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPrintf (const int fd, const char *message, ...)
|
||||
{
|
||||
va_list argp ;
|
||||
char buffer [1024] ;
|
||||
|
||||
va_start (argp, message) ;
|
||||
vsnprintf (buffer, 1023, message, argp) ;
|
||||
va_end (argp) ;
|
||||
|
||||
serialPuts (fd, buffer) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialDataAvail:
|
||||
* Return the number of bytes of data avalable to be read in the serial port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialDataAvail (const int fd)
|
||||
{
|
||||
int result ;
|
||||
|
||||
if (ioctl (fd, FIONREAD, &result) == -1)
|
||||
return -1 ;
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* serialGetchar:
|
||||
* Get a single character from the serial device.
|
||||
* Note: Zero is a valid character and this function will time-out after
|
||||
* 10 seconds.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialGetchar (const int fd)
|
||||
{
|
||||
uint8_t x ;
|
||||
|
||||
if (read (fd, &x, 1) != 1)
|
||||
return -1 ;
|
||||
|
||||
return ((int)x) & 0xFF ;
|
||||
}
|
||||
38
wiringPi/wiringSerial.h
Normal file
38
wiringPi/wiringSerial.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* wiringSerial.h:
|
||||
* Handle a serial port
|
||||
***********************************************************************
|
||||
* 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 serialOpen (const char *device, const int baud) ;
|
||||
extern void serialClose (const int fd) ;
|
||||
extern void serialFlush (const int fd) ;
|
||||
extern void serialPutchar (const int fd, const unsigned char c) ;
|
||||
extern void serialPuts (const int fd, const char *s) ;
|
||||
extern void serialPrintf (const int fd, const char *message, ...) ;
|
||||
extern int serialDataAvail (const int fd) ;
|
||||
extern int serialGetchar (const int fd) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
83
wiringPi/wiringShift.c
Normal file
83
wiringPi/wiringShift.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* wiringShift.c:
|
||||
* Emulate some of the Arduino wiring functionality.
|
||||
*
|
||||
* Copyright (c) 2009-2012 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 <stdint.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringShift.h"
|
||||
|
||||
/*
|
||||
* shiftIn:
|
||||
* Shift data in from a clocked source
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order)
|
||||
{
|
||||
uint8_t value = 0 ;
|
||||
int8_t i ;
|
||||
|
||||
if (order == MSBFIRST)
|
||||
for (i = 7 ; i >= 0 ; --i)
|
||||
{
|
||||
digitalWrite (cPin, HIGH) ;
|
||||
value |= digitalRead (dPin) << i ;
|
||||
digitalWrite (cPin, LOW) ;
|
||||
}
|
||||
else
|
||||
for (i = 0 ; i < 8 ; ++i)
|
||||
{
|
||||
digitalWrite (cPin, HIGH) ;
|
||||
value |= digitalRead (dPin) << i ;
|
||||
digitalWrite (cPin, LOW) ;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* shiftOut:
|
||||
* Shift data out to a clocked source
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val)
|
||||
{
|
||||
int8_t i;
|
||||
|
||||
if (order == MSBFIRST)
|
||||
for (i = 7 ; i >= 0 ; --i)
|
||||
{
|
||||
digitalWrite (dPin, val & (1 << i)) ;
|
||||
digitalWrite (cPin, HIGH) ;
|
||||
digitalWrite (cPin, LOW) ;
|
||||
}
|
||||
else
|
||||
for (i = 0 ; i < 8 ; ++i)
|
||||
{
|
||||
digitalWrite (dPin, val & (1 << i)) ;
|
||||
digitalWrite (cPin, HIGH) ;
|
||||
digitalWrite (cPin, LOW) ;
|
||||
}
|
||||
}
|
||||
41
wiringPi/wiringShift.h
Normal file
41
wiringPi/wiringShift.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* wiringShift.h:
|
||||
* Emulate some of the Arduino wiring functionality.
|
||||
*
|
||||
* Copyright (c) 2009-2012 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 LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
|
||||
#ifndef _STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ;
|
||||
extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
928
wiringPi/wpiExtensions.c
Normal file
928
wiringPi/wpiExtensions.c
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* extensions.c:
|
||||
* Originally part of the GPIO program to test, peek, poke and otherwise
|
||||
* noodle with the GPIO hardware on the Raspberry Pi.
|
||||
* Now used as a general purpose library to allow systems to dynamically
|
||||
* add in new devices into wiringPi at program run-time.
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
|
||||
#include "mcp23008.h"
|
||||
#include "mcp23016.h"
|
||||
#include "mcp23017.h"
|
||||
#include "mcp23s08.h"
|
||||
#include "mcp23s17.h"
|
||||
#include "sr595.h"
|
||||
#include "pcf8574.h"
|
||||
#include "pcf8591.h"
|
||||
#include "mcp3002.h"
|
||||
#include "mcp3004.h"
|
||||
#include "mcp4802.h"
|
||||
#include "mcp3422.h"
|
||||
#include "max31855.h"
|
||||
#include "max5322.h"
|
||||
#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"
|
||||
|
||||
extern int wiringPiDebug ;
|
||||
|
||||
static int verbose ;
|
||||
static char errorMessage [1024] ;
|
||||
|
||||
|
||||
// Local structure to hold details
|
||||
|
||||
struct extensionFunctionStruct
|
||||
{
|
||||
const char *name ;
|
||||
int (*function)(char *progName, int pinBase, char *params) ;
|
||||
} ;
|
||||
|
||||
|
||||
/*
|
||||
* verbError:
|
||||
* Convenient error handling
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void verbError (const char *message, ...)
|
||||
{
|
||||
va_list argp ;
|
||||
va_start (argp, message) ;
|
||||
vsnprintf (errorMessage, 1023, message, argp) ;
|
||||
va_end (argp) ;
|
||||
|
||||
if (verbose)
|
||||
fprintf (stderr, "%s\n", errorMessage) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* extractInt:
|
||||
* Check & return an integer at the given location (prefixed by a :)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static char *extractInt (char *progName, char *p, int *num)
|
||||
{
|
||||
if (*p != ':')
|
||||
{
|
||||
verbError ("%s: colon expected", progName) ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
++p ;
|
||||
|
||||
if (!isdigit (*p))
|
||||
{
|
||||
verbError ("%s: digit expected", progName) ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
*num = strtol (p, NULL, 0) ;
|
||||
|
||||
// Increment p, but we need to check for hex 0x
|
||||
|
||||
if ((*p == '0') && (*(p + 1) == 'x'))
|
||||
p +=2 ;
|
||||
|
||||
while (isxdigit (*p))
|
||||
++p ;
|
||||
|
||||
return p ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 != ':')
|
||||
{
|
||||
verbError ("%s: colon expected", progName) ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
++p ;
|
||||
|
||||
if (*p == '[')
|
||||
{
|
||||
quoted = TRUE ;
|
||||
++p ;
|
||||
}
|
||||
|
||||
if (!isprint (*p)) // Is this needed?
|
||||
{
|
||||
verbError ("%s: character expected", progName) ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
q = p ;
|
||||
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 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp23008:
|
||||
* MCP23008 - 8-bit I2C GPIO expansion chip
|
||||
* mcp23002:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x01) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp23008Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp23016:
|
||||
* MCP230016- 16-bit I2C GPIO expansion chip
|
||||
* mcp23016:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp23016Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp23017:
|
||||
* MCP230017- 16-bit I2C GPIO expansion chip
|
||||
* mcp23017:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp23017Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp23s08:
|
||||
* MCP23s08 - 8-bit SPI GPIO expansion chip
|
||||
* mcp23s08:base:spi:port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi, port ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI address (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &port)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((port < 0) || (port > 7))
|
||||
{
|
||||
verbError ("%s: port address (%d) out of range", progName, port) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp23s08Setup (pinBase, spi, port) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp23s17:
|
||||
* MCP23s17 - 16-bit SPI GPIO expansion chip
|
||||
* mcp23s17:base:spi:port
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi, port ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI address (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &port)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((port < 0) || (port > 7))
|
||||
{
|
||||
verbError ("%s: port address (%d) out of range", progName, port) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp23s17Setup (pinBase, spi, port) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionSr595:
|
||||
* Shift Register 74x595
|
||||
* sr595:base:pins:data:clock:latch
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionSr595 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int pins, data, clock, latch ;
|
||||
|
||||
// Extract pins
|
||||
|
||||
if ((params = extractInt (progName, params, &pins)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((pins < 8) || (pins > 32))
|
||||
{
|
||||
verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &data)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((params = extractInt (progName, params, &clock)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((params = extractInt (progName, params, &latch)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
sr595Setup (pinBase, pins, data, clock, latch) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionPcf8574:
|
||||
* Digital IO (Crude!)
|
||||
* pcf8574:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
pcf8574Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionAds1115:
|
||||
* Analog Input
|
||||
* ads1115:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionAds1115 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
ads1115Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionPcf8591:
|
||||
* Analog IO
|
||||
* pcf8591:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
pcf8591Setup (pinBase, i2c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMax31855 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
max31855Setup (pinBase, spi) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp3002:
|
||||
* Analog IO
|
||||
* mcp3002:base:spiChan
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp3002Setup (pinBase, spi) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp3004:
|
||||
* Analog IO
|
||||
* mcp3004:base:spiChan
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp3004Setup (pinBase, spi) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMax5322:
|
||||
* Analog O
|
||||
* max5322:base:spiChan
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMax5322 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
max5322Setup (pinBase, spi) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp4802:
|
||||
* Analog IO
|
||||
* mcp4802:base:spiChan
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int spi ;
|
||||
|
||||
if ((params = extractInt (progName, params, &spi)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((spi < 0) || (spi > 1))
|
||||
{
|
||||
verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp4802Setup (pinBase, spi) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionSn3218:
|
||||
* Analog Output (LED Driver)
|
||||
* sn3218:base
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params)
|
||||
{
|
||||
sn3218Setup (pinBase) ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionMcp3422:
|
||||
* Analog IO
|
||||
* mcp3422:base:i2cAddr
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
|
||||
{
|
||||
int i2c, sampleRate, gain ;
|
||||
|
||||
if ((params = extractInt (progName, params, &i2c)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((i2c < 0x03) || (i2c > 0x77))
|
||||
{
|
||||
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &sampleRate)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((sampleRate < 0) || (sampleRate > 3))
|
||||
{
|
||||
verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &gain)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((gain < 0) || (gain > 3))
|
||||
{
|
||||
verbError ("%s: gain (%d) out of range", progName, gain) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* doExtensionDrcS:
|
||||
* Interface to a DRC Serial system
|
||||
* drcs:base:pins:serialPort:baud
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int doExtensionDrcS (char *progName, int pinBase, char *params)
|
||||
{
|
||||
char *port ;
|
||||
int pins, baud ;
|
||||
|
||||
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, &port)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if (strlen (port) == 0)
|
||||
{
|
||||
verbError ("%s: serial port device name required", progName) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
if ((params = extractInt (progName, params, &baud)) == NULL)
|
||||
return FALSE ;
|
||||
|
||||
if ((baud < 1) || (baud > 4000000))
|
||||
{
|
||||
verbError ("%s: baud rate (%d) out of range", progName, baud) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
drcSetupSerial (pinBase, pins, port, baud) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static struct extensionFunctionStruct extensionFunctions [] =
|
||||
{
|
||||
{ "mcp23008", &doExtensionMcp23008 },
|
||||
{ "mcp23016", &doExtensionMcp23016 },
|
||||
{ "mcp23017", &doExtensionMcp23017 },
|
||||
{ "mcp23s08", &doExtensionMcp23s08 },
|
||||
{ "mcp23s17", &doExtensionMcp23s17 },
|
||||
{ "sr595", &doExtensionSr595 },
|
||||
{ "pcf8574", &doExtensionPcf8574 },
|
||||
{ "pcf8591", &doExtensionPcf8591 },
|
||||
{ "bmp180", &doExtensionBmp180 },
|
||||
{ "pseudoPins", &doExtensionPseudoPins },
|
||||
{ "htu21d", &doExtensionHtu21d },
|
||||
{ "ds18b20", &doExtensionDs18b20 },
|
||||
{ "rht03", &doExtensionRht03 },
|
||||
{ "mcp3002", &doExtensionMcp3002 },
|
||||
{ "mcp3004", &doExtensionMcp3004 },
|
||||
{ "mcp4802", &doExtensionMcp4802 },
|
||||
{ "mcp3422", &doExtensionMcp3422 },
|
||||
{ "max31855", &doExtensionMax31855 },
|
||||
{ "ads1115", &doExtensionAds1115 },
|
||||
{ "max5322", &doExtensionMax5322 },
|
||||
{ "sn3218", &doExtensionSn3218 },
|
||||
{ "drcs", &doExtensionDrcS },
|
||||
{ "drcn", &doExtensionDrcNet },
|
||||
{ NULL, NULL },
|
||||
} ;
|
||||
|
||||
|
||||
/*
|
||||
* loadWPiExtension:
|
||||
* Load in a wiringPi extension
|
||||
* The extensionData always starts with the name, a colon then the pinBase
|
||||
* number. Other parameters after that are decoded by the module in question.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int loadWPiExtension (char *progName, char *extensionData, int printErrors)
|
||||
{
|
||||
char *p ;
|
||||
char *extension = extensionData ;
|
||||
struct extensionFunctionStruct *extensionFn ;
|
||||
int pinBase = 0 ;
|
||||
|
||||
verbose = printErrors ;
|
||||
|
||||
// Get the extension name by finding the first colon
|
||||
|
||||
p = extension ;
|
||||
while (*p != ':')
|
||||
{
|
||||
if (!*p) // ran out of characters
|
||||
{
|
||||
verbError ("%s: extension name not terminated by a colon", progName) ;
|
||||
return FALSE ;
|
||||
}
|
||||
++p ;
|
||||
}
|
||||
*p++ = 0 ;
|
||||
|
||||
// Simple ATOI code
|
||||
|
||||
if (!isdigit (*p))
|
||||
{
|
||||
verbError ("%s: decimal pinBase number expected after extension name", progName) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
while (isdigit (*p))
|
||||
{
|
||||
if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here...
|
||||
{
|
||||
verbError ("%s: pinBase too large", progName) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
pinBase = pinBase * 10 + (*p - '0') ;
|
||||
++p ;
|
||||
}
|
||||
|
||||
if (pinBase < 64)
|
||||
{
|
||||
verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
// Search for extensions:
|
||||
|
||||
for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
|
||||
{
|
||||
if (strcmp (extensionFn->name, extension) == 0)
|
||||
return extensionFn->function (progName, pinBase, p) ;
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s: extension %s not found", progName, extension) ;
|
||||
return FALSE ;
|
||||
}
|
||||
26
wiringPi/wpiExtensions.h
Normal file
26
wiringPi/wpiExtensions.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* extensions.h:
|
||||
* Part of the GPIO program to test, peek, poke and otherwise
|
||||
* noodle with the GPIO hardware on 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ;
|
||||
Reference in New Issue
Block a user