mirror of
https://github.com/clockworkpi/WiringPi.git
synced 2026-03-21 11:22:44 +01:00
wiringPi Version 2 - First commit (of v2)
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
|
||||
#################################################################################
|
||||
|
||||
DYN_VERS_MAJ=1
|
||||
DYN_VERS_MAJ=2
|
||||
DYN_VERS_MIN=0
|
||||
|
||||
VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
|
||||
@@ -35,26 +35,25 @@ DYNAMIC=libwiringPi.so.$(VERSION)
|
||||
DEBUG = -O2
|
||||
CC = gcc
|
||||
INCLUDE = -I.
|
||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC
|
||||
CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC
|
||||
|
||||
LIBS =
|
||||
|
||||
# Should not alter anything below this line
|
||||
###############################################################################
|
||||
|
||||
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
|
||||
gertboard.c \
|
||||
piNes.c \
|
||||
lcd.c piHiPri.c piThread.c \
|
||||
wiringPiSPI.c \
|
||||
softPwm.c softServo.c softTone.c
|
||||
|
||||
SRC_I2C = wiringPiI2C.c
|
||||
SRC = wiringPi.c \
|
||||
wiringSerial.c wiringShift.c \
|
||||
piHiPri.c piThread.c \
|
||||
wiringPiSPI.c wiringPiI2C.c \
|
||||
softPwm.c softTone.c \
|
||||
mcp23s08.c mcp23008.c \
|
||||
mcp23s17.c mcp23017.c sr595.c pcf8574.c \
|
||||
mcp3002.c mcp4802.c mcp3422.c \
|
||||
drc.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
OBJ_I2C = $(SRC_I2C:.c=.o)
|
||||
|
||||
all: $(DYNAMIC)
|
||||
|
||||
static: $(STATIC)
|
||||
@@ -67,11 +66,7 @@ $(STATIC): $(OBJ)
|
||||
|
||||
$(DYNAMIC): $(OBJ)
|
||||
@echo "[Link (Dynamic)]"
|
||||
@$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)
|
||||
|
||||
i2c: $(OBJ) $(OBJ_I2C)
|
||||
@echo "[Link (Dynamic + I2C)]"
|
||||
@$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C)
|
||||
@$(CC) -shared -Wl,-soname,libwiringPi.so -o libwiringPi.so.$(VERSION) -lpthread $(OBJ)
|
||||
|
||||
.c.o:
|
||||
@echo [Compile] $<
|
||||
@@ -79,37 +74,48 @@ i2c: $(OBJ) $(OBJ_I2C)
|
||||
|
||||
.PHONEY: clean
|
||||
clean:
|
||||
rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
|
||||
@echo "[Clean]"
|
||||
@rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
|
||||
|
||||
.PHONEY: tags
|
||||
tags: $(SRC)
|
||||
@echo [ctags]
|
||||
@ctags $(SRC)
|
||||
|
||||
.PHONEY: install
|
||||
install: $(DYNAMIC)
|
||||
@echo "[Install]"
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
|
||||
|
||||
.PHONEY: install-headers
|
||||
install-headers:
|
||||
@echo "[Install Headers]"
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringShift.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softPwm.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
|
||||
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
|
||||
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1
|
||||
@install -m 0644 mcp23008.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp23017.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp23s08.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp23s17.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp3002.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp4802.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 mcp3422.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 sr595.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 pcf8574.h $(DESTDIR)$(PREFIX)/include
|
||||
|
||||
.PHONEY: install
|
||||
install: $(DYNAMIC) install-headers
|
||||
@echo "[Install Dynamic Lib]"
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
|
||||
@install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
|
||||
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
|
||||
@ldconfig
|
||||
|
||||
.PHONEY: install-static
|
||||
install-static: $(STATIC)
|
||||
@echo "[Install Static]"
|
||||
install-static: $(STATIC) install-headers
|
||||
@echo "[Install Static Lib]"
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
|
||||
@install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib
|
||||
|
||||
.PHONEY: uninstall
|
||||
@@ -118,14 +124,19 @@ uninstall:
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softTone.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp23008.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp23017.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp23s08.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp23s17.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp3002.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp4802.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/mcp3422.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/sr595.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/pcf8574.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
|
||||
@ldconfig
|
||||
|
||||
@@ -137,16 +148,21 @@ depend:
|
||||
# DO NOT DELETE
|
||||
|
||||
wiringPi.o: wiringPi.h
|
||||
wiringPiFace.o: wiringPi.h
|
||||
wiringSerial.o: wiringSerial.h
|
||||
wiringShift.o: wiringPi.h wiringShift.h
|
||||
gertboard.o: wiringPiSPI.h gertboard.h
|
||||
piNes.o: wiringPi.h piNes.h
|
||||
lcd.o: wiringPi.h lcd.h
|
||||
piHiPri.o: wiringPi.h
|
||||
piThread.o: wiringPi.h
|
||||
wiringPiSPI.o: wiringPiSPI.h
|
||||
softPwm.o: wiringPi.h softPwm.h
|
||||
softServo.o: wiringPi.h softServo.h
|
||||
softTone.o: wiringPi.h softTone.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
|
||||
mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
|
||||
mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h
|
||||
mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
|
||||
mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h
|
||||
sr595.o: wiringPi.h sr595.h
|
||||
pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h
|
||||
mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h
|
||||
mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
|
||||
mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h
|
||||
drc.o: wiringPi.h wiringSerial.h drc.h
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
WiringPi: An implementation of most of the Arduino Wiring
|
||||
functions for the Raspberry Pi,
|
||||
along with many more features and libraries to support
|
||||
hardware, etc. on the Raspberry Pi
|
||||
|
||||
Full details at:
|
||||
https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
|
||||
203
wiringPi/drc.c
Normal file
203
wiringPi/drc.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* drc.c:
|
||||
* Extend wiringPi with the DRC control protocll 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "wiringSerial.h"
|
||||
|
||||
#include "drc.h"
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE (1==1)
|
||||
# define FALSE (1==2)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 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) ;
|
||||
|
||||
/**/ 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 drcSetup (const int pinBase, const int numPins, const char *device)
|
||||
{
|
||||
int fd ;
|
||||
int ok, tries ;
|
||||
time_t then ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = serialOpen (device, 115200)) < 0)
|
||||
return wiringPiFailure (WPI_ALMOST, "Unable to open DRC device (%s): %s", device, strerror (errno)) ;
|
||||
|
||||
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 ; ++tries)
|
||||
{
|
||||
serialPutchar (fd, '@') ;
|
||||
then = time (NULL) + 2 ;
|
||||
while (time (NULL) < then)
|
||||
if (serialDataAvail (fd))
|
||||
{
|
||||
if (serialGetchar (fd) == '@')
|
||||
{
|
||||
ok = TRUE ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
break ;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
serialClose (fd) ;
|
||||
return wiringPiFailure (WPI_FATAL, "Unable to communidate with DRC device") ;
|
||||
}
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
/*
|
||||
* gertboard.h:
|
||||
* Access routines for the SPI devices on the Gertboard
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
*
|
||||
* The Gertboard has an MCP4802 dual-channel D to A convertor
|
||||
* connected to the SPI bus, selected via chip-select B.
|
||||
*
|
||||
* drc.h:
|
||||
* Extend wiringPi with the DRC control protocll to Arduino
|
||||
* Copyright (c) 2013 Gordon Henderson
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
@@ -30,9 +26,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void gertboardAnalogWrite (int chan, int value) ;
|
||||
extern int gertboardAnalogRead (int chan) ;
|
||||
extern int gertboardSPISetup (void) ;
|
||||
int drcSetup (const int pinBase, const int numPins, const char *device) ;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* gertboard.c:
|
||||
* Access routines for the SPI devices on the Gertboard
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
*
|
||||
* The Gertboard has:
|
||||
*
|
||||
* An MCP3002 dual-channel A to D convertor connected
|
||||
* to the SPI bus, selected by chip-select A, and:
|
||||
*
|
||||
* An MCP4802 dual-channel D to A convertor connected
|
||||
* to the SPI bus, selected via chip-select B.
|
||||
*
|
||||
***********************************************************************
|
||||
* 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 <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "wiringPiSPI.h"
|
||||
|
||||
#include "gertboard.h"
|
||||
|
||||
// The A-D convertor won't run at more than 1MHz @ 3.3v
|
||||
|
||||
#define SPI_ADC_SPEED 1000000
|
||||
#define SPI_DAC_SPEED 1000000
|
||||
#define SPI_A2D 0
|
||||
#define SPI_D2A 1
|
||||
|
||||
|
||||
/*
|
||||
* gertboardAnalogWrite:
|
||||
* Write an 8-bit data value to the MCP4802 Analog to digital
|
||||
* convertor on the Gertboard.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void gertboardAnalogWrite (int chan, int value)
|
||||
{
|
||||
uint8_t spiData [2] ;
|
||||
uint8_t chanBits, dataBits ;
|
||||
|
||||
if (chan == 0)
|
||||
chanBits = 0x30 ;
|
||||
else
|
||||
chanBits = 0xB0 ;
|
||||
|
||||
chanBits |= ((value >> 4) & 0x0F) ;
|
||||
dataBits = ((value << 4) & 0xF0) ;
|
||||
|
||||
spiData [0] = chanBits ;
|
||||
spiData [1] = dataBits ;
|
||||
|
||||
wiringPiSPIDataRW (SPI_D2A, spiData, 2) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gertboardAnalogRead:
|
||||
* Return the analog value of the given channel (0/1).
|
||||
* The A/D is a 10-bit device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int gertboardAnalogRead (int chan)
|
||||
{
|
||||
uint8_t spiData [2] ;
|
||||
|
||||
uint8_t chanBits ;
|
||||
|
||||
if (chan == 0)
|
||||
chanBits = 0b11010000 ;
|
||||
else
|
||||
chanBits = 0b11110000 ;
|
||||
|
||||
spiData [0] = chanBits ;
|
||||
spiData [1] = 0 ;
|
||||
|
||||
wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;
|
||||
|
||||
return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gertboardSPISetup:
|
||||
* Initialise the SPI bus, etc.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int gertboardSPISetup (void)
|
||||
{
|
||||
if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0)
|
||||
return -1 ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
380
wiringPi/lcd.c
380
wiringPi/lcd.c
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
* lcd.c:
|
||||
* Text-based LCD driver.
|
||||
* This is designed to drive the parallel interface LCD drivers
|
||||
* based in the Hitachi HD44780U controller and compatables.
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "lcd.h"
|
||||
|
||||
// Commands
|
||||
|
||||
#define LCD_CLEAR 0x01
|
||||
#define LCD_HOME 0x02
|
||||
#define LCD_ENTRY 0x04
|
||||
#define LCD_ON_OFF 0x08
|
||||
#define LCD_CDSHIFT 0x10
|
||||
#define LCD_FUNC 0x20
|
||||
#define LCD_CGRAM 0x40
|
||||
#define LCD_DGRAM 0x80
|
||||
|
||||
#define LCD_ENTRY_SH 0x01
|
||||
#define LCD_ENTRY_ID 0x02
|
||||
|
||||
#define LCD_ON_OFF_B 0x01
|
||||
#define LCD_ON_OFF_C 0x02
|
||||
#define LCD_ON_OFF_D 0x04
|
||||
|
||||
#define LCD_FUNC_F 0x04
|
||||
#define LCD_FUNC_N 0x08
|
||||
#define LCD_FUNC_DL 0x10
|
||||
|
||||
#define LCD_CDSHIFT_RL 0x04
|
||||
|
||||
struct lcdDataStruct
|
||||
{
|
||||
uint8_t bits, rows, cols ;
|
||||
uint8_t rsPin, strbPin ;
|
||||
uint8_t dataPins [8] ;
|
||||
} ;
|
||||
|
||||
struct lcdDataStruct *lcds [MAX_LCDS] ;
|
||||
|
||||
|
||||
/*
|
||||
* strobe:
|
||||
* Toggle the strobe (Really the "E") pin to the device.
|
||||
* According to the docs, data is latched on the falling edge.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void strobe (struct lcdDataStruct *lcd)
|
||||
{
|
||||
|
||||
// Note timing changes for new version of delayMicroseconds ()
|
||||
|
||||
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ;
|
||||
digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sentDataCmd:
|
||||
* Send an data or command byte to the display.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
|
||||
{
|
||||
uint8_t i, d4 ;
|
||||
|
||||
if (lcd->bits == 4)
|
||||
{
|
||||
d4 = (data >> 4) & 0x0F;
|
||||
for (i = 0 ; i < 4 ; ++i)
|
||||
{
|
||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
|
||||
d4 >>= 1 ;
|
||||
}
|
||||
strobe (lcd) ;
|
||||
|
||||
d4 = data & 0x0F ;
|
||||
for (i = 0 ; i < 4 ; ++i)
|
||||
{
|
||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
|
||||
d4 >>= 1 ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0 ; i < 8 ; ++i)
|
||||
{
|
||||
digitalWrite (lcd->dataPins [i], (data & 1)) ;
|
||||
data >>= 1 ;
|
||||
}
|
||||
}
|
||||
strobe (lcd) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* putCommand:
|
||||
* Send a command byte to the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void putCommand (struct lcdDataStruct *lcd, uint8_t command)
|
||||
{
|
||||
digitalWrite (lcd->rsPin, 0) ;
|
||||
sendDataCmd (lcd, command) ;
|
||||
}
|
||||
|
||||
static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
|
||||
{
|
||||
uint8_t i ;
|
||||
|
||||
digitalWrite (lcd->rsPin, 0) ;
|
||||
|
||||
for (i = 0 ; i < 4 ; ++i)
|
||||
{
|
||||
digitalWrite (lcd->dataPins [i], (command & 1)) ;
|
||||
command >>= 1 ;
|
||||
}
|
||||
strobe (lcd) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************
|
||||
* User Code below here
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* lcdHome: lcdClear:
|
||||
* Home the cursor or clear the screen.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcdHome (int fd)
|
||||
{
|
||||
struct lcdDataStruct *lcd = lcds [fd] ;
|
||||
putCommand (lcd, LCD_HOME) ;
|
||||
}
|
||||
|
||||
void lcdClear (int fd)
|
||||
{
|
||||
struct lcdDataStruct *lcd = lcds [fd] ;
|
||||
putCommand (lcd, LCD_CLEAR) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcdSendCommand:
|
||||
* Send any arbitary command to the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcdSendCommand (int fd, uint8_t command)
|
||||
{
|
||||
struct lcdDataStruct *lcd = lcds [fd] ;
|
||||
putCommand (lcd, command) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* lcdPosition:
|
||||
* Update the position of the cursor on the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
void lcdPosition (int fd, int x, int y)
|
||||
{
|
||||
static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
|
||||
struct lcdDataStruct *lcd = lcds [fd] ;
|
||||
|
||||
putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcdPutchar:
|
||||
* Send a data byte to be displayed on the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcdPutchar (int fd, uint8_t data)
|
||||
{
|
||||
struct lcdDataStruct *lcd = lcds [fd] ;
|
||||
|
||||
digitalWrite (lcd->rsPin, 1) ;
|
||||
sendDataCmd (lcd, data) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcdPuts:
|
||||
* Send a string to be displayed on the display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcdPuts (int fd, char *string)
|
||||
{
|
||||
while (*string)
|
||||
lcdPutchar (fd, *string++) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcdPrintf:
|
||||
* Printf to an LCD display
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void lcdPrintf (int fd, char *message, ...)
|
||||
{
|
||||
va_list argp ;
|
||||
char buffer [1024] ;
|
||||
|
||||
va_start (argp, message) ;
|
||||
vsnprintf (buffer, 1023, message, argp) ;
|
||||
va_end (argp) ;
|
||||
|
||||
lcdPuts (fd, buffer) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcdInit:
|
||||
* Take a lot of parameters and initialise the LCD, and return a handle to
|
||||
* that LCD, or -1 if any error.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int lcdInit (int rows, int cols, int bits, int rs, int strb,
|
||||
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)
|
||||
{
|
||||
static int initialised = 0 ;
|
||||
|
||||
uint8_t func ;
|
||||
int i ;
|
||||
int lcdFd = -1 ;
|
||||
struct lcdDataStruct *lcd ;
|
||||
|
||||
if (initialised == 0)
|
||||
{
|
||||
initialised = 1 ;
|
||||
for (i = 0 ; i < MAX_LCDS ; ++i)
|
||||
lcds [i] = NULL ;
|
||||
}
|
||||
|
||||
// Simple sanity checks
|
||||
|
||||
if (! ((bits == 4) || (bits == 8)))
|
||||
return -1 ;
|
||||
|
||||
if ((rows < 0) || (rows > 20))
|
||||
return -1 ;
|
||||
|
||||
if ((cols < 0) || (cols > 20))
|
||||
return -1 ;
|
||||
|
||||
// Create a new LCD:
|
||||
|
||||
for (i = 0 ; i < MAX_LCDS ; ++i)
|
||||
{
|
||||
if (lcds [i] == NULL)
|
||||
{
|
||||
lcdFd = i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
if (lcdFd == -1)
|
||||
return -1 ;
|
||||
|
||||
lcd = malloc (sizeof (struct lcdDataStruct)) ;
|
||||
if (lcd == NULL)
|
||||
return -1 ;
|
||||
|
||||
lcd->rsPin = rs ;
|
||||
lcd->strbPin = strb ;
|
||||
lcd->bits = 8 ; // For now - we'll set it properly later.
|
||||
lcd->rows = rows ;
|
||||
lcd->cols = cols ;
|
||||
|
||||
lcd->dataPins [0] = d0 ;
|
||||
lcd->dataPins [1] = d1 ;
|
||||
lcd->dataPins [2] = d2 ;
|
||||
lcd->dataPins [3] = d3 ;
|
||||
lcd->dataPins [4] = d4 ;
|
||||
lcd->dataPins [5] = d5 ;
|
||||
lcd->dataPins [6] = d6 ;
|
||||
lcd->dataPins [7] = d7 ;
|
||||
|
||||
lcds [lcdFd] = lcd ;
|
||||
|
||||
digitalWrite (lcd->rsPin, 0) ; pinMode (lcd->rsPin, OUTPUT) ;
|
||||
digitalWrite (lcd->strbPin, 0) ; pinMode (lcd->strbPin, OUTPUT) ;
|
||||
|
||||
for (i = 0 ; i < bits ; ++i)
|
||||
{
|
||||
digitalWrite (lcd->dataPins [i], 0) ;
|
||||
pinMode (lcd->dataPins [i], OUTPUT) ;
|
||||
}
|
||||
delay (35) ; // mS
|
||||
|
||||
|
||||
// 4-bit mode?
|
||||
// OK. This is a PIG and it's not at all obvious from the documentation I had,
|
||||
// so I guess some others have worked through either with better documentation
|
||||
// or more trial and error... Anyway here goes:
|
||||
//
|
||||
// It seems that the controller needs to see the FUNC command at least 3 times
|
||||
// consecutively - in 8-bit mode. If you're only using 8-bit mode, then it appears
|
||||
// that you can get away with one func-set, however I'd not rely on it...
|
||||
//
|
||||
// So to set 4-bit mode, you need to send the commands one nibble at a time,
|
||||
// the same three times, but send the command to set it into 8-bit mode those
|
||||
// three times, then send a final 4th command to set it into 4-bit mode, and only
|
||||
// then can you flip the switch for the rest of the library to work in 4-bit
|
||||
// mode which sends the commands as 2 x 4-bit values.
|
||||
|
||||
if (bits == 4)
|
||||
{
|
||||
func = LCD_FUNC | LCD_FUNC_DL ; // Set 8-bit mode 3 times
|
||||
put4Command (lcd, func >> 4) ; delay (35) ;
|
||||
put4Command (lcd, func >> 4) ; delay (35) ;
|
||||
put4Command (lcd, func >> 4) ; delay (35) ;
|
||||
func = LCD_FUNC ; // 4th set: 4-bit mode
|
||||
put4Command (lcd, func >> 4) ; delay (35) ;
|
||||
lcd->bits = 4 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = LCD_FUNC | LCD_FUNC_DL ;
|
||||
putCommand (lcd, func ) ; delay (35) ;
|
||||
putCommand (lcd, func ) ; delay (35) ;
|
||||
putCommand (lcd, func ) ; delay (35) ;
|
||||
}
|
||||
|
||||
if (lcd->rows > 1)
|
||||
{
|
||||
func |= LCD_FUNC_N ;
|
||||
putCommand (lcd, func) ; delay (35) ;
|
||||
}
|
||||
|
||||
// Rest of the initialisation sequence
|
||||
|
||||
putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ;
|
||||
putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ;
|
||||
putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ;
|
||||
putCommand (lcd, LCD_CLEAR) ; delay (5) ;
|
||||
|
||||
return lcdFd ;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* lcd.h:
|
||||
* Text-based LCD driver.
|
||||
* This is designed to drive the parallel interface LCD drivers
|
||||
* based in the Hitachi HD44780U controller and compatables.
|
||||
*
|
||||
* 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/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#define MAX_LCDS 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void lcdHome (int fd) ;
|
||||
extern void lcdClear (int fd) ;
|
||||
extern void lcdSendCommand (int fd, uint8_t command) ;
|
||||
extern void lcdPosition (int fd, int x, int y) ;
|
||||
extern void lcdPutchar (int fd, uint8_t data) ;
|
||||
extern void lcdPuts (int fd, char *string) ;
|
||||
extern void lcdPrintf (int fd, char *message, ...) ;
|
||||
|
||||
extern int lcdInit (int rows, int cols, int bits, int rs, int strb,
|
||||
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
|
||||
|
||||
#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 fd ;
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
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
|
||||
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 fd ;
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
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
|
||||
189
wiringPi/mcp23s08.c
Normal file
189
wiringPi/mcp23s08.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
int x ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0)
|
||||
return x ;
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
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
|
||||
236
wiringPi/mcp23s17.c
Normal file
236
wiringPi/mcp23s17.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
int x ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0)
|
||||
return x ;
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
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] << 7) | (spiData [1] >> 1)) & 0x3FF ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp3002Setup:
|
||||
* Create a new wiringPi device node for an mcp2003 on the Pi's
|
||||
* SPI interface.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp3002Setup (const int pinBase, int spiChannel)
|
||||
{
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if (wiringPiSPISetup (spiChannel, 1000000) < 0)
|
||||
return -1 ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 2) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
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
|
||||
116
wiringPi/mcp3422.c
Normal file
116
wiringPi/mcp3422.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* mcp3422.c:
|
||||
* Extend wiringPi with the MCP3422 I2C ADC 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 <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include <wiringPi.h>
|
||||
#include <wiringPiI2C.h>
|
||||
|
||||
#include "mcp3422.h"
|
||||
|
||||
|
||||
/*
|
||||
* myAnalogRead:
|
||||
* Read a channel from the device
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
|
||||
{
|
||||
unsigned char config, b0, b1, b2, b3 ;
|
||||
int value = 0 ;
|
||||
|
||||
// One-shot mode, trigger plus the other configs.
|
||||
|
||||
config = 0x80 | ((chan - node->pinBase) << 5) | (node->data0 << 2) | (node->data1) ;
|
||||
|
||||
wiringPiI2CWrite (node->fd, config) ;
|
||||
|
||||
switch (node->data0) // Sample rate
|
||||
{
|
||||
case MCP3422_SR_3_75: // 18 bits
|
||||
delay (270) ;
|
||||
b0 = wiringPiI2CRead (node->fd) ;
|
||||
b1 = wiringPiI2CRead (node->fd) ;
|
||||
b2 = wiringPiI2CRead (node->fd) ;
|
||||
b3 = wiringPiI2CRead (node->fd) ;
|
||||
value = ((b0 & 3) << 16) | (b1 << 8) | b2 ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_15: // 16 bits
|
||||
delay ( 70) ;
|
||||
b0 = wiringPiI2CRead (node->fd) ;
|
||||
b1 = wiringPiI2CRead (node->fd) ;
|
||||
b2 = wiringPiI2CRead (node->fd) ;
|
||||
value = (b0 << 8) | b1 ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_60: // 14 bits
|
||||
delay ( 17) ;
|
||||
b0 = wiringPiI2CRead (node->fd) ;
|
||||
b1 = wiringPiI2CRead (node->fd) ;
|
||||
b2 = wiringPiI2CRead (node->fd) ;
|
||||
value = ((b0 & 0x3F) << 8) | b1 ;
|
||||
break ;
|
||||
|
||||
case MCP3422_SR_240: // 12 bits
|
||||
delay ( 5) ;
|
||||
b0 = wiringPiI2CRead (node->fd) ;
|
||||
b1 = wiringPiI2CRead (node->fd) ;
|
||||
b2 = wiringPiI2CRead (node->fd) ;
|
||||
value = ((b0 & 0x0F) << 8) | b1 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return value ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mcp3422Setup:
|
||||
* Create a new wiringPi device node for the mcp3422
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int mcp3422Setup (int pinBase, int i2cAddress, int channels, int sampleRate, int gain)
|
||||
{
|
||||
int fd ;
|
||||
struct wiringPiNodeStruct *node ;
|
||||
|
||||
if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
|
||||
return fd ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, channels) ;
|
||||
|
||||
node->data0 = sampleRate ;
|
||||
node->data1 = gain ;
|
||||
node->analogRead = myAnalogRead ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* piNes.h:
|
||||
* Driver for the NES Joystick controller on the Raspberry Pi
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
* mcp3422.c:
|
||||
* Extend wiringPi with the MCP3422 I2C ADC chip
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
@@ -22,23 +21,22 @@
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#define MAX_NES_JOYSTICKS 8
|
||||
#define MCP3422_SR_3_75 0
|
||||
#define MCP3422_SR_15 1
|
||||
#define MCP3422_SR_60 2
|
||||
#define MCP3422_SR_240 3
|
||||
|
||||
#define MCP3422_GAIN_1 0
|
||||
#define MCP3422_GAIN_2 1
|
||||
#define MCP3422_GAIN_4 2
|
||||
#define MCP3422_GAIN_8 3
|
||||
|
||||
#define NES_RIGHT 0x01
|
||||
#define NES_LEFT 0x02
|
||||
#define NES_DOWN 0x04
|
||||
#define NES_UP 0x08
|
||||
#define NES_START 0x10
|
||||
#define NES_SELECT 0x20
|
||||
#define NES_B 0x40
|
||||
#define NES_A 0x80
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int setupNesJoystick (int dPin, int cPin, int lPin) ;
|
||||
extern unsigned int readNesJoystick (int joystick) ;
|
||||
extern int mcp3422Setup (int pinBase, int i2cAddress, int channels, int sampleRate, int gain) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
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 -1 ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 2) ;
|
||||
|
||||
node->fd = spiChannel ;
|
||||
node->analogWrite = myAnalogWrite ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
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
|
||||
126
wiringPi/pcf8574.c
Normal file
126
wiringPi/pcf8574.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* pcf8574.c:
|
||||
* Extend wiringPi with the PFC8574 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 PFC8574 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 PFC8574 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 fd ;
|
||||
|
||||
node = wiringPiNewNode (pinBase, 8) ;
|
||||
|
||||
node->fd = fd ;
|
||||
node->pinMode = myPinMode ;
|
||||
node->digitalRead = myDigitalRead ;
|
||||
node->digitalWrite = myDigitalWrite ;
|
||||
node->data2 = wiringPiI2CRead (fd) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
33
wiringPi/pcf8574.h
Normal file
33
wiringPi/pcf8574.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* pfc8574.h:
|
||||
* Extend wiringPi with the PFC8574 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 pfc8574Setup (const int pinBase, const int i2cAddress) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -36,15 +36,16 @@
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int piHiPri (int pri)
|
||||
int piHiPri (const int pri)
|
||||
{
|
||||
struct sched_param sched ;
|
||||
|
||||
memset (&sched, 0, sizeof(sched)) ;
|
||||
|
||||
if (pri > sched_get_priority_max (SCHED_RR))
|
||||
pri = sched_get_priority_max (SCHED_RR) ;
|
||||
sched.sched_priority = sched_get_priority_max (SCHED_RR) ;
|
||||
else
|
||||
sched.sched_priority = pri ;
|
||||
|
||||
sched.sched_priority = pri ;
|
||||
return sched_setscheduler (0, SCHED_RR, &sched) ;
|
||||
}
|
||||
|
||||
113
wiringPi/piNes.c
113
wiringPi/piNes.c
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* piNes.c:
|
||||
* Driver for the NES Joystick controller on the Raspberry Pi
|
||||
* 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 <wiringPi.h>
|
||||
|
||||
#include "piNes.h"
|
||||
|
||||
#define MAX_NES_JOYSTICKS 8
|
||||
|
||||
#define NES_RIGHT 0x01
|
||||
#define NES_LEFT 0x02
|
||||
#define NES_DOWN 0x04
|
||||
#define NES_UP 0x08
|
||||
#define NES_START 0x10
|
||||
#define NES_SELECT 0x20
|
||||
#define NES_B 0x40
|
||||
#define NES_A 0x80
|
||||
|
||||
|
||||
#define PULSE_TIME 25
|
||||
|
||||
// Data to store the pins for each controller
|
||||
|
||||
struct nesPinsStruct
|
||||
{
|
||||
unsigned int cPin, dPin, lPin ;
|
||||
} ;
|
||||
|
||||
static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ;
|
||||
|
||||
static int joysticks = 0 ;
|
||||
|
||||
|
||||
/*
|
||||
* setupNesJoystick:
|
||||
* Create a new NES joystick interface, program the pins, etc.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int setupNesJoystick (int dPin, int cPin, int lPin)
|
||||
{
|
||||
if (joysticks == MAX_NES_JOYSTICKS)
|
||||
return -1 ;
|
||||
|
||||
nesPins [joysticks].dPin = dPin ;
|
||||
nesPins [joysticks].cPin = cPin ;
|
||||
nesPins [joysticks].lPin = lPin ;
|
||||
|
||||
digitalWrite (lPin, LOW) ;
|
||||
digitalWrite (cPin, LOW) ;
|
||||
|
||||
pinMode (lPin, OUTPUT) ;
|
||||
pinMode (cPin, OUTPUT) ;
|
||||
pinMode (dPin, INPUT) ;
|
||||
|
||||
return joysticks++ ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* readNesJoystick:
|
||||
* Do a single scan of the NES Joystick.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
unsigned int readNesJoystick (int joystick)
|
||||
{
|
||||
unsigned int value = 0 ;
|
||||
int i ;
|
||||
|
||||
struct nesPinsStruct *pins = &nesPins [joystick] ;
|
||||
|
||||
// Toggle Latch - which presents the first bit
|
||||
|
||||
digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
|
||||
digitalWrite (pins->lPin, LOW) ; delayMicroseconds (PULSE_TIME) ;
|
||||
|
||||
// Read first bit
|
||||
|
||||
value = digitalRead (pins->dPin) ;
|
||||
|
||||
// Now get the next 7 bits with the clock
|
||||
|
||||
for (i = 0 ; i < 7 ; ++i)
|
||||
{
|
||||
digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
|
||||
digitalWrite (pins->cPin, LOW) ; delayMicroseconds (PULSE_TIME) ;
|
||||
value = (value << 1) | digitalRead (pins->dPin) ;
|
||||
}
|
||||
|
||||
return value ^ 0xFF ;
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "wiringPi.h"
|
||||
#include "softPwm.h"
|
||||
|
||||
#define MAX_PINS 64
|
||||
#define MAX_PINS 1024
|
||||
|
||||
// The PWM Frequency is derived from the "pulse time" below. Essentially,
|
||||
// the frequency is a function of the range and this pulse time.
|
||||
@@ -93,7 +93,7 @@ static PI_THREAD (softPwmThread)
|
||||
|
||||
void softPwmWrite (int pin, int value)
|
||||
{
|
||||
pin &= 63 ;
|
||||
pin &= (MAX_PINS - 1) ;
|
||||
|
||||
/**/ if (value < 0)
|
||||
value = 0 ;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#define PULSE_TIME 100
|
||||
|
||||
static int frewqs [MAX_PINS] ;
|
||||
static int freqs [MAX_PINS] ;
|
||||
|
||||
static int newPin = -1 ;
|
||||
|
||||
@@ -49,7 +49,7 @@ static int newPin = -1 ;
|
||||
|
||||
static PI_THREAD (softToneThread)
|
||||
{
|
||||
int pin, frewq, halfPeriod ;
|
||||
int pin, freq, halfPeriod ;
|
||||
|
||||
pin = newPin ;
|
||||
newPin = -1 ;
|
||||
@@ -58,12 +58,12 @@ static PI_THREAD (softToneThread)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
frewq = frewqs [pin] ;
|
||||
if (frewq == 0)
|
||||
freq = freqs [pin] ;
|
||||
if (freq == 0)
|
||||
delay (1) ;
|
||||
else
|
||||
{
|
||||
halfPeriod = 500000 / frewq ;
|
||||
halfPeriod = 500000 / freq ;
|
||||
|
||||
digitalWrite (pin, HIGH) ;
|
||||
delayMicroseconds (halfPeriod) ;
|
||||
@@ -83,16 +83,16 @@ static PI_THREAD (softToneThread)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softToneWrite (int pin, int frewq)
|
||||
void softToneWrite (int pin, int freq)
|
||||
{
|
||||
pin &= 63 ;
|
||||
|
||||
/**/ if (frewq < 0)
|
||||
frewq = 0 ;
|
||||
else if (frewq > 5000) // Max 5KHz
|
||||
frewq = 5000 ;
|
||||
/**/ if (freq < 0)
|
||||
freq = 0 ;
|
||||
else if (freq > 5000) // Max 5KHz
|
||||
freq = 5000 ;
|
||||
|
||||
frewqs [pin] = frewq ;
|
||||
freqs [pin] = freq ;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ int softToneCreate (int pin)
|
||||
pinMode (pin, OUTPUT) ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
|
||||
frewqs [pin] = 0 ;
|
||||
freqs [pin] = 0 ;
|
||||
|
||||
newPin = pin ;
|
||||
res = piThreadCreate (softToneThread) ;
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern int softToneCreate (int pin) ;
|
||||
extern void softToneWrite (int pin, int frewq) ;
|
||||
extern void softToneWrite (int pin, int freq) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
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 0 ;
|
||||
}
|
||||
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
|
||||
1180
wiringPi/wiringPi.c
1180
wiringPi/wiringPi.c
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,8 @@
|
||||
#define WPI_MODE_PINS 0
|
||||
#define WPI_MODE_GPIO 1
|
||||
#define WPI_MODE_GPIO_SYS 2
|
||||
#define WPI_MODE_PIFACE 3
|
||||
#define WPI_MODE_PHYS 3
|
||||
#define WPI_MODE_PIFACE 4
|
||||
#define WPI_MODE_UNINITIALISED -1
|
||||
|
||||
// Pin modes
|
||||
@@ -64,6 +65,42 @@
|
||||
|
||||
#define PI_THREAD(X) void *X (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) ;
|
||||
void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
|
||||
void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
|
||||
int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
|
||||
void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
|
||||
|
||||
struct wiringPiNodeStruct *next ;
|
||||
} ;
|
||||
|
||||
|
||||
// Function prototypes
|
||||
// c++ wrappers thanks to a comment by Nick Lott
|
||||
@@ -73,46 +110,61 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Basic wiringPi functions
|
||||
// Internal
|
||||
|
||||
extern int wiringPiFailure (int fatal, const char *message, ...) ;
|
||||
|
||||
// Core wiringPi functions
|
||||
|
||||
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
|
||||
|
||||
extern int wiringPiSetup (void) ;
|
||||
extern int wiringPiSetupSys (void) ;
|
||||
extern int wiringPiSetupGpio (void) ;
|
||||
extern int wiringPiSetupPhys (void) ;
|
||||
|
||||
extern void pinMode (int pin, int mode) ;
|
||||
extern void pullUpDnControl (int pin, int pud) ;
|
||||
extern int digitalRead (int pin) ;
|
||||
extern void digitalWrite (int pin, int value) ;
|
||||
extern void pwmWrite (int pin, int value) ;
|
||||
extern int analogRead (int pin) ;
|
||||
extern void analogWrite (int pin, int value) ;
|
||||
|
||||
// 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 piBoardRev (void) ;
|
||||
extern int wpiPinToGpio (int wpiPin) ;
|
||||
|
||||
extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only
|
||||
|
||||
extern void (*pinMode) (int pin, int mode) ;
|
||||
extern int (*getAlt) (int pin) ;
|
||||
extern void (*pullUpDnControl) (int pin, int pud) ;
|
||||
extern void (*digitalWrite) (int pin, int value) ;
|
||||
extern void (*digitalWriteByte) (int value) ;
|
||||
extern void (*gpioClockSet) (int pin, int freq) ;
|
||||
extern void (*pwmWrite) (int pin, int value) ;
|
||||
extern void (*setPadDrive) (int group, int value) ;
|
||||
extern int (*digitalRead) (int pin) ;
|
||||
extern void (*pwmSetMode) (int mode) ;
|
||||
extern void (*pwmSetRange) (unsigned int range) ;
|
||||
extern void (*pwmSetClock) (int divisor) ;
|
||||
extern int physPinToGpio (int physPin) ;
|
||||
extern void setPadDrive (int group, int value) ;
|
||||
extern int getAlt (int pin) ;
|
||||
extern void digitalWriteByte (int value) ;
|
||||
extern void pwmSetMode (int mode) ;
|
||||
extern void pwmSetRange (unsigned int range) ;
|
||||
extern void pwmSetClock (int divisor) ;
|
||||
extern void gpioClockSet (int pin, int freq) ;
|
||||
|
||||
// Interrupts
|
||||
// (Also Pi hardware specific)
|
||||
|
||||
extern int (*waitForInterrupt) (int pin, int mS) ;
|
||||
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) ;
|
||||
extern int piThreadCreate (void *(*fn)(void *)) ;
|
||||
extern void piLock (int key) ;
|
||||
extern void piUnlock (int key) ;
|
||||
|
||||
// Schedulling priority
|
||||
|
||||
extern int piHiPri (int pri) ;
|
||||
|
||||
extern int piHiPri (const int pri) ;
|
||||
|
||||
// Extras from arduino land
|
||||
|
||||
|
||||
@@ -1,362 +0,0 @@
|
||||
/*
|
||||
* wiringPiFace:
|
||||
* Arduino compatable (ish) Wiring library for the Raspberry Pi
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
*
|
||||
* This file to interface with the PiFace peripheral device which
|
||||
* has an MCP23S17 GPIO device connected via the SPI bus.
|
||||
*
|
||||
***********************************************************************
|
||||
* 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 <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
|
||||
|
||||
// The SPI bus parameters
|
||||
// Variables as they need to be passed as pointers later on
|
||||
|
||||
static char *spiDevice = "/dev/spidev0.0" ;
|
||||
static uint8_t spiMode = 0 ;
|
||||
static uint8_t spiBPW = 8 ;
|
||||
static uint32_t spiSpeed = 5000000 ;
|
||||
static uint16_t spiDelay = 0;
|
||||
|
||||
// Locals here to keep track of everything
|
||||
|
||||
static int spiFd ;
|
||||
|
||||
// The MCP23S17 doesn't have bit-set operations, so it's
|
||||
// cheaper to keep a copy here than to read/modify/write it
|
||||
|
||||
uint8_t dataOutRegister = 0 ;
|
||||
uint8_t pudRegister = 0 ;
|
||||
|
||||
// MCP23S17 Registers
|
||||
|
||||
#define IOCON 0x0A
|
||||
|
||||
#define IODIRA 0x00
|
||||
#define IPOLA 0x02
|
||||
#define GPINTENA 0x04
|
||||
#define DEFVALA 0x06
|
||||
#define INTCONA 0x08
|
||||
#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 GPPUB 0x0D
|
||||
#define INTFB 0x0F
|
||||
#define INTCAPB 0x11
|
||||
#define GPIOB 0x13
|
||||
#define OLATB 0x15
|
||||
|
||||
// Bits in the IOCON register
|
||||
|
||||
#define IOCON_BANK_MODE 0x80
|
||||
#define IOCON_MIRROR 0x40
|
||||
#define IOCON_SEQOP 0x20
|
||||
#define IOCON_DISSLW 0x10
|
||||
#define IOCON_HAEN 0x08
|
||||
#define IOCON_ODR 0x04
|
||||
#define IOCON_INTPOL 0x02
|
||||
#define IOCON_UNUSED 0x01
|
||||
|
||||
// Default initialisation mode
|
||||
|
||||
#define IOCON_INIT (IOCON_SEQOP)
|
||||
|
||||
// Command codes
|
||||
|
||||
#define CMD_WRITE 0x40
|
||||
#define CMD_READ 0x41
|
||||
|
||||
|
||||
/*
|
||||
* writeByte:
|
||||
* Write a byte to a register on the MCP23S17 on the SPI bus.
|
||||
* This is using the synchronous access mechanism.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static void writeByte (uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t spiBufTx [3] ;
|
||||
uint8_t spiBufRx [3] ;
|
||||
struct spi_ioc_transfer spi ;
|
||||
|
||||
spiBufTx [0] = CMD_WRITE ;
|
||||
spiBufTx [1] = reg ;
|
||||
spiBufTx [2] = data ;
|
||||
|
||||
spi.tx_buf = (unsigned long)spiBufTx ;
|
||||
spi.rx_buf = (unsigned long)spiBufRx ;
|
||||
spi.len = 3 ;
|
||||
spi.delay_usecs = spiDelay ;
|
||||
spi.speed_hz = spiSpeed ;
|
||||
spi.bits_per_word = spiBPW ;
|
||||
|
||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* readByte:
|
||||
* Read a byte from a register on the MCP23S17 on the SPI bus.
|
||||
* This is the synchronous access mechanism.
|
||||
* What appears to happen is that the data returned is at
|
||||
* the same offset as the number of bytes written to the device. So if we
|
||||
* write 2 bytes (e.g. command then register number), then the data returned
|
||||
* will by at the 3rd byte...
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static uint8_t readByte (uint8_t reg)
|
||||
{
|
||||
uint8_t tx [4] ;
|
||||
uint8_t rx [4] ;
|
||||
struct spi_ioc_transfer spi ;
|
||||
|
||||
tx [0] = CMD_READ ;
|
||||
tx [1] = reg ;
|
||||
tx [2] = 0 ;
|
||||
|
||||
spi.tx_buf = (unsigned long)tx ;
|
||||
spi.rx_buf = (unsigned long)rx ;
|
||||
spi.len = 3 ;
|
||||
spi.delay_usecs = spiDelay ;
|
||||
spi.speed_hz = spiSpeed ;
|
||||
spi.bits_per_word = spiBPW ;
|
||||
|
||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;
|
||||
|
||||
return rx [2] ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* digitalWritePiFace:
|
||||
* Perform the digitalWrite function on the PiFace board
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void digitalWritePiFace (int pin, int value)
|
||||
{
|
||||
uint8_t mask = 1 << pin ;
|
||||
|
||||
if (value == 0)
|
||||
dataOutRegister &= (~mask) ;
|
||||
else
|
||||
dataOutRegister |= mask ;
|
||||
|
||||
writeByte (GPIOA, dataOutRegister) ;
|
||||
}
|
||||
|
||||
void digitalWriteBytePiFace (int value)
|
||||
{
|
||||
writeByte (GPIOA, value) ;
|
||||
}
|
||||
|
||||
|
||||
void digitalWritePiFaceSpecial (int pin, int value)
|
||||
{
|
||||
uint8_t mask = 1 << pin ;
|
||||
uint8_t old ;
|
||||
|
||||
old = readByte (GPIOA) ;
|
||||
|
||||
if (value == 0)
|
||||
old &= (~mask) ;
|
||||
else
|
||||
old |= mask ;
|
||||
|
||||
writeByte (GPIOA, old) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* digitalReadPiFace:
|
||||
* Perform the digitalRead function on the PiFace board
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int digitalReadPiFace (int pin)
|
||||
{
|
||||
uint8_t mask = 1 << pin ;
|
||||
|
||||
if ((readByte (GPIOB) & mask) != 0)
|
||||
return HIGH ;
|
||||
else
|
||||
return LOW ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pullUpDnControlPiFace:
|
||||
* Perform the pullUpDnControl function on the PiFace board
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void pullUpDnControlPiFace (int pin, int pud)
|
||||
{
|
||||
uint8_t mask = 1 << pin ;
|
||||
|
||||
if (pud == PUD_UP)
|
||||
pudRegister |= mask ;
|
||||
else
|
||||
pudRegister &= (~mask) ;
|
||||
|
||||
writeByte (GPPUB, pudRegister) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void pullUpDnControlPiFaceSpecial (int pin, int pud)
|
||||
{
|
||||
uint8_t mask = 1 << pin ;
|
||||
uint8_t old ;
|
||||
|
||||
old = readByte (GPPUB) ;
|
||||
|
||||
if (pud == PUD_UP)
|
||||
old |= mask ;
|
||||
else
|
||||
old &= (~mask) ;
|
||||
|
||||
writeByte (GPPUB, old) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Dummy functions that are not used in this mode
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void pinModePiFace (int pin, int mode) {}
|
||||
void pwmWritePiFace (int pin, int value) {}
|
||||
int waitForInterruptPiFace (int pin, int mS) { return 0 ; }
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSetupPiFace
|
||||
* Setup the SPI interface and initialise the MCP23S17 chip
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static int _wiringPiSetupPiFace (void)
|
||||
{
|
||||
if ((spiFd = open (spiDevice, O_RDWR)) < 0)
|
||||
return -1 ;
|
||||
|
||||
// Set SPI parameters
|
||||
// Why are we doing a read after write?
|
||||
// I don't know - just blindliy copying an example elsewhere... -GH-
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
|
||||
return -1 ;
|
||||
|
||||
// Setup the MCP23S17
|
||||
|
||||
writeByte (IOCON, IOCON_INIT) ;
|
||||
|
||||
writeByte (IODIRA, 0x00) ; // Port A -> Outputs
|
||||
writeByte (IODIRB, 0xFF) ; // Port B -> Inputs
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int wiringPiSetupPiFace (void)
|
||||
{
|
||||
int x = _wiringPiSetupPiFace () ;
|
||||
|
||||
if (x != 0)
|
||||
return x ;
|
||||
|
||||
writeByte (GPIOA, 0x00) ; // Set all outptus off
|
||||
writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B
|
||||
|
||||
pinMode = pinModePiFace ;
|
||||
pullUpDnControl = pullUpDnControlPiFace ;
|
||||
digitalWrite = digitalWritePiFace ;
|
||||
digitalWriteByte = digitalWriteBytePiFace ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wiringPiSetupPiFaceForGpioProg:
|
||||
* Setup the SPI interface and initialise the MCP23S17 chip
|
||||
* Special version for the gpio program
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
int wiringPiSetupPiFaceForGpioProg (void)
|
||||
{
|
||||
int x = _wiringPiSetupPiFace () ;
|
||||
|
||||
if (x != 0)
|
||||
return x ;
|
||||
|
||||
pinMode = pinModePiFace ;
|
||||
pullUpDnControl = pullUpDnControlPiFaceSpecial ;
|
||||
digitalWrite = digitalWritePiFaceSpecial ;
|
||||
digitalWriteByte = digitalWriteBytePiFace ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
@@ -22,15 +22,93 @@
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <linux/i2c-dev.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:
|
||||
@@ -40,7 +118,12 @@
|
||||
|
||||
int wiringPiI2CRead (int fd)
|
||||
{
|
||||
return i2c_smbus_read_byte (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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +135,22 @@ int wiringPiI2CRead (int fd)
|
||||
|
||||
int wiringPiI2CReadReg8 (int fd, int reg)
|
||||
{
|
||||
return i2c_smbus_read_byte_data (fd, 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)
|
||||
{
|
||||
return i2c_smbus_read_word_data (fd, 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.byte & 0xFF ;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +162,7 @@ int wiringPiI2CReadReg16 (int fd, int reg)
|
||||
|
||||
int wiringPiI2CWrite (int fd, int data)
|
||||
{
|
||||
return i2c_smbus_write_byte (fd, data) ;
|
||||
return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,14 +172,41 @@ int wiringPiI2CWrite (int fd, int data)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CWriteReg8 (int fd, int reg, int data)
|
||||
int wiringPiI2CWriteReg8 (int fd, int reg, int value)
|
||||
{
|
||||
return i2c_smbus_write_byte_data (fd, reg, data) ;
|
||||
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 data)
|
||||
int wiringPiI2CWriteReg16 (int fd, int reg, int value)
|
||||
{
|
||||
return i2c_smbus_write_word_data (fd, reg, data) ;
|
||||
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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,27 +216,17 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int data)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int wiringPiI2CSetup (int devId)
|
||||
int wiringPiI2CSetup (const int devId)
|
||||
{
|
||||
int rev, fd ;
|
||||
char *device ;
|
||||
int rev ;
|
||||
const char *device ;
|
||||
|
||||
if ((rev = piBoardRev ()) < 0)
|
||||
{
|
||||
fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ;
|
||||
exit (1) ;
|
||||
}
|
||||
rev = piBoardRev () ;
|
||||
|
||||
if (rev == 1)
|
||||
device = "/dev/i2c-0" ;
|
||||
else
|
||||
device = "/dev/i2c-1" ;
|
||||
|
||||
if ((fd = open (device, O_RDWR)) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (ioctl (fd, I2C_SLAVE, devId) < 0)
|
||||
return -1 ;
|
||||
|
||||
return fd ;
|
||||
return wiringPiI2CSetupInterface (device, devId) ;
|
||||
}
|
||||
|
||||
@@ -26,15 +26,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int wiringPiI2CRead (int fd) ;
|
||||
extern int wiringPiI2CReadReg8 (int fd, int reg) ;
|
||||
extern int wiringPiI2CReadReg16 (int fd, int reg) ;
|
||||
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 wiringPiI2CWrite (int fd, int data) ;
|
||||
extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
|
||||
extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
|
||||
|
||||
int wiringPiI2CSetup (int devId) ;
|
||||
extern int wiringPiI2CSetupInterface (const char *device, int devId) ;
|
||||
extern int wiringPiI2CSetup (const int devId) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -25,20 +25,24 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/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 char *spiDev0 = "/dev/spidev0.0" ;
|
||||
static char *spiDev1 = "/dev/spidev0.1" ;
|
||||
static uint8_t spiMode = 0 ;
|
||||
static uint8_t spiBPW = 8 ;
|
||||
static uint16_t spiDelay = 0;
|
||||
const static char *spiDev0 = "/dev/spidev0.0" ;
|
||||
const static char *spiDev1 = "/dev/spidev0.1" ;
|
||||
const static uint8_t spiMode = 0 ;
|
||||
const static uint8_t spiBPW = 8 ;
|
||||
const static uint16_t spiDelay = 0 ;
|
||||
|
||||
static uint32_t spiSpeeds [2] ;
|
||||
static int spiFds [2] ;
|
||||
@@ -95,7 +99,7 @@ int wiringPiSPISetup (int channel, int speed)
|
||||
channel &= 1 ;
|
||||
|
||||
if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0)
|
||||
return -1 ;
|
||||
return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ;
|
||||
|
||||
spiSpeeds [channel] = speed ;
|
||||
spiFds [channel] = fd ;
|
||||
@@ -104,14 +108,14 @@ int wiringPiSPISetup (int channel, int speed)
|
||||
// Why are we reading it afterwriting it? I've no idea, but for now I'm blindly
|
||||
// copying example code I've seen online...
|
||||
|
||||
if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ;
|
||||
if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ;
|
||||
|
||||
if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ;
|
||||
if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ;
|
||||
if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 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 -1 ;
|
||||
if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ;
|
||||
return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ;
|
||||
|
||||
return fd ;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialOpen (char *device, int baud)
|
||||
int serialOpen (const char *device, const int baud)
|
||||
{
|
||||
struct termios options ;
|
||||
speed_t myBaud ;
|
||||
@@ -60,6 +60,7 @@ int serialOpen (char *device, int baud)
|
||||
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 ;
|
||||
@@ -116,7 +117,7 @@ int serialOpen (char *device, int baud)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialFlush (int fd)
|
||||
void serialFlush (const int fd)
|
||||
{
|
||||
tcflush (fd, TCIOFLUSH) ;
|
||||
}
|
||||
@@ -128,7 +129,7 @@ void serialFlush (int fd)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialClose (int fd)
|
||||
void serialClose (const int fd)
|
||||
{
|
||||
close (fd) ;
|
||||
}
|
||||
@@ -140,7 +141,7 @@ void serialClose (int fd)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPutchar (int fd, unsigned char c)
|
||||
void serialPutchar (const int fd, const unsigned char c)
|
||||
{
|
||||
write (fd, &c, 1) ;
|
||||
}
|
||||
@@ -152,7 +153,7 @@ void serialPutchar (int fd, unsigned char c)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPuts (int fd, char *s)
|
||||
void serialPuts (const int fd, const char *s)
|
||||
{
|
||||
write (fd, s, strlen (s)) ;
|
||||
}
|
||||
@@ -163,7 +164,7 @@ void serialPuts (int fd, char *s)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void serialPrintf (int fd, char *message, ...)
|
||||
void serialPrintf (const int fd, const char *message, ...)
|
||||
{
|
||||
va_list argp ;
|
||||
char buffer [1024] ;
|
||||
@@ -182,7 +183,7 @@ void serialPrintf (int fd, char *message, ...)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialDataAvail (int fd)
|
||||
int serialDataAvail (const int fd)
|
||||
{
|
||||
int result ;
|
||||
|
||||
@@ -201,7 +202,7 @@ int serialDataAvail (int fd)
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int serialGetchar (int fd)
|
||||
int serialGetchar (const int fd)
|
||||
{
|
||||
uint8_t x ;
|
||||
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int serialOpen (char *device, int baud) ;
|
||||
extern void serialClose (int fd) ;
|
||||
extern void serialFlush (int fd) ;
|
||||
extern void serialPutchar (int fd, unsigned char c) ;
|
||||
extern void serialPuts (int fd, char *s) ;
|
||||
extern void serialPrintf (int fd, char *message, ...) ;
|
||||
extern int serialDataAvail (int fd) ;
|
||||
extern int serialGetchar (int fd) ;
|
||||
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
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order)
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shiftOut:
|
||||
* Shift data out to a clocked source
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
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) ;
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user