wiringPi Version 2 - First commit (of v2)

This commit is contained in:
Gordon Henderson
2013-05-13 19:43:26 +01:00
parent 98bcb20d93
commit da38443cb2
97 changed files with 11243 additions and 1617 deletions

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
View 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
View 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
View 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
View 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

View File

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

View File

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

View File

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

View File

@@ -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) ;

View File

@@ -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
View 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
View 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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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

View File

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