@@ -30,18 +30,6 @@ To un-install wiringPi: | |||||
./build uninstall | ./build uninstall | ||||
I2C: | |||||
If your system has the correct i2c-dev libraries and headers installed, | |||||
then the I2C helpers will be compiled into wiringPi. If you want to | |||||
use the I2C helpers and don't have them installed, then under Raspbian, | |||||
issue the command: | |||||
sudo apt-get install libi2c-dev | |||||
Consult the documentation for your system if you are not running Raspbian. | |||||
Gordon Henderson | Gordon Henderson | ||||
projects@drogon.net | projects@drogon.net | ||||
@@ -16,7 +16,7 @@ accepted to Github.... | |||||
Please see | Please see | ||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
http://wiringpi.com/ | |||||
for the official documentation, etc. and the best way to submit bug reports, etc. | for the official documentation, etc. and the best way to submit bug reports, etc. | ||||
is by sending an email to projects@drogon.net | is by sending an email to projects@drogon.net | ||||
@@ -14,28 +14,28 @@ check-make-ok() | |||||
} | } | ||||
if [ x$1 = "xclean" ]; then | if [ x$1 = "xclean" ]; then | ||||
echo Cleaning | |||||
echo | |||||
cd wiringPi | cd wiringPi | ||||
make clean | |||||
echo -n "wiringPi: " ; make clean | |||||
cd ../devLib | |||||
echo -n "DevLib: " ; make clean | |||||
cd ../gpio | cd ../gpio | ||||
make clean | |||||
echo -n "gpio: " ; make clean | |||||
cd ../examples | cd ../examples | ||||
make clean | |||||
echo -n "Examples: " ; make clean | |||||
cd Gertboard | |||||
echo -n "Gertboard: " ; make clean | |||||
cd ../PiFace | |||||
echo -n "PiFace: " ; make clean | |||||
exit | exit | ||||
fi | fi | ||||
if [ x$1 = "xuninstall" ]; then | if [ x$1 = "xuninstall" ]; then | ||||
echo Uninstalling | |||||
echo | |||||
echo "WiringPi library" | |||||
cd wiringPi | cd wiringPi | ||||
sudo make uninstall | |||||
echo | |||||
echo "GPIO Utility" | |||||
echo -n "wiringPi: " ; sudo make uninstall | |||||
cd ../devLib | |||||
echo -n "DevLib: " ; sudo make uninstall | |||||
cd ../gpio | cd ../gpio | ||||
sudo make uninstall | |||||
cd .. | |||||
echo -n "gpio: " ; sudo make uninstall | |||||
exit | exit | ||||
fi | fi | ||||
@@ -44,25 +44,20 @@ fi | |||||
echo "=====================" | echo "=====================" | ||||
echo | echo | ||||
# Check for I2C being installed... | |||||
# ... and if-so, then automatically make the I2C helpers | |||||
if [ -f /usr/include/linux/i2c-dev.h ]; then | |||||
grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h | |||||
if [ $? = 0 ]; then | |||||
target=i2c | |||||
echo "Building wiringPi with the I2C helper libraries." | |||||
else | |||||
target=all | |||||
echo "The wiringPi I2C helper libraries will not be built." | |||||
fi | |||||
fi | |||||
echo | echo | ||||
echo "WiringPi library" | |||||
echo "WiringPi Library" | |||||
cd wiringPi | cd wiringPi | ||||
sudo make uninstall | sudo make uninstall | ||||
make $target | |||||
make | |||||
check-make-ok | |||||
sudo make install | |||||
check-make-ok | |||||
echo | |||||
echo "WiringPi Devices Library" | |||||
cd ../devLib | |||||
sudo make uninstall | |||||
make | |||||
check-make-ok | check-make-ok | ||||
sudo make install | sudo make install | ||||
check-make-ok | check-make-ok | ||||
@@ -0,0 +1,130 @@ | |||||
# Makefile: | |||||
# wiringPi device - Wiring Compatable library for the Raspberry Pi | |||||
# | |||||
# 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/>. | |||||
################################################################################# | |||||
DYN_VERS_MAJ=2 | |||||
DYN_VERS_MIN=0 | |||||
VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) | |||||
DESTDIR=/usr | |||||
PREFIX=/local | |||||
STATIC=libwiringPiDev.a | |||||
DYNAMIC=libwiringPiDev.so.$(VERSION) | |||||
#DEBUG = -g -O0 | |||||
DEBUG = -O2 | |||||
CC = gcc | |||||
INCLUDE = -I. | |||||
CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC | |||||
LIBS = | |||||
############################################################################### | |||||
SRC = ds1302.c maxdetect.c piNes.c \ | |||||
gertboard.c piFace.c \ | |||||
lcd128x64.c lcd.c | |||||
OBJ = $(SRC:.c=.o) | |||||
all: $(DYNAMIC) | |||||
static: $(STATIC) | |||||
$(STATIC): $(OBJ) | |||||
@echo "[Link (Static)]" | |||||
@ar rcs $(STATIC) $(OBJ) | |||||
@ranlib $(STATIC) | |||||
# @size $(STATIC) | |||||
$(DYNAMIC): $(OBJ) | |||||
@echo "[Link (Dynamic)]" | |||||
@$(CC) -shared -Wl,-soname,libwiringPiDev.so -o libwiringPiDev.so.$(VERSION) -lpthread $(OBJ) | |||||
.c.o: | |||||
@echo [Compile] $< | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | |||||
.PHONEY: clean | |||||
clean: | |||||
@echo "[Clean]" | |||||
@rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPiDev.* | |||||
.PHONEY: tags | |||||
tags: $(SRC) | |||||
@echo [ctags] | |||||
@ctags $(SRC) | |||||
.PHONEY: install-headers | |||||
install-headers: | |||||
@echo "[Install Headers]" | |||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 ds1302.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 maxdetect.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 piFace.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 lcd128x64.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include | |||||
.PHONEY: install | |||||
install: $(DYNAMIC) install-headers | |||||
@echo "[Install Dynamic Lib]" | |||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib | |||||
@install -m 0755 libwiringPiDev.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) | |||||
@ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) $(DESTDIR)/lib/libwiringPiDev.so | |||||
@ldconfig | |||||
.PHONEY: install-static | |||||
install-static: $(STATIC) install-headers | |||||
@echo "[Install Static Lib]" | |||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib | |||||
@install -m 0755 libwiringPiDev.a $(DESTDIR)$(PREFIX)/lib | |||||
.PHONEY: uninstall | |||||
uninstall: | |||||
@echo "[UnInstall]" | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/ds1302.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/maxdetect.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/piNes.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/piFace.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/lcd128x64.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/lcd.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.* | |||||
@ldconfig | |||||
.PHONEY: depend | |||||
depend: | |||||
makedepend -Y $(SRC) | |||||
# DO NOT DELETE | |||||
ds1302.o: ds1302.h | |||||
maxdetect.o: maxdetect.h | |||||
piNes.o: piNes.h | |||||
gertboard.o: gertboard.h | |||||
piFace.o: piFace.h | |||||
lcd128x64.o: font.h lcd128x64.h | |||||
lcd.o: lcd.h |
@@ -0,0 +1,240 @@ | |||||
/* | |||||
* ds1302.c: | |||||
* Real Time clock | |||||
* | |||||
* 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 <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <stdarg.h> | |||||
#include <wiringPi.h> | |||||
#include "ds1302.h" | |||||
// Register defines | |||||
#define RTC_SECS 0 | |||||
#define RTC_MINS 1 | |||||
#define RTC_HOURS 2 | |||||
#define RTC_DATE 3 | |||||
#define RTC_MONTH 4 | |||||
#define RTC_DAY 5 | |||||
#define RTC_YEAR 6 | |||||
#define RTC_WP 7 | |||||
#define RTC_TC 8 | |||||
#define RTC_BM 31 | |||||
// Locals | |||||
static int dPin, cPin, sPin ; | |||||
/* | |||||
* dsShiftIn: | |||||
* Shift a number in from the chip, LSB first. Note that the data is | |||||
* sampled on the trailing edge of the last clock, so it's valid immediately. | |||||
********************************************************************************* | |||||
*/ | |||||
static unsigned int dsShiftIn (void) | |||||
{ | |||||
uint8_t value = 0 ; | |||||
int i ; | |||||
pinMode (dPin, INPUT) ; delayMicroseconds (1) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
{ | |||||
value |= (digitalRead (dPin) << i) ; | |||||
digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; | |||||
digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; | |||||
} | |||||
return value; | |||||
} | |||||
/* | |||||
* dsShiftOut: | |||||
* A normal LSB-first shift-out, just slowed down a bit - the Pi is | |||||
* a bit faster than the chip can handle. | |||||
********************************************************************************* | |||||
*/ | |||||
static void dsShiftOut (unsigned int data) | |||||
{ | |||||
int i ; | |||||
pinMode (dPin, OUTPUT) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
{ | |||||
digitalWrite (dPin, data & (1 << i)) ; delayMicroseconds (1) ; | |||||
digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; | |||||
digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; | |||||
} | |||||
} | |||||
/* | |||||
* ds1302regRead: ds1302regWrite: | |||||
* Read/Write a value to an RTC Register or RAM location on the chip | |||||
********************************************************************************* | |||||
*/ | |||||
static unsigned int ds1302regRead (const int reg) | |||||
{ | |||||
unsigned int data ; | |||||
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; | |||||
dsShiftOut (reg) ; | |||||
data = dsShiftIn () ; | |||||
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; | |||||
return data ; | |||||
} | |||||
static void ds1302regWrite (const int reg, const unsigned int data) | |||||
{ | |||||
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; | |||||
dsShiftOut (reg) ; | |||||
dsShiftOut (data) ; | |||||
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; | |||||
} | |||||
/* | |||||
* ds1302rtcWrite: ds1302rtcRead: | |||||
* Writes/Reads the data to/from the RTC register | |||||
********************************************************************************* | |||||
*/ | |||||
unsigned int ds1302rtcRead (const int reg) | |||||
{ | |||||
return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ; | |||||
} | |||||
void ds1302rtcWrite (int reg, unsigned int data) | |||||
{ | |||||
ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ; | |||||
} | |||||
/* | |||||
* ds1302ramWrite: ds1302ramRead: | |||||
* Writes/Reads the data to/from the RTC register | |||||
********************************************************************************* | |||||
*/ | |||||
unsigned int ds1302ramRead (const int addr) | |||||
{ | |||||
return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ; | |||||
} | |||||
void ds1302ramWrite (const int addr, const unsigned int data) | |||||
{ | |||||
ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ; | |||||
} | |||||
/* | |||||
* ds1302clockRead: | |||||
* Read all 8 bytes of the clock in a single operation | |||||
********************************************************************************* | |||||
*/ | |||||
void ds1302clockRead (int clockData [8]) | |||||
{ | |||||
int i ; | |||||
unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ; | |||||
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; | |||||
dsShiftOut (regVal) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
clockData [i] = dsShiftIn () ; | |||||
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; | |||||
} | |||||
/* | |||||
* ds1302clockWrite: | |||||
* Write all 8 bytes of the clock in a single operation | |||||
********************************************************************************* | |||||
*/ | |||||
void ds1302clockWrite (const int clockData [8]) | |||||
{ | |||||
int i ; | |||||
unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ; | |||||
digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; | |||||
dsShiftOut (regVal) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
dsShiftOut (clockData [i]) ; | |||||
digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; | |||||
} | |||||
/* | |||||
* ds1302trickleCharge: | |||||
* Set the bits on the trickle charger. | |||||
* Probably best left alone... | |||||
********************************************************************************* | |||||
*/ | |||||
void ds1302trickleCharge (const int diodes, const int resistors) | |||||
{ | |||||
if (diodes + resistors == 0) | |||||
ds1302rtcWrite (RTC_TC, 0x5C) ; // Disabled | |||||
else | |||||
ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ; | |||||
} | |||||
/* | |||||
* ds1302setup: | |||||
* Initialise the chip & remember the pins we're using | |||||
********************************************************************************* | |||||
*/ | |||||
void ds1302setup (const int clockPin, const int dataPin, const int csPin) | |||||
{ | |||||
dPin = dataPin ; | |||||
cPin = clockPin ; | |||||
sPin = csPin ; | |||||
digitalWrite (dPin, LOW) ; | |||||
digitalWrite (cPin, LOW) ; | |||||
digitalWrite (sPin, LOW) ; | |||||
pinMode (dPin, OUTPUT) ; | |||||
pinMode (cPin, OUTPUT) ; | |||||
pinMode (sPin, OUTPUT) ; | |||||
ds1302rtcWrite (RTC_WP, 0) ; // Remove write-protect | |||||
} |
@@ -1,10 +1,8 @@ | |||||
/* | /* | ||||
* lcd.h: | |||||
* Text-based LCD driver. | |||||
* This is designed to drive the parallel interface LCD drivers | |||||
* based in the Hitachi HD44780U controller and compatables. | |||||
* ds1302.h: | |||||
* Real Time clock | |||||
* | * | ||||
* Copyright (c) 2012 Gordon Henderson. | |||||
* Copyright (c) 2013 Gordon Henderson. | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -24,22 +22,22 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#define MAX_LCDS 8 | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
#endif | #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 unsigned int ds1302rtcRead (const int reg) ; | |||||
extern void ds1302rtcWrite (const int reg, const unsigned int data) ; | |||||
extern unsigned int ds1302ramRead (const int addr) ; | |||||
extern void ds1302ramWrite (const int addr, const unsigned int data) ; | |||||
extern void ds1302clockRead (int clockData [8]) ; | |||||
extern void ds1302clockWrite (const int clockData [8]) ; | |||||
extern void ds1302trickleCharge (const int diodes, const int resistors) ; | |||||
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) ; | |||||
extern void ds1302setup (const int clockPin, const int dataPin, const int csPin) ; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } |
@@ -38,16 +38,17 @@ | |||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <linux/spi/spidev.h> | #include <linux/spi/spidev.h> | ||||
#include "wiringPiSPI.h" | |||||
#include <wiringPi.h> | |||||
#include <wiringPiSPI.h> | |||||
#include "gertboard.h" | #include "gertboard.h" | ||||
// The A-D convertor won't run at more than 1MHz @ 3.3v | // 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 | |||||
#define SPI_ADC_SPEED 1000000 | |||||
#define SPI_DAC_SPEED 1000000 | |||||
#define SPI_A2D 0 | |||||
#define SPI_D2A 1 | |||||
/* | /* | ||||
@@ -57,7 +58,7 @@ | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void gertboardAnalogWrite (int chan, int value) | |||||
void gertboardAnalogWrite (const int chan, const int value) | |||||
{ | { | ||||
uint8_t spiData [2] ; | uint8_t spiData [2] ; | ||||
uint8_t chanBits, dataBits ; | uint8_t chanBits, dataBits ; | ||||
@@ -84,7 +85,7 @@ void gertboardAnalogWrite (int chan, int value) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int gertboardAnalogRead (int chan) | |||||
int gertboardAnalogRead (const int chan) | |||||
{ | { | ||||
uint8_t spiData [2] ; | uint8_t spiData [2] ; | ||||
@@ -120,3 +121,44 @@ int gertboardSPISetup (void) | |||||
return 0 ; | return 0 ; | ||||
} | } | ||||
/* | |||||
* New wiringPi node extension methods. | |||||
********************************************************************************* | |||||
*/ | |||||
static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan) | |||||
{ | |||||
return gertboardAnalogRead (chan - node->pinBase) ; | |||||
} | |||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value) | |||||
{ | |||||
gertboardAnalogWrite (chan - node->pinBase, value) ; | |||||
} | |||||
/* | |||||
* gertboardAnalogSetup: | |||||
* Create a new wiringPi device node for the analog devices on the | |||||
* Gertboard. We create one node with 2 pins - each pin being read | |||||
* and write - although the operations actually go to different | |||||
* hardware devices. | |||||
********************************************************************************* | |||||
*/ | |||||
int gertboardAnalogSetup (const int pinBase) | |||||
{ | |||||
struct wiringPiNodeStruct *node ; | |||||
int x ; | |||||
if (( x = gertboardSPISetup ()) != 0) | |||||
return x; | |||||
node = wiringPiNewNode (pinBase, 2) ; | |||||
node->analogRead = myAnalogRead ; | |||||
node->analogWrite = myAnalogWrite ; | |||||
return 0 ; | |||||
} |
@@ -30,10 +30,16 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
extern void gertboardAnalogWrite (int chan, int value) ; | |||||
extern int gertboardAnalogRead (int chan) ; | |||||
// Old routines | |||||
extern void gertboardAnalogWrite (const int chan, const int value) ; | |||||
extern int gertboardAnalogRead (const int chan) ; | |||||
extern int gertboardSPISetup (void) ; | extern int gertboardSPISetup (void) ; | ||||
// New | |||||
extern int gertboardAnalogSetup (const int pinBase) ; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif |
@@ -26,29 +26,40 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdint.h> | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include "wiringPi.h" | |||||
#include <wiringPi.h> | |||||
#include "lcd.h" | #include "lcd.h" | ||||
// Commands | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
// HD44780U Commands | |||||
#define LCD_CLEAR 0x01 | #define LCD_CLEAR 0x01 | ||||
#define LCD_HOME 0x02 | #define LCD_HOME 0x02 | ||||
#define LCD_ENTRY 0x04 | #define LCD_ENTRY 0x04 | ||||
#define LCD_ON_OFF 0x08 | |||||
#define LCD_CTRL 0x08 | |||||
#define LCD_CDSHIFT 0x10 | #define LCD_CDSHIFT 0x10 | ||||
#define LCD_FUNC 0x20 | #define LCD_FUNC 0x20 | ||||
#define LCD_CGRAM 0x40 | #define LCD_CGRAM 0x40 | ||||
#define LCD_DGRAM 0x80 | #define LCD_DGRAM 0x80 | ||||
#define LCD_ENTRY_SH 0x01 | |||||
#define LCD_ENTRY_ID 0x02 | |||||
// Bits in the entry register | |||||
#define LCD_ENTRY_SH 0x01 | |||||
#define LCD_ENTRY_ID 0x02 | |||||
// Bits in the control register | |||||
#define LCD_ON_OFF_B 0x01 | |||||
#define LCD_ON_OFF_C 0x02 | |||||
#define LCD_ON_OFF_D 0x04 | |||||
#define LCD_BLINK_CTRL 0x01 | |||||
#define LCD_CURSOR_CTRL 0x02 | |||||
#define LCD_DISPLAY_CTRL 0x04 | |||||
// Bits in the function register | |||||
#define LCD_FUNC_F 0x04 | #define LCD_FUNC_F 0x04 | ||||
#define LCD_FUNC_N 0x08 | #define LCD_FUNC_N 0x08 | ||||
@@ -58,13 +69,20 @@ | |||||
struct lcdDataStruct | struct lcdDataStruct | ||||
{ | { | ||||
uint8_t bits, rows, cols ; | |||||
uint8_t rsPin, strbPin ; | |||||
uint8_t dataPins [8] ; | |||||
int bits, rows, cols ; | |||||
int rsPin, strbPin ; | |||||
int dataPins [8] ; | |||||
int cx, cy ; | |||||
} ; | } ; | ||||
struct lcdDataStruct *lcds [MAX_LCDS] ; | struct lcdDataStruct *lcds [MAX_LCDS] ; | ||||
static int lcdControl ; | |||||
// Row offsets | |||||
static const int rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; | |||||
/* | /* | ||||
* strobe: | * strobe: | ||||
@@ -73,7 +91,7 @@ struct lcdDataStruct *lcds [MAX_LCDS] ; | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
static void strobe (struct lcdDataStruct *lcd) | |||||
static void strobe (const struct lcdDataStruct *lcd) | |||||
{ | { | ||||
// Note timing changes for new version of delayMicroseconds () | // Note timing changes for new version of delayMicroseconds () | ||||
@@ -89,13 +107,14 @@ static void strobe (struct lcdDataStruct *lcd) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) | |||||
static void sendDataCmd (const struct lcdDataStruct *lcd, unsigned char data) | |||||
{ | { | ||||
uint8_t i, d4 ; | |||||
register unsigned char myData = data ; | |||||
unsigned char i, d4 ; | |||||
if (lcd->bits == 4) | if (lcd->bits == 4) | ||||
{ | { | ||||
d4 = (data >> 4) & 0x0F; | |||||
d4 = (myData >> 4) & 0x0F; | |||||
for (i = 0 ; i < 4 ; ++i) | for (i = 0 ; i < 4 ; ++i) | ||||
{ | { | ||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | ||||
@@ -103,7 +122,7 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) | |||||
} | } | ||||
strobe (lcd) ; | strobe (lcd) ; | ||||
d4 = data & 0x0F ; | |||||
d4 = myData & 0x0F ; | |||||
for (i = 0 ; i < 4 ; ++i) | for (i = 0 ; i < 4 ; ++i) | ||||
{ | { | ||||
digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | digitalWrite (lcd->dataPins [i], (d4 & 1)) ; | ||||
@@ -114,8 +133,8 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) | |||||
{ | { | ||||
for (i = 0 ; i < 8 ; ++i) | for (i = 0 ; i < 8 ; ++i) | ||||
{ | { | ||||
digitalWrite (lcd->dataPins [i], (data & 1)) ; | |||||
data >>= 1 ; | |||||
digitalWrite (lcd->dataPins [i], (myData & 1)) ; | |||||
myData >>= 1 ; | |||||
} | } | ||||
} | } | ||||
strobe (lcd) ; | strobe (lcd) ; | ||||
@@ -128,22 +147,24 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
static void putCommand (struct lcdDataStruct *lcd, uint8_t command) | |||||
static void putCommand (const struct lcdDataStruct *lcd, unsigned char command) | |||||
{ | { | ||||
digitalWrite (lcd->rsPin, 0) ; | digitalWrite (lcd->rsPin, 0) ; | ||||
sendDataCmd (lcd, command) ; | sendDataCmd (lcd, command) ; | ||||
delay (2) ; | |||||
} | } | ||||
static void put4Command (struct lcdDataStruct *lcd, uint8_t command) | |||||
static void put4Command (const struct lcdDataStruct *lcd, unsigned char command) | |||||
{ | { | ||||
uint8_t i ; | |||||
register unsigned char myCommand = command ; | |||||
register unsigned char i ; | |||||
digitalWrite (lcd->rsPin, 0) ; | digitalWrite (lcd->rsPin, 0) ; | ||||
for (i = 0 ; i < 4 ; ++i) | for (i = 0 ; i < 4 ; ++i) | ||||
{ | { | ||||
digitalWrite (lcd->dataPins [i], (command & 1)) ; | |||||
command >>= 1 ; | |||||
digitalWrite (lcd->dataPins [i], (myCommand & 1)) ; | |||||
myCommand >>= 1 ; | |||||
} | } | ||||
strobe (lcd) ; | strobe (lcd) ; | ||||
} | } | ||||
@@ -151,7 +172,7 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command) | |||||
/* | /* | ||||
********************************************************************************* | ********************************************************************************* | ||||
* User Code below here | |||||
* User Callable code below here | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -161,16 +182,66 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdHome (int fd) | |||||
void lcdHome (const int fd) | |||||
{ | { | ||||
struct lcdDataStruct *lcd = lcds [fd] ; | struct lcdDataStruct *lcd = lcds [fd] ; | ||||
putCommand (lcd, LCD_HOME) ; | putCommand (lcd, LCD_HOME) ; | ||||
lcd->cx = lcd->cy = 0 ; | |||||
delay (5) ; | |||||
} | } | ||||
void lcdClear (int fd) | |||||
void lcdClear (const int fd) | |||||
{ | { | ||||
struct lcdDataStruct *lcd = lcds [fd] ; | struct lcdDataStruct *lcd = lcds [fd] ; | ||||
putCommand (lcd, LCD_CLEAR) ; | putCommand (lcd, LCD_CLEAR) ; | ||||
putCommand (lcd, LCD_HOME) ; | |||||
lcd->cx = lcd->cy = 0 ; | |||||
delay (5) ; | |||||
} | |||||
/* | |||||
* lcdDisplay: lcdCursor: lcdCursorBlink: | |||||
* Turn the display, cursor, cursor blinking on/off | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdDisplay (const int fd, int state) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
if (state) | |||||
lcdControl |= LCD_DISPLAY_CTRL ; | |||||
else | |||||
lcdControl &= ~LCD_DISPLAY_CTRL ; | |||||
putCommand (lcd, LCD_CTRL | lcdControl) ; | |||||
} | |||||
void lcdCursor (const int fd, int state) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
if (state) | |||||
lcdControl |= LCD_CURSOR_CTRL ; | |||||
else | |||||
lcdControl &= ~LCD_CURSOR_CTRL ; | |||||
putCommand (lcd, LCD_CTRL | lcdControl) ; | |||||
} | |||||
void lcdCursorBlink (const int fd, int state) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
if (state) | |||||
lcdControl |= LCD_BLINK_CTRL ; | |||||
else | |||||
lcdControl &= ~LCD_BLINK_CTRL ; | |||||
putCommand (lcd, LCD_CTRL | lcdControl) ; | |||||
} | } | ||||
@@ -180,40 +251,77 @@ void lcdClear (int fd) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdSendCommand (int fd, uint8_t command) | |||||
void lcdSendCommand (const int fd, unsigned char command) | |||||
{ | { | ||||
struct lcdDataStruct *lcd = lcds [fd] ; | struct lcdDataStruct *lcd = lcds [fd] ; | ||||
putCommand (lcd, command) ; | putCommand (lcd, command) ; | ||||
} | } | ||||
/* | /* | ||||
* lcdPosition: | * lcdPosition: | ||||
* Update the position of the cursor on the display | |||||
* Update the position of the cursor on the display. | |||||
* Ignore invalid locations. | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdPosition (int fd, int x, int y) | |||||
void lcdPosition (const int fd, int x, int y) | |||||
{ | { | ||||
static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | struct lcdDataStruct *lcd = lcds [fd] ; | ||||
if ((x > lcd->cols) || (x < 0)) | |||||
return ; | |||||
if ((y > lcd->rows) || (y < 0)) | |||||
return ; | |||||
putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; | putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; | ||||
lcd->cx = x ; | |||||
lcd->cy = y ; | |||||
} | |||||
/* | |||||
* lcdCharDef: | |||||
* Defines a new character in the CGRAM | |||||
********************************************************************************* | |||||
*/ | |||||
void lcdCharDef (const int fd, int index, unsigned char data [8]) | |||||
{ | |||||
struct lcdDataStruct *lcd = lcds [fd] ; | |||||
int i ; | |||||
putCommand (lcd, LCD_CGRAM | ((index & 7) << 3)) ; | |||||
digitalWrite (lcd->rsPin, 1) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
sendDataCmd (lcd, data [i]) ; | |||||
} | } | ||||
/* | /* | ||||
* lcdPutchar: | * lcdPutchar: | ||||
* Send a data byte to be displayed on the display | |||||
* Send a data byte to be displayed on the display. We implement a very | |||||
* simple terminal here - with line wrapping, but no scrolling. Yet. | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdPutchar (int fd, uint8_t data) | |||||
void lcdPutchar (const int fd, unsigned char data) | |||||
{ | { | ||||
struct lcdDataStruct *lcd = lcds [fd] ; | struct lcdDataStruct *lcd = lcds [fd] ; | ||||
digitalWrite (lcd->rsPin, 1) ; | digitalWrite (lcd->rsPin, 1) ; | ||||
sendDataCmd (lcd, data) ; | |||||
sendDataCmd (lcd, data) ; | |||||
if (++lcd->cx == lcd->cols) | |||||
{ | |||||
lcd->cx = 0 ; | |||||
if (++lcd->cy == lcd->rows) | |||||
lcd->cy = 0 ; | |||||
putCommand (lcd, lcd->cx + (LCD_DGRAM | rowOff [lcd->cy])) ; | |||||
} | |||||
} | } | ||||
@@ -223,7 +331,7 @@ void lcdPutchar (int fd, uint8_t data) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdPuts (int fd, char *string) | |||||
void lcdPuts (const int fd, const char *string) | |||||
{ | { | ||||
while (*string) | while (*string) | ||||
lcdPutchar (fd, *string++) ; | lcdPutchar (fd, *string++) ; | ||||
@@ -236,7 +344,7 @@ void lcdPuts (int fd, char *string) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void lcdPrintf (int fd, char *message, ...) | |||||
void lcdPrintf (const int fd, const char *message, ...) | |||||
{ | { | ||||
va_list argp ; | va_list argp ; | ||||
char buffer [1024] ; | char buffer [1024] ; | ||||
@@ -256,12 +364,14 @@ void lcdPrintf (int fd, char *message, ...) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
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) | |||||
int lcdInit (const int rows, const int cols, const int bits, | |||||
const int rs, const int strb, | |||||
const int d0, const int d1, const int d2, const int d3, const int d4, | |||||
const int d5, const int d6, const int d7) | |||||
{ | { | ||||
static int initialised = 0 ; | static int initialised = 0 ; | ||||
uint8_t func ; | |||||
unsigned char func ; | |||||
int i ; | int i ; | ||||
int lcdFd = -1 ; | int lcdFd = -1 ; | ||||
struct lcdDataStruct *lcd ; | struct lcdDataStruct *lcd ; | ||||
@@ -298,7 +408,7 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb, | |||||
if (lcdFd == -1) | if (lcdFd == -1) | ||||
return -1 ; | return -1 ; | ||||
lcd = malloc (sizeof (struct lcdDataStruct)) ; | |||||
lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ; | |||||
if (lcd == NULL) | if (lcd == NULL) | ||||
return -1 ; | return -1 ; | ||||
@@ -307,6 +417,8 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb, | |||||
lcd->bits = 8 ; // For now - we'll set it properly later. | lcd->bits = 8 ; // For now - we'll set it properly later. | ||||
lcd->rows = rows ; | lcd->rows = rows ; | ||||
lcd->cols = cols ; | lcd->cols = cols ; | ||||
lcd->cx = 0 ; | |||||
lcd->cy = 0 ; | |||||
lcd->dataPins [0] = d0 ; | lcd->dataPins [0] = d0 ; | ||||
lcd->dataPins [1] = d1 ; | lcd->dataPins [1] = d1 ; | ||||
@@ -371,10 +483,13 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb, | |||||
// Rest of the initialisation sequence | // 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) ; | |||||
lcdDisplay (lcdFd, TRUE) ; | |||||
lcdCursor (lcdFd, FALSE) ; | |||||
lcdCursorBlink (lcdFd, FALSE) ; | |||||
lcdClear (lcdFd) ; | |||||
putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; | |||||
putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; | |||||
return lcdFd ; | return lcdFd ; | ||||
} | } |
@@ -0,0 +1,52 @@ | |||||
/* | |||||
* 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 (const int fd) ; | |||||
extern void lcdClear (const int fd) ; | |||||
extern void lcdDisplay (const int fd, int state) ; | |||||
extern void lcdCursor (const int fd, int state) ; | |||||
extern void lcdCursorBlink (const int fd, int state) ; | |||||
extern void lcdSendCommand (const int fd, unsigned char command) ; | |||||
extern void lcdPosition (const int fd, int x, int y) ; | |||||
extern void lcdCharDef (const int fd, int index, unsigned char data [8]) ; | |||||
extern void lcdPutchar (const int fd, unsigned char data) ; | |||||
extern void lcdPuts (const int fd, const char *string) ; | |||||
extern void lcdPrintf (const int fd, const char *message, ...) ; | |||||
extern int lcdInit (const int rows, const int cols, const int bits, | |||||
const int rs, const int strb, | |||||
const int d0, const int d1, const int d2, const int d3, const int d4, | |||||
const int d5, const int d6, const int d7) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -0,0 +1,673 @@ | |||||
/* | |||||
* lcd128x64.c: | |||||
* Graphics-based LCD driver. | |||||
* This is designed to drive the parallel interface LCD drivers | |||||
* based on the generic 12864H chips | |||||
* | |||||
* There are many variations on these chips, however they all mostly | |||||
* seem to be similar. | |||||
* This implementation has the Pins from the Pi hard-wired into it, | |||||
* in particular wiringPi pins 0-7 so that we can use | |||||
* digitalWriteByete() to speed things up somewhat. | |||||
* | |||||
* 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 <stdlib.h> | |||||
#include <wiringPi.h> | |||||
#include "font.h" | |||||
#include "lcd128x64.h" | |||||
// Size | |||||
#define LCD_WIDTH 128 | |||||
#define LCD_HEIGHT 64 | |||||
// Hardware Pins | |||||
// Note pins 0-7 are the 8-bit data port | |||||
#define CS1 10 | |||||
#define CS2 11 | |||||
#define STROBE 12 | |||||
#define RS 13 | |||||
// Software copy of the framebuffer | |||||
// it's 8-bit deep although the display itself is only 1-bit deep. | |||||
static unsigned char frameBuffer [LCD_WIDTH * LCD_HEIGHT] ; | |||||
static int maxX, maxY ; | |||||
static int lastX, lastY ; | |||||
static int xOrigin, yOrigin ; | |||||
static int lcdOrientation = 0 ; | |||||
/* | |||||
* 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 (void) | |||||
{ | |||||
digitalWrite (STROBE, 1) ; delayMicroseconds (1) ; | |||||
digitalWrite (STROBE, 0) ; delayMicroseconds (5) ; | |||||
} | |||||
/* | |||||
* sentData: | |||||
* Send an data or command byte to the display. | |||||
********************************************************************************* | |||||
*/ | |||||
static void sendData (const int data, const int chip) | |||||
{ | |||||
digitalWrite (chip, 0) ; | |||||
digitalWriteByte (data) ; | |||||
strobe () ; | |||||
digitalWrite (chip, 1) ; | |||||
} | |||||
/* | |||||
* sendCommand: | |||||
* Send a command byte to the display | |||||
********************************************************************************* | |||||
*/ | |||||
static void sendCommand (const int command, const int chip) | |||||
{ | |||||
digitalWrite (RS, 0) ; | |||||
sendData (command, chip) ; | |||||
digitalWrite (RS, 1) ; | |||||
} | |||||
/* | |||||
* setCol: SetLine: | |||||
* Set the column and line addresses | |||||
********************************************************************************* | |||||
*/ | |||||
static void setCol (int col, const int chip) | |||||
{ sendCommand (0x40 | (col & 0x3F), chip) ; } | |||||
static void setLine (int line, const int chip) | |||||
{ sendCommand (0xB8 | (line & 0x07), chip) ; } | |||||
/* | |||||
* lcd128x64update: | |||||
* Copy our software version to the real display | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64update (void) | |||||
{ | |||||
int line, x, y, fbLoc ; | |||||
unsigned char byte ; | |||||
// Left side | |||||
for (line = 0 ; line < 8 ; ++line) | |||||
{ | |||||
setCol (0, CS1) ; | |||||
setLine (line, CS1) ; | |||||
for (x = 63 ; x >= 0 ; --x) | |||||
{ | |||||
byte = 0 ; | |||||
for (y = 0 ; y < 8 ; ++y) | |||||
{ | |||||
fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ; | |||||
if (frameBuffer [fbLoc] != 0) | |||||
byte |= (1 << y) ; | |||||
} | |||||
sendData (byte, CS1) ; | |||||
} | |||||
} | |||||
// Right side | |||||
for (line = 0 ; line < 8 ; ++line) | |||||
{ | |||||
setCol (0, CS2) ; | |||||
setLine (line, CS2) ; | |||||
for (x = 127 ; x >= 64 ; --x) | |||||
{ | |||||
byte = 0 ; | |||||
for (y = 0 ; y < 8 ; ++y) | |||||
{ | |||||
fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ; | |||||
if (frameBuffer [fbLoc] != 0) | |||||
byte |= (1 << y) ; | |||||
} | |||||
sendData (byte, CS2) ; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64setOrigin: | |||||
* Set the display offset origin | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64setOrigin (int x, int y) | |||||
{ | |||||
xOrigin = x ; | |||||
yOrigin = y ; | |||||
} | |||||
/* | |||||
* lcd128x64setOrientation: | |||||
* Set the display orientation: | |||||
* 0: Normal, the display is portrait mode, 0,0 is top left | |||||
* 1: Landscape | |||||
* 2: Portrait, flipped | |||||
* 3: Landscape, flipped | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64setOrientation (int orientation) | |||||
{ | |||||
lcdOrientation = orientation & 3 ; | |||||
lcd128x64setOrigin (0,0) ; | |||||
switch (lcdOrientation) | |||||
{ | |||||
case 0: | |||||
maxX = LCD_WIDTH ; | |||||
maxY = LCD_HEIGHT ; | |||||
break ; | |||||
case 1: | |||||
maxX = LCD_HEIGHT ; | |||||
maxY = LCD_WIDTH ; | |||||
break ; | |||||
case 2: | |||||
maxX = LCD_WIDTH ; | |||||
maxY = LCD_HEIGHT ; | |||||
break ; | |||||
case 3: | |||||
maxX = LCD_HEIGHT ; | |||||
maxY = LCD_WIDTH ; | |||||
break ; | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64orientCoordinates: | |||||
* Adjust the coordinates given to the display orientation | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64orientCoordinates (int *x, int *y) | |||||
{ | |||||
register int tmp ; | |||||
*x += xOrigin ; | |||||
*y += yOrigin ; | |||||
*y = maxY - *y - 1 ; | |||||
switch (lcdOrientation) | |||||
{ | |||||
case 0: | |||||
break; | |||||
case 1: | |||||
tmp = maxY - *y - 1 ; | |||||
*y = *x ; | |||||
*x = tmp ; | |||||
break; | |||||
case 2: | |||||
*x = maxX - *x - 1 ; | |||||
*y = maxY - *y - 1 ; | |||||
break; | |||||
case 3: | |||||
*x = maxX - *x - 1 ; | |||||
tmp = *y ; | |||||
*y = *x ; | |||||
*x = tmp ; | |||||
break ; | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64getScreenSize: | |||||
* Return the max X & Y screen sizes. Needs to be called again, if you | |||||
* change screen orientation. | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64getScreenSize (int *x, int *y) | |||||
{ | |||||
*x = maxX ; | |||||
*y = maxY ; | |||||
} | |||||
/* | |||||
********************************************************************************* | |||||
* Standard Graphical Functions | |||||
********************************************************************************* | |||||
*/ | |||||
/* | |||||
* lcd128x64point: | |||||
* Plot a pixel. | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64point (int x, int y, int colour) | |||||
{ | |||||
lastX = x ; | |||||
lastY = y ; | |||||
lcd128x64orientCoordinates (&x, &y) ; | |||||
if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT)) | |||||
return ; | |||||
frameBuffer [x + y * LCD_WIDTH] = colour ; | |||||
} | |||||
/* | |||||
* lcd128x64line: lcd128x64lineTo: | |||||
* Classic Bressenham Line code | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64line (int x0, int y0, int x1, int y1, int colour) | |||||
{ | |||||
int dx, dy ; | |||||
int sx, sy ; | |||||
int err, e2 ; | |||||
lastX = x1 ; | |||||
lastY = y1 ; | |||||
dx = abs (x1 - x0) ; | |||||
dy = abs (y1 - y0) ; | |||||
sx = (x0 < x1) ? 1 : -1 ; | |||||
sy = (y0 < y1) ? 1 : -1 ; | |||||
err = dx - dy ; | |||||
for (;;) | |||||
{ | |||||
lcd128x64point (x0, y0, colour) ; | |||||
if ((x0 == x1) && (y0 == y1)) | |||||
break ; | |||||
e2 = 2 * err ; | |||||
if (e2 > -dy) | |||||
{ | |||||
err -= dy ; | |||||
x0 += sx ; | |||||
} | |||||
if (e2 < dx) | |||||
{ | |||||
err += dx ; | |||||
y0 += sy ; | |||||
} | |||||
} | |||||
} | |||||
void lcd128x64lineTo (int x, int y, int colour) | |||||
{ | |||||
lcd128x64line (lastX, lastY, x, y, colour) ; | |||||
} | |||||
/* | |||||
* lcd128x64rectangle: | |||||
* A rectangle is a spoilt days fishing | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled) | |||||
{ | |||||
register int x ; | |||||
if (filled) | |||||
{ | |||||
/**/ if (x1 == x2) | |||||
lcd128x64line (x1, y1, x2, y2, colour) ; | |||||
else if (x1 < x2) | |||||
for (x = x1 ; x <= x2 ; ++x) | |||||
lcd128x64line (x, y1, x, y2, colour) ; | |||||
else | |||||
for (x = x2 ; x <= x1 ; ++x) | |||||
lcd128x64line (x, y1, x, y2, colour) ; | |||||
} | |||||
else | |||||
{ | |||||
lcd128x64line (x1, y1, x2, y1, colour) ; | |||||
lcd128x64lineTo (x2, y2, colour) ; | |||||
lcd128x64lineTo (x1, y2, colour) ; | |||||
lcd128x64lineTo (x1, y1, colour) ; | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64circle: | |||||
* This is the midpoint circle algorithm. | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64circle (int x, int y, int r, int colour, int filled) | |||||
{ | |||||
int ddF_x = 1 ; | |||||
int ddF_y = -2 * r ; | |||||
int f = 1 - r ; | |||||
int x1 = 0 ; | |||||
int y1 = r ; | |||||
if (filled) | |||||
{ | |||||
lcd128x64line (x, y + r, x, y - r, colour) ; | |||||
lcd128x64line (x + r, y, x - r, y, colour) ; | |||||
} | |||||
else | |||||
{ | |||||
lcd128x64point (x, y + r, colour) ; | |||||
lcd128x64point (x, y - r, colour) ; | |||||
lcd128x64point (x + r, y, colour) ; | |||||
lcd128x64point (x - r, y, colour) ; | |||||
} | |||||
while (x1 < y1) | |||||
{ | |||||
if (f >= 0) | |||||
{ | |||||
y1-- ; | |||||
ddF_y += 2 ; | |||||
f += ddF_y ; | |||||
} | |||||
x1++ ; | |||||
ddF_x += 2 ; | |||||
f += ddF_x ; | |||||
if (filled) | |||||
{ | |||||
lcd128x64line (x + x1, y + y1, x - x1, y + y1, colour) ; | |||||
lcd128x64line (x + x1, y - y1, x - x1, y - y1, colour) ; | |||||
lcd128x64line (x + y1, y + x1, x - y1, y + x1, colour) ; | |||||
lcd128x64line (x + y1, y - x1, x - y1, y - x1, colour) ; | |||||
} | |||||
else | |||||
{ | |||||
lcd128x64point (x + x1, y + y1, colour) ; lcd128x64point (x - x1, y + y1, colour) ; | |||||
lcd128x64point (x + x1, y - y1, colour) ; lcd128x64point (x - x1, y - y1, colour) ; | |||||
lcd128x64point (x + y1, y + x1, colour) ; lcd128x64point (x - y1, y + x1, colour) ; | |||||
lcd128x64point (x + y1, y - x1, colour) ; lcd128x64point (x - y1, y - x1, colour) ; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64ellipse: | |||||
* Fast ellipse drawing algorithm by | |||||
* John Kennedy | |||||
* Mathematics Department | |||||
* Santa Monica College | |||||
* 1900 Pico Blvd. | |||||
* Santa Monica, CA 90405 | |||||
* jrkennedy6@gmail.com | |||||
* -Confirned in email this algorithm is in the public domain -GH- | |||||
********************************************************************************* | |||||
*/ | |||||
static void plot4ellipsePoints (int cx, int cy, int x, int y, int colour, int filled) | |||||
{ | |||||
if (filled) | |||||
{ | |||||
lcd128x64line (cx + x, cy + y, cx - x, cy + y, colour) ; | |||||
lcd128x64line (cx - x, cy - y, cx + x, cy - y, colour) ; | |||||
} | |||||
else | |||||
{ | |||||
lcd128x64point (cx + x, cy + y, colour) ; | |||||
lcd128x64point (cx - x, cy + y, colour) ; | |||||
lcd128x64point (cx - x, cy - y, colour) ; | |||||
lcd128x64point (cx + x, cy - y, colour) ; | |||||
} | |||||
} | |||||
void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled) | |||||
{ | |||||
int x, y ; | |||||
int xChange, yChange, ellipseError ; | |||||
int twoAsquare, twoBsquare ; | |||||
int stoppingX, stoppingY ; | |||||
twoAsquare = 2 * xRadius * xRadius ; | |||||
twoBsquare = 2 * yRadius * yRadius ; | |||||
x = xRadius ; | |||||
y = 0 ; | |||||
xChange = yRadius * yRadius * (1 - 2 * xRadius) ; | |||||
yChange = xRadius * xRadius ; | |||||
ellipseError = 0 ; | |||||
stoppingX = twoBsquare * xRadius ; | |||||
stoppingY = 0 ; | |||||
while (stoppingX >= stoppingY) // 1st set of points | |||||
{ | |||||
plot4ellipsePoints (cx, cy, x, y, colour, filled) ; | |||||
++y ; | |||||
stoppingY += twoAsquare ; | |||||
ellipseError += yChange ; | |||||
yChange += twoAsquare ; | |||||
if ((2 * ellipseError + xChange) > 0 ) | |||||
{ | |||||
--x ; | |||||
stoppingX -= twoBsquare ; | |||||
ellipseError += xChange ; | |||||
xChange += twoBsquare ; | |||||
} | |||||
} | |||||
x = 0 ; | |||||
y = yRadius ; | |||||
xChange = yRadius * yRadius ; | |||||
yChange = xRadius * xRadius * (1 - 2 * yRadius) ; | |||||
ellipseError = 0 ; | |||||
stoppingX = 0 ; | |||||
stoppingY = twoAsquare * yRadius ; | |||||
while (stoppingX <= stoppingY) //2nd set of points | |||||
{ | |||||
plot4ellipsePoints (cx, cy, x, y, colour, filled) ; | |||||
++x ; | |||||
stoppingX += twoBsquare ; | |||||
ellipseError += xChange ; | |||||
xChange += twoBsquare ; | |||||
if ((2 * ellipseError + yChange) > 0 ) | |||||
{ | |||||
--y ; | |||||
stoppingY -= twoAsquare ; | |||||
ellipseError += yChange ; | |||||
yChange += twoAsquare ; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64putchar: | |||||
* Print a single character to the screen | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol) | |||||
{ | |||||
int y1, y2 ; | |||||
unsigned char line ; | |||||
unsigned char *fontPtr ; | |||||
// Can't print if we're offscreen | |||||
//if ((x < 0) || (x >= (maxX - fontWidth)) || (y < 0) || (y >= (maxY - fontHeight))) | |||||
// return ; | |||||
fontPtr = font + c * fontHeight ; | |||||
for (y1 = fontHeight - 1 ; y1 >= 0 ; --y1) | |||||
{ | |||||
y2 = y + y1 ; | |||||
line = *fontPtr++ ; | |||||
lcd128x64point (x + 0, y2, (line & 0x80) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 1, y2, (line & 0x40) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 2, y2, (line & 0x20) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 3, y2, (line & 0x10) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 4, y2, (line & 0x08) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 5, y2, (line & 0x04) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 6, y2, (line & 0x02) == 0 ? bgCol : fgCol) ; | |||||
lcd128x64point (x + 7, y2, (line & 0x01) == 0 ? bgCol : fgCol) ; | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64puts: | |||||
* Send a string to the display. Obeys \n and \r formatting | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol) | |||||
{ | |||||
int c, mx, my ; | |||||
mx = x ; my = y ; | |||||
while (*str) | |||||
{ | |||||
c = *str++ ; | |||||
if (c == '\r') | |||||
{ | |||||
mx = x ; | |||||
continue ; | |||||
} | |||||
if (c == '\n') | |||||
{ | |||||
mx = x ; | |||||
my -= fontHeight ; | |||||
continue ; | |||||
} | |||||
lcd128x64putchar (mx, my, c, bgCol, fgCol) ; | |||||
mx += fontWidth ; | |||||
if (mx >= (maxX - fontWidth)) | |||||
{ | |||||
mx = 0 ; | |||||
my -= fontHeight ; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* lcd128x64clear: | |||||
* Clear the display to the given colour. | |||||
********************************************************************************* | |||||
*/ | |||||
void lcd128x64clear (int colour) | |||||
{ | |||||
register int i ; | |||||
register unsigned char *ptr = frameBuffer ; | |||||
for (i = 0 ; i < (maxX * maxY) ; ++i) | |||||
*ptr++ = colour ; | |||||
} | |||||
/* | |||||
* lcd128x64setup: | |||||
* Initialise the display and GPIO. | |||||
********************************************************************************* | |||||
*/ | |||||
int lcd128x64setup (void) | |||||
{ | |||||
int i ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
pinMode (i, OUTPUT) ; | |||||
digitalWrite (CS1, 1) ; | |||||
digitalWrite (CS2, 1) ; | |||||
digitalWrite (STROBE, 0) ; | |||||
digitalWrite (RS, 1) ; | |||||
pinMode (CS1, OUTPUT) ; | |||||
pinMode (CS2, OUTPUT) ; | |||||
pinMode (STROBE, OUTPUT) ; | |||||
pinMode (RS, OUTPUT) ; | |||||
sendCommand (0x3F, CS1) ; // Display ON | |||||
sendCommand (0xC0, CS1) ; // Set display start line to 0 | |||||
sendCommand (0x3F, CS2) ; // Display ON | |||||
sendCommand (0xC0, CS2) ; // Set display start line to 0 | |||||
lcd128x64clear (0) ; | |||||
lcd128x64setOrientation (0) ; | |||||
lcd128x64update () ; | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,39 @@ | |||||
/* | |||||
* lcd128x64.h: | |||||
* | |||||
* 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/>. | |||||
*********************************************************************** | |||||
*/ | |||||
extern void lcd128x64setOrigin (int x, int y) ; | |||||
extern void lcd128x64setOrientation (int orientation) ; | |||||
extern void lcd128x64orientCoordinates (int *x, int *y) ; | |||||
extern void lcd128x64getScreenSize (int *x, int *y) ; | |||||
extern void lcd128x64point (int x, int y, int colour) ; | |||||
extern void lcd128x64line (int x0, int y0, int x1, int y1, int colour) ; | |||||
extern void lcd128x64lineTo (int x, int y, int colour) ; | |||||
extern void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled) ; | |||||
extern void lcd128x64circle (int x, int y, int r, int colour, int filled) ; | |||||
extern void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled) ; | |||||
extern void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol) ; | |||||
extern void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol) ; | |||||
extern void lcd128x64update (void) ; | |||||
extern void lcd128x64clear (int colour) ; | |||||
extern int lcd128x64setup (void) ; |
@@ -0,0 +1,165 @@ | |||||
/* | |||||
* maxdetect.c: | |||||
* Driver for the MaxDetect series sensors | |||||
* | |||||
* 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 <stdlib.h> | |||||
//#include <unistd.h> | |||||
#include <wiringPi.h> | |||||
#include "maxdetect.h" | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
/* | |||||
* maxDetectLowHighWait: | |||||
* Wait for a transition from high to low on the bus | |||||
********************************************************************************* | |||||
*/ | |||||
static void maxDetectLowHighWait (const int pin) | |||||
{ | |||||
unsigned int timeOut = millis () + 2000 ; | |||||
while (digitalRead (pin) == HIGH) | |||||
if (millis () > timeOut) | |||||
return ; | |||||
while (digitalRead (pin) == LOW) | |||||
if (millis () > timeOut) | |||||
return ; | |||||
} | |||||
/* | |||||
* maxDetectClockByte: | |||||
* Read in a single byte from the MaxDetect bus | |||||
********************************************************************************* | |||||
*/ | |||||
static unsigned int maxDetectClockByte (const int pin) | |||||
{ | |||||
unsigned int byte = 0 ; | |||||
int bit ; | |||||
for (bit = 0 ; bit < 8 ; ++bit) | |||||
{ | |||||
maxDetectLowHighWait (pin) ; | |||||
// bit starting now - we need to time it. | |||||
delayMicroseconds (30) ; | |||||
byte <<= 1 ; | |||||
if (digitalRead (pin) == HIGH) // It's a 1 | |||||
byte |= 1 ; | |||||
} | |||||
return byte ; | |||||
} | |||||
/* | |||||
* maxDetectRead: | |||||
* Read in and return the 4 data bytes from the MaxDetect sensor. | |||||
* Return TRUE/FALSE depending on the checksum validity | |||||
********************************************************************************* | |||||
*/ | |||||
int maxDetectRead (const int pin, unsigned char buffer [4]) | |||||
{ | |||||
int i ; | |||||
unsigned int checksum ; | |||||
unsigned char localBuf [5] ; | |||||
// Wake up the RHT03 by pulling the data line low, then high | |||||
// Low for 10mS, high for 40uS. | |||||
pinMode (pin, OUTPUT) ; | |||||
digitalWrite (pin, 0) ; delay (10) ; | |||||
digitalWrite (pin, 1) ; delayMicroseconds (40) ; | |||||
pinMode (pin, INPUT) ; | |||||
// Now wait for sensor to pull pin low | |||||
maxDetectLowHighWait (pin) ; | |||||
// and read in 5 bytes (40 bits) | |||||
for (i = 0 ; i < 5 ; ++i) | |||||
localBuf [i] = maxDetectClockByte (pin) ; | |||||
checksum = 0 ; | |||||
for (i = 0 ; i < 4 ; ++i) | |||||
{ | |||||
buffer [i] = localBuf [i] ; | |||||
checksum += localBuf [i] ; | |||||
} | |||||
checksum &= 0xFF ; | |||||
return checksum == localBuf [4] ; | |||||
} | |||||
/* | |||||
* readRHT03: | |||||
* Read the Temperature & Humidity from an RHT03 sensor | |||||
********************************************************************************* | |||||
*/ | |||||
int readRHT03 (const int pin, int *temp, int *rh) | |||||
{ | |||||
static unsigned int nextTime = 0 ; | |||||
static int lastTemp = 0 ; | |||||
static int lastRh = 0 ; | |||||
static int lastResult = TRUE ; | |||||
unsigned char buffer [4] ; | |||||
// Don't read more than once a second | |||||
if (millis () < nextTime) | |||||
{ | |||||
*temp = lastTemp ; | |||||
*rh = lastRh ; | |||||
return lastResult ; | |||||
} | |||||
lastResult = maxDetectRead (pin, buffer) ; | |||||
if (lastResult) | |||||
{ | |||||
*temp = lastTemp = (buffer [2] * 256 + buffer [3]) ; | |||||
*rh = lastRh = (buffer [0] * 256 + buffer [1]) ; | |||||
nextTime = millis () + 2000 ; | |||||
return TRUE ; | |||||
} | |||||
else | |||||
{ | |||||
return FALSE ; | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
/* | |||||
* maxdetect.h: | |||||
* Driver for the MaxDetect series sensors | |||||
* | |||||
* 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 | |||||
// Main generic function | |||||
int maxDetectRead (const int pin, unsigned char buffer [4]) ; | |||||
// Individual sensors | |||||
int readRHT03 (const int pin, int *temp, int *rh) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -0,0 +1,112 @@ | |||||
/* | |||||
* piFace.: | |||||
* This file to interface with the PiFace peripheral device which | |||||
* has an MCP23S17 GPIO device connected via the SPI bus. | |||||
* | |||||
* 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 <stdio.h> | |||||
#include <stdint.h> | |||||
#include <wiringPi.h> | |||||
#include <mcp23s17.h> | |||||
#include "piFace.h" | |||||
/* | |||||
* myDigitalWrite: | |||||
* Perform the digitalWrite function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) | |||||
{ | |||||
digitalWrite (pin + 16, value) ; | |||||
} | |||||
/* | |||||
* myDigitalRead: | |||||
* Perform the digitalRead function on the PiFace board | |||||
* With a slight twist - if we read from base + 8, then we | |||||
* read from the output latch... | |||||
********************************************************************************* | |||||
*/ | |||||
int myDigitalRead (struct wiringPiNodeStruct *node, int pin) | |||||
{ | |||||
if ((pin - node->pinBase) >= 8) | |||||
return digitalRead (pin + 8) ; | |||||
else | |||||
return digitalRead (pin + 16 + 8) ; | |||||
} | |||||
/* | |||||
* myPullUpDnControl: | |||||
* Perform the pullUpDnControl function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) | |||||
{ | |||||
pullUpDnControl (pin + 16 + 8, pud) ; | |||||
} | |||||
/* | |||||
* piFaceSetup | |||||
* We're going to create an instance of the mcp23s17 here, then | |||||
* provide our own read/write routines on-top of it... | |||||
* The supplied PiFace code (in Pithon) treats it as an 8-bit device | |||||
* where you write the output ports and read the input port using the | |||||
* same pin numbers, however I have had a request to be able to read | |||||
* the output port, so reading 8..15 will read the output latch. | |||||
********************************************************************************* | |||||
*/ | |||||
int piFaceSetup (const int pinBase) | |||||
{ | |||||
int i ; | |||||
struct wiringPiNodeStruct *node ; | |||||
// Create an mcp23s17 instance: | |||||
mcp23s17Setup (pinBase + 16, 0, 0) ; | |||||
// Set the direction bits | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
{ | |||||
pinMode (pinBase + 16 + i, OUTPUT) ; // Port A is the outputs | |||||
pinMode (pinBase + 16 + 8 + i, INPUT) ; // Port B inputs. | |||||
} | |||||
node = wiringPiNewNode (pinBase, 16) ; | |||||
node->digitalRead = myDigitalRead ; | |||||
node->digitalWrite = myDigitalWrite ; | |||||
node->pullUpDnControl = myPullUpDnControl ; | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,32 @@ | |||||
/* | |||||
* piFace.h: | |||||
* Control the PiFace Interface board for the Raspberry Pi | |||||
* 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 piFaceSetup (const int pinBase) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -0,0 +1,178 @@ | |||||
/* | |||||
* piFace.: | |||||
* Arduino compatable (ish) Wiring library for the Raspberry Pi | |||||
* Copyright (c) 2012-2013 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 <wiringPi.h> | |||||
#include <wiringPiSPI.h> | |||||
#include "../wiringPi/mcp23x0817.h" | |||||
#include "piFace.h" | |||||
#define PIFACE_SPEED 4000000 | |||||
#define PIFACE_DEVNO 0 | |||||
/* | |||||
* writeByte: | |||||
* Write a byte to a register on the MCP23S17 on the SPI bus. | |||||
********************************************************************************* | |||||
*/ | |||||
static void writeByte (uint8_t reg, uint8_t data) | |||||
{ | |||||
uint8_t spiData [4] ; | |||||
spiData [0] = CMD_WRITE ; | |||||
spiData [1] = reg ; | |||||
spiData [2] = data ; | |||||
wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; | |||||
} | |||||
/* | |||||
* readByte: | |||||
* Read a byte from a register on the MCP23S17 on the SPI bus. | |||||
********************************************************************************* | |||||
*/ | |||||
static uint8_t readByte (uint8_t reg) | |||||
{ | |||||
uint8_t spiData [4] ; | |||||
spiData [0] = CMD_READ ; | |||||
spiData [1] = reg ; | |||||
wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; | |||||
return spiData [2] ; | |||||
} | |||||
/* | |||||
* myDigitalWrite: | |||||
* Perform the digitalWrite function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) | |||||
{ | |||||
uint8_t mask, old ; | |||||
pin -= node->pinBase ; | |||||
mask = 1 << pin ; | |||||
old = readByte (MCP23x17_GPIOA) ; | |||||
if (value == 0) | |||||
old &= (~mask) ; | |||||
else | |||||
old |= mask ; | |||||
writeByte (MCP23x17_GPIOA, old) ; | |||||
} | |||||
/* | |||||
* myDigitalRead: | |||||
* Perform the digitalRead function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
int myDigitalRead (struct wiringPiNodeStruct *node, int pin) | |||||
{ | |||||
uint8_t mask, reg ; | |||||
mask = 1 << ((pin - node->pinBase) & 7) ; | |||||
if (pin < 8) | |||||
reg = MCP23x17_GPIOB ; // Input regsiter | |||||
else | |||||
reg = MCP23x17_OLATA ; // Output latch regsiter | |||||
if ((readByte (reg) & mask) != 0) | |||||
return HIGH ; | |||||
else | |||||
return LOW ; | |||||
} | |||||
/* | |||||
* myPullUpDnControl: | |||||
* Perform the pullUpDnControl function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) | |||||
{ | |||||
uint8_t mask, old ; | |||||
mask = 1 << (pin - node->pinBase) ; | |||||
old = readByte (MCP23x17_GPPUB) ; | |||||
if (pud == 0) | |||||
old &= (~mask) ; | |||||
else | |||||
old |= mask ; | |||||
writeByte (MCP23x17_GPPUB, old) ; | |||||
} | |||||
/* | |||||
* piFaceSetup | |||||
* Setup the SPI interface and initialise the MCP23S17 chip | |||||
* We create one node with 16 pins - each if the first 8 pins being read | |||||
* and write - although the operations actually go to different | |||||
* hardware ports. The top 8 let you read the state of the output register. | |||||
********************************************************************************* | |||||
*/ | |||||
int piFaceSetup (const int pinBase) | |||||
{ | |||||
int x ; | |||||
struct wiringPiNodeStruct *node ; | |||||
if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0) | |||||
return x ; | |||||
// Setup the MCP23S17 | |||||
writeByte (MCP23x17_IOCON, IOCON_INIT) ; | |||||
writeByte (MCP23x17_IODIRA, 0x00) ; // Port A -> Outputs | |||||
writeByte (MCP23x17_IODIRB, 0xFF) ; // Port B -> Inputs | |||||
node = wiringPiNewNode (pinBase, 16) ; | |||||
node->digitalRead = myDigitalRead ; | |||||
node->digitalWrite = myDigitalWrite ; | |||||
node->pullUpDnControl = myPullUpDnControl ; | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,221 @@ | |||||
/* | |||||
* 7segments.c: | |||||
* Simple test program to see if we can drive a 7-segment LED | |||||
* display using the GPIO and little else on the Raspberry Pi | |||||
* | |||||
* Copyright (c) 2013 Gordon Henderson | |||||
*********************************************************************** | |||||
*/ | |||||
#undef PHOTO_HACK | |||||
#include <wiringPi.h> | |||||
#include <stdio.h> | |||||
#include <time.h> | |||||
#include <ctype.h> | |||||
#include <string.h> | |||||
/* | |||||
* Segment mapping | |||||
* | |||||
* --a-- | |||||
* | | | |||||
* f b | |||||
* | | | |||||
* --g-- | |||||
* | | | |||||
* e c | |||||
* | | | |||||
* --d-- p | |||||
*/ | |||||
// GPIO Pin Mapping | |||||
static int digits [6] = { 7, 11, 10, 13, 12, 14 } ; | |||||
static int segments [7] = { 6, 5, 4, 3, 2, 1, 0 } ; | |||||
static const int segmentDigits [] = | |||||
{ | |||||
// a b c d e f g Segments | |||||
// 6 5 4 3 2 1 0, // wiringPi pin No. | |||||
1, 1, 1, 1, 1, 1, 0, // 0 | |||||
0, 1, 1, 0, 0, 0, 0, // 1 | |||||
1, 1, 0, 1, 1, 0, 1, // 2 | |||||
1, 1, 1, 1, 0, 0, 1, // 3 | |||||
0, 1, 1, 0, 0, 1, 1, // 4 | |||||
1, 0, 1, 1, 0, 1, 1, // 5 | |||||
1, 0, 1, 1, 1, 1, 1, // 6 | |||||
1, 1, 1, 0, 0, 0, 0, // 7 | |||||
1, 1, 1, 1, 1, 1, 1, // 8 | |||||
1, 1, 1, 1, 0, 1, 1, // 9 | |||||
1, 1, 1, 0, 1, 1, 1, // A | |||||
0, 0, 1, 1, 1, 1, 1, // b | |||||
1, 0, 0, 1, 1, 1, 0, // C | |||||
0, 1, 1, 1, 1, 0, 1, // d | |||||
1, 0, 0, 1, 1, 1, 1, // E | |||||
1, 0, 0, 0, 1, 1, 1, // F | |||||
0, 0, 0, 0, 0, 0, 0, // blank | |||||
} ; | |||||
// display: | |||||
// A global variable which is written to by the main program and | |||||
// read from by the thread that updates the display. Only the first | |||||
// 6 characters are used. | |||||
char display [8] ; | |||||
/* | |||||
* displayDigits: | |||||
* This is our thread that's run concurrently with the main program. | |||||
* Essentially sit in a loop, parsing and displaying the data held in | |||||
* the "display" global. | |||||
********************************************************************************* | |||||
*/ | |||||
PI_THREAD (displayDigits) | |||||
{ | |||||
int digit, segment ; | |||||
int index, d, segVal ; | |||||
piHiPri (50) ; | |||||
for (;;) | |||||
{ | |||||
for (digit = 0 ; digit < 6 ; ++digit) | |||||
{ | |||||
for (segment = 0 ; segment < 7 ; ++segment) | |||||
{ | |||||
d = toupper (display [digit]) ; | |||||
/**/ if ((d >= '0') && (d <= '9')) // Digit | |||||
index = d - '0' ; | |||||
else if ((d >= 'A') && (d <= 'F')) // Hex | |||||
index = d - 'A' + 10 ; | |||||
else | |||||
index = 16 ; // Blank | |||||
segVal = segmentDigits [index * 7 + segment] ; | |||||
digitalWrite (segments [segment], segVal) ; | |||||
} | |||||
digitalWrite (digits [digit], 1) ; | |||||
delay (2) ; | |||||
digitalWrite (digits [digit], 0) ; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* setup: | |||||
* Initialise the hardware and start the thread | |||||
********************************************************************************* | |||||
*/ | |||||
void setup (void) | |||||
{ | |||||
int i, c ; | |||||
wiringPiSetup () ; | |||||
// 7 segments | |||||
for (i = 0 ; i < 7 ; ++i) | |||||
{ digitalWrite (segments [i], 0) ; pinMode (segments [i], OUTPUT) ; } | |||||
// 6 digits | |||||
for (i = 0 ; i < 6 ; ++i) | |||||
{ digitalWrite (digits [i], 0) ; pinMode (digits [i], OUTPUT) ; } | |||||
strcpy (display, " ") ; | |||||
piThreadCreate (displayDigits) ; | |||||
delay (10) ; // Just to make sure it's started | |||||
// Quick countdown LED test sort of thing | |||||
c = 999999 ; | |||||
for (i = 0 ; i < 10 ; ++i) | |||||
{ | |||||
sprintf (display, "%06d", c) ; | |||||
delay (400) ; | |||||
c -= 111111 ; | |||||
} | |||||
strcpy (display, " ") ; | |||||
delay (400) ; | |||||
#ifdef PHOTO_HACK | |||||
sprintf (display, "%s", "123456") ; | |||||
for (;;) | |||||
delay (1000) ; | |||||
#endif | |||||
} | |||||
/* | |||||
* teenager: | |||||
* No explanation needed. (Nor one given!) | |||||
********************************************************************************* | |||||
*/ | |||||
void teenager (void) | |||||
{ | |||||
char *message = " feedbeef babe cafe b00b " ; | |||||
int i ; | |||||
for (i = 0 ; i < strlen (message) - 4 ; ++i) | |||||
{ | |||||
strncpy (display, &message [i], 6) ; | |||||
delay (200) ; | |||||
} | |||||
delay (1000) ; | |||||
for (i = 0 ; i < 3 ; ++i) | |||||
{ | |||||
strcpy (display, " ") ; | |||||
delay (150) ; | |||||
strcpy (display, " b00b ") ; | |||||
delay (250) ; | |||||
} | |||||
delay (1000) ; | |||||
strcpy (display, " ") ; | |||||
delay (1000) ; | |||||
} | |||||
/* | |||||
********************************************************************************* | |||||
* main: | |||||
* Let the fun begin | |||||
********************************************************************************* | |||||
*/ | |||||
int main (void) | |||||
{ | |||||
struct tm *t ; | |||||
time_t tim ; | |||||
setup () ; | |||||
teenager () ; | |||||
tim = time (NULL) ; | |||||
for (;;) | |||||
{ | |||||
while (time (NULL) == tim) | |||||
delay (5) ; | |||||
tim = time (NULL) ; | |||||
t = localtime (&tim) ; | |||||
sprintf (display, "%02d%02d%02d", t->tm_hour, t->tm_min, t->tm_sec) ; | |||||
delay (500) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,74 @@ | |||||
# | |||||
# Makefile: | |||||
# Gertboard - Examples using wiringPi | |||||
# | |||||
# Copyright (c) 2013 Gordon Henderson | |||||
################################################################################# | |||||
#DEBUG = -g -O0 | |||||
DEBUG = -O3 | |||||
CC = gcc | |||||
INCLUDE = -I/usr/local/include | |||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||||
LDFLAGS = -L/usr/local/lib | |||||
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm | |||||
# Should not alter anything below this line | |||||
############################################################################### | |||||
SRC = gertboard.c \ | |||||
buttons.c 7segments.c \ | |||||
voltmeter.c temperature.c vumeter.c \ | |||||
record.c | |||||
OBJ = $(SRC:.c=.o) | |||||
BINS = $(SRC:.c=) | |||||
all: $(BINS) | |||||
gertboard: gertboard.o | |||||
@echo [link] | |||||
@$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) | |||||
buttons: buttons.o | |||||
@echo [link] | |||||
@$(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) | |||||
7segments: 7segments.o | |||||
@echo [link] | |||||
@$(CC) -o $@ 7segments.o $(LDFLAGS) $(LDLIBS) | |||||
voltmeter: voltmeter.o | |||||
@echo [link] | |||||
@$(CC) -o $@ voltmeter.o $(LDFLAGS) $(LDLIBS) | |||||
temperature: temperature.o | |||||
@echo [link] | |||||
@$(CC) -o $@ temperature.o $(LDFLAGS) $(LDLIBS) | |||||
vumeter: vumeter.o | |||||
@echo [link] | |||||
@$(CC) -o $@ vumeter.o $(LDFLAGS) $(LDLIBS) | |||||
record: record.o | |||||
@echo [link] | |||||
@$(CC) -o $@ record.o $(LDFLAGS) $(LDLIBS) | |||||
.c.o: | |||||
@echo [CC] $< | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | |||||
clean: | |||||
@echo [Clean] | |||||
@rm -f $(OBJ) *~ core tags $(BINS) | |||||
tags: $(SRC) | |||||
@echo [ctags] | |||||
@ctags $(SRC) | |||||
depend: | |||||
makedepend -Y $(SRC) | |||||
# DO NOT DELETE |
@@ -0,0 +1,83 @@ | |||||
/* | |||||
* buttons.c: | |||||
* Read the Gertboard buttons. Each one will act as an on/off | |||||
* tiggle switch for 3 different LEDs | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <wiringPi.h> | |||||
// Array to keep track of our LEDs | |||||
int leds [] = { 0, 0, 0 } ; | |||||
// scanButton: | |||||
// See if a button is pushed, if so, then flip that LED and | |||||
// wait for the button to be let-go | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (button) == HIGH) // Low is pushed | |||||
return ; | |||||
leds [button] ^= 1 ; // Invert state | |||||
digitalWrite (4 + button, leds [button]) ; | |||||
while (digitalRead (button) == LOW) // Wait for release | |||||
delay (10) ; | |||||
} | |||||
int main (void) | |||||
{ | |||||
int i ; | |||||
printf ("Raspberry Pi Gertboard Button Test\n") ; | |||||
wiringPiSetup () ; | |||||
// Setup the outputs: | |||||
// Pins 3, 4, 5, 6 and 7 output: | |||||
// We're not using 3 or 4, but make sure they're off anyway | |||||
// (Using same hardware config as blink12.c) | |||||
for (i = 3 ; i < 8 ; ++i) | |||||
{ | |||||
pinMode (i, OUTPUT) ; | |||||
digitalWrite (i, 0) ; | |||||
} | |||||
// Setup the inputs | |||||
for (i = 0 ; i < 3 ; ++i) | |||||
{ | |||||
pinMode (i, INPUT) ; | |||||
pullUpDnControl (i, PUD_UP) ; | |||||
leds [i] = 0 ; | |||||
} | |||||
for (;;) | |||||
{ | |||||
for (i = 0 ; i < 3 ; ++i) | |||||
scanButton (i) ; | |||||
delay (1) ; | |||||
} | |||||
} |
@@ -6,8 +6,8 @@ | |||||
* D/A port 0 jumpered to A/D port 0. | * D/A port 0 jumpered to A/D port 0. | ||||
* | * | ||||
* We output a sine wave on D/A port 0 and sample A/D port 0. We then | * We output a sine wave on D/A port 0 and sample A/D port 0. We then | ||||
* copy this value to D/A port 1 and use a 'scope on both D/A ports | |||||
* to check all's well. | |||||
* plot the input value on the terminal as a sort of vertical scrolling | |||||
* oscilloscipe. | |||||
* | * | ||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | ||||
*********************************************************************** | *********************************************************************** | ||||
@@ -30,11 +30,13 @@ | |||||
*/ | */ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdint.h> | |||||
#include <sys/ioctl.h> | |||||
#include <stdlib.h> | |||||
#include <math.h> | #include <math.h> | ||||
#define B_SIZE 200 | |||||
#undef DO_TIMING | |||||
// Gertboard D to A is an 8-bit unit. | |||||
#define B_SIZE 256 | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
#include <gertboard.h> | #include <gertboard.h> | ||||
@@ -42,23 +44,28 @@ | |||||
int main (void) | int main (void) | ||||
{ | { | ||||
double angle ; | double angle ; | ||||
int i ; | |||||
uint32_t x1 ; | |||||
int i, inputValue ; | |||||
int buffer [B_SIZE] ; | int buffer [B_SIZE] ; | ||||
int cols ; | |||||
struct winsize w ; | |||||
#ifdef DO_TIMING | |||||
unsigned int now, then ; | |||||
#endif | |||||
printf ("Raspberry Pi Gertboard SPI test program\n") ; | printf ("Raspberry Pi Gertboard SPI test program\n") ; | ||||
printf ("=======================================\n") ; | |||||
ioctl (fileno (stdin), TIOCGWINSZ, &w); | |||||
cols = w.ws_col - 2 ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
if (wiringPiSetupSys () < 0) | |||||
return -1 ; | |||||
// Initialise the Gertboard analog hardware at pin 100 | |||||
if (gertboardSPISetup () < 0) | |||||
return 1 ; | |||||
gertboardAnalogSetup (100) ; | |||||
// Generate a Sine Wave | |||||
// Generate a Sine Wave and store in our buffer | |||||
for (i = 0 ; i < B_SIZE ; ++i) | for (i = 0 ; i < B_SIZE ; ++i) | ||||
{ | { | ||||
@@ -66,28 +73,23 @@ int main (void) | |||||
buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ; | buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ; | ||||
} | } | ||||
// Loop, output the sine wave on analog out port 0, read it into A-D port 0 | |||||
// and display it on the screen | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
#ifdef DO_TIMING | |||||
then = millis () ; | |||||
#endif | |||||
for (i = 0 ; i < B_SIZE ; ++i) | for (i = 0 ; i < B_SIZE ; ++i) | ||||
{ | { | ||||
gertboardAnalogWrite (0, buffer [i]) ; | |||||
analogWrite (100, buffer [i]) ; | |||||
#ifndef DO_TIMING | |||||
x1 = gertboardAnalogRead (0) ; | |||||
gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A | |||||
#endif | |||||
} | |||||
inputValue = analogRead (100) ; | |||||
#ifdef DO_TIMING | |||||
now = millis () ; | |||||
printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ; | |||||
printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ; | |||||
#endif | |||||
// We don't need to wory about the scale or sign - the analog hardware is | |||||
// a 10-bit value, so 0-1023. Just scale this to our terminal | |||||
printf ("%*s\n", (inputValue * cols) / 1023, "*") ; | |||||
delay (2) ; | |||||
} | |||||
} | } | ||||
return 0 ; | return 0 ; |
@@ -0,0 +1,60 @@ | |||||
/* | |||||
* record.c: | |||||
* Record some audio via the Gertboard | |||||
* | |||||
* Copyright (c) 2013 Gordon Henderson | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <sys/time.h> | |||||
#include <wiringPi.h> | |||||
#include <gertboard.h> | |||||
#define B_SIZE 40000 | |||||
int main () | |||||
{ | |||||
int i ; | |||||
struct timeval tStart, tEnd, tTaken ; | |||||
unsigned char buffer [B_SIZE] ; | |||||
printf ("\n") ; | |||||
printf ("Gertboard demo: Recorder\n") ; | |||||
printf ("========================\n") ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
// Initialise the Gertboard analog hardware at pin 100 | |||||
gertboardAnalogSetup (100) ; | |||||
gettimeofday (&tStart, NULL) ; | |||||
for (i = 0 ; i < B_SIZE ; ++i) | |||||
buffer [i] = analogRead (100) >> 2 ; | |||||
gettimeofday (&tEnd, NULL) ; | |||||
timersub (&tEnd, &tStart, &tTaken) ; | |||||
printf ("Time taken for %d reads: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ; | |||||
gettimeofday (&tStart, NULL) ; | |||||
for (i = 0 ; i < B_SIZE ; ++i) | |||||
analogWrite (100, buffer [i]) ; | |||||
gettimeofday (&tEnd, NULL) ; | |||||
timersub (&tEnd, &tStart, &tTaken) ; | |||||
printf ("Time taken for %d writes: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ; | |||||
return 0 ; | |||||
} | |||||
@@ -0,0 +1,78 @@ | |||||
/* | |||||
* temperature.c: | |||||
* Demonstrate use of the Gertboard A to D converter to make | |||||
* a simple thermometer using the LM35. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <wiringPi.h> | |||||
#include <gertboard.h> | |||||
int main () | |||||
{ | |||||
int x1, x2 ; | |||||
double v1, v2 ; | |||||
printf ("\n") ; | |||||
printf ("Gertboard demo: Simple Thermemeter\n") ; | |||||
printf ("==================================\n") ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
// Initialise the Gertboard analog hardware at pin 100 | |||||
gertboardAnalogSetup (100) ; | |||||
printf ("\n") ; | |||||
printf ("| Channel 0 | Channel 1 | Temperature 1 | Temperature 2 |\n") ; | |||||
for (;;) | |||||
{ | |||||
// Read the 2 channels: | |||||
x1 = analogRead (100) ; | |||||
x2 = analogRead (101) ; | |||||
// Convert to a voltage: | |||||
v1 = (double)x1 / 1023.0 * 3.3 ; | |||||
v2 = (double)x2 / 1023.0 * 3.3 ; | |||||
printf ("| %6.3f | %6.3f |", v1, v2) ; | |||||
// Print Temperature of both channels by converting the LM35 reading | |||||
// to a temperature. Fortunately these are easy: 0.01 volts per C. | |||||
printf (" %4.1f | %4.1f |\r", v1 * 100.0, v2 * 100.0) ; | |||||
fflush (stdout) ; | |||||
} | |||||
return 0 ; | |||||
} | |||||
@@ -0,0 +1,73 @@ | |||||
/* | |||||
* voltmeter.c: | |||||
* Demonstrate use of the Gertboard A to D converter to make | |||||
* a simple voltmeter. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <wiringPi.h> | |||||
#include <gertboard.h> | |||||
int main () | |||||
{ | |||||
int x1, x2 ; | |||||
double v1, v2 ; | |||||
printf ("\n") ; | |||||
printf ("Gertboard demo: Simple Voltmeters\n") ; | |||||
printf ("=================================\n") ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
// Initialise the Gertboard analog hardware at pin 100 | |||||
gertboardAnalogSetup (100) ; | |||||
printf ("\n") ; | |||||
printf ("| Channel 0 | Channel 1 |\n") ; | |||||
for (;;) | |||||
{ | |||||
// Read the 2 channels: | |||||
x1 = analogRead (100) ; | |||||
x2 = analogRead (101) ; | |||||
// Convert to a voltage: | |||||
v1 = (double)x1 / 1023.0 * 3.3 ; | |||||
v2 = (double)x2 / 1023.0 * 3.3 ; | |||||
printf ("| %6.3f | %6.3f |\r", v1, v2) ; | |||||
fflush (stdout) ; | |||||
} | |||||
return 0 ; | |||||
} | |||||
@@ -0,0 +1,152 @@ | |||||
/* | |||||
* vumeter.c: | |||||
* Simple VU meter | |||||
* | |||||
* Heres the theory: | |||||
* We will sample at 4000 samples/sec and put the data into a | |||||
* low-pass filter with a depth of 1000 samples. This will give | |||||
* us 1/4 a second of lag on the signal, but I think it might | |||||
* produce a more pleasing output. | |||||
* | |||||
* The input of the microphone should be at mid-pont with no | |||||
* sound input, but we might have to sample that too, to get | |||||
* our reference zero... | |||||
* | |||||
* Copyright (c) 2013 Gordon Henderson | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <sys/time.h> | |||||
#include <wiringPi.h> | |||||
#include <gertboard.h> | |||||
#ifndef TRUE | |||||
#define TRUE (1==1) | |||||
#define FALSE (!TRUE) | |||||
#endif | |||||
#define B_SIZE 1000 | |||||
#define S_SIZE 128 | |||||
static int buffer [B_SIZE] ; | |||||
static int bPtr = 0 ; | |||||
/* | |||||
* ledPercent: | |||||
* Output the given value as a percentage on the LEDs | |||||
********************************************************************************* | |||||
*/ | |||||
static void ledPercent (int percent) | |||||
{ | |||||
unsigned int output = 0 ; | |||||
if (percent > 11) output |= 0x01 ; | |||||
if (percent > 22) output |= 0x02 ; | |||||
if (percent > 33) output |= 0x04 ; | |||||
if (percent > 44) output |= 0x08 ; | |||||
if (percent > 55) output |= 0x10 ; | |||||
if (percent > 66) output |= 0x20 ; | |||||
if (percent > 77) output |= 0x40 ; | |||||
if (percent > 88) output |= 0x80 ; | |||||
digitalWriteByte (output) ; | |||||
} | |||||
static unsigned int tPeriod, tNextSampleTime ; | |||||
/* | |||||
* sample: | |||||
* Get a sample from the Gertboard. If not enough time has elapsed | |||||
* since the last sample, then wait... | |||||
********************************************************************************* | |||||
*/ | |||||
static void sample (void) | |||||
{ | |||||
unsigned int tFuture ; | |||||
// Calculate the future sample time | |||||
tFuture = tPeriod + tNextSampleTime ; | |||||
// Wait until the next sample time | |||||
while (micros () < tNextSampleTime) | |||||
; | |||||
buffer [bPtr] = gertboardAnalogRead (0) ; | |||||
tNextSampleTime = tFuture ; | |||||
} | |||||
int main () | |||||
{ | |||||
int quietLevel, min, max ; | |||||
int i, sum ; | |||||
unsigned int tStart, tEnd ; | |||||
printf ("\n") ; | |||||
printf ("Gertboard demo: VU Meter\n") ; | |||||
printf ("========================\n") ; | |||||
wiringPiSetup () ; | |||||
gertboardSPISetup () ; | |||||
ledPercent (0) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
pinMode (i, OUTPUT) ; | |||||
for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) | |||||
buffer [bPtr] = 99 ; | |||||
tPeriod = 1000000 / 1000 ; | |||||
printf ("Shhhh.... ") ; fflush (stdout) ; | |||||
delay (1000) ; | |||||
printf ("Sampling quiet... ") ; fflush (stdout) ; | |||||
tStart = micros () ; | |||||
tNextSampleTime = micros () ; | |||||
for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) | |||||
sample () ; | |||||
tEnd = micros () ; | |||||
quietLevel = 0 ; | |||||
max = 0 ; | |||||
min = 1024 ; | |||||
for (i = 0 ; i < B_SIZE ; ++i) | |||||
{ | |||||
quietLevel += buffer [i] ; | |||||
if (buffer [i] > max) max = buffer [i] ; | |||||
if (buffer [i] < min) min = buffer [i] ; | |||||
} | |||||
quietLevel /= B_SIZE ; | |||||
printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ; | |||||
printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ; | |||||
for (bPtr = 0 ;;) | |||||
{ | |||||
sample () ; | |||||
sum = 0 ; | |||||
for (i = 0 ; i < S_SIZE ; ++i) | |||||
sum += buffer [i] ; | |||||
sum /= S_SIZE ; | |||||
sum = abs (quietLevel - sum) ; | |||||
sum = (sum * 1000) / quietLevel ; | |||||
ledPercent (sum) ; | |||||
if (++bPtr > S_SIZE) | |||||
bPtr = 0 ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -30,15 +30,19 @@ INCLUDE = -I/usr/local/include | |||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | ||||
LDFLAGS = -L/usr/local/lib | LDFLAGS = -L/usr/local/lib | ||||
LDLIBS = -lwiringPi -lpthread -lm | |||||
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm | |||||
# Should not alter anything below this line | # Should not alter anything below this line | ||||
############################################################################### | ############################################################################### | ||||
SRC = blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c \ | |||||
piface.c gertboard.c nes.c \ | |||||
pwm.c tone.c servo.c \ | |||||
delayTest.c serialRead.c serialTest.c okLed.c | |||||
SRC = blink.c blink8.c blink12.c \ | |||||
pwm.c \ | |||||
speed.c wfi.c isr.c isr-osc.c \ | |||||
lcd.c clock.c \ | |||||
nes.c \ | |||||
softPwm.c softTone.c \ | |||||
delayTest.c serialRead.c serialTest.c okLed.c ds1302.c \ | |||||
rht03.c | |||||
OBJ = $(SRC:.c=.o) | OBJ = $(SRC:.c=.o) | ||||
@@ -55,13 +59,13 @@ blink: blink.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) | ||||
test1: test1.o | |||||
blink8: blink8.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) | |||||
test2: test2.o | |||||
@$(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS) | |||||
blink12: blink12.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS) | |||||
@$(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS) | |||||
speed: speed.o | speed: speed.o | ||||
@echo [link] | @echo [link] | ||||
@@ -71,6 +75,10 @@ lcd: lcd.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) | ||||
clock: clock.o | |||||
@echo [link] | |||||
@$(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS) | |||||
wfi: wfi.o | wfi: wfi.o | ||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) | ||||
@@ -83,22 +91,26 @@ isr-osc: isr-osc.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) | ||||
piface: piface.o | |||||
@echo [link] | |||||
@$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) | |||||
gertboard: gertboard.o | |||||
@echo [link] | |||||
@$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) | |||||
nes: nes.o | nes: nes.o | ||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) | ||||
rht03: rht03.o | |||||
@echo [link] | |||||
@$(CC) -o $@ rht03.o $(LDFLAGS) $(LDLIBS) | |||||
pwm: pwm.o | pwm: pwm.o | ||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) | ||||
softPwm: softPwm.o | |||||
@echo [link] | |||||
@$(CC) -o $@ softPwm.o $(LDFLAGS) $(LDLIBS) | |||||
softTone: softTone.o | |||||
@echo [link] | |||||
@$(CC) -o $@ softTone.o $(LDFLAGS) $(LDLIBS) | |||||
delayTest: delayTest.o | delayTest: delayTest.o | ||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) | ||||
@@ -119,9 +131,9 @@ tone: tone.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) | @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) | ||||
servo: servo.o | |||||
ds1302: ds1302.o | |||||
@echo [link] | @echo [link] | ||||
@$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS) | |||||
@$(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS) | |||||
.c.o: | .c.o: | ||||
@@ -129,7 +141,8 @@ servo: servo.o | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | @$(CC) -c $(CFLAGS) $< -o $@ | ||||
clean: | clean: | ||||
rm -f $(OBJ) *~ core tags $(BINS) | |||||
@echo "[Clean]" | |||||
@rm -f $(OBJ) *~ core tags $(BINS) | |||||
tags: $(SRC) | tags: $(SRC) | ||||
@echo [ctags] | @echo [ctags] | ||||
@@ -0,0 +1,85 @@ | |||||
# | |||||
# Makefile: | |||||
# wiringPi - Wiring Compatable library for the Raspberry Pi | |||||
# https://projects.drogon.net/wiring-pi | |||||
# | |||||
# Copyright (c) 2012 Gordon Henderson | |||||
################################################################################# | |||||
# This file is part of wiringPi: | |||||
# Wiring Compatable library for the Raspberry Pi | |||||
# | |||||
# 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/>. | |||||
################################################################################# | |||||
#DEBUG = -g -O0 | |||||
DEBUG = -O3 | |||||
CC = gcc | |||||
INCLUDE = -I/usr/local/include | |||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||||
LDFLAGS = -L/usr/local/lib | |||||
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm | |||||
# Should not alter anything below this line | |||||
############################################################################### | |||||
SRC = blink.c buttons.c reaction.c ladder.c metro.c motor.c | |||||
OBJ = $(SRC:.c=.o) | |||||
BINS = $(SRC:.c=) | |||||
all: $(BINS) | |||||
blink: blink.o | |||||
@echo [link] | |||||
@$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) | |||||
buttons: buttons.o | |||||
@echo [link] | |||||
@$(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) | |||||
reaction: reaction.o | |||||
@echo [link] | |||||
@$(CC) -o $@ reaction.o $(LDFLAGS) $(LDLIBS) | |||||
ladder: ladder.o | |||||
@echo [link] | |||||
@$(CC) -o $@ ladder.o $(LDFLAGS) $(LDLIBS) | |||||
metro: metro.o | |||||
@echo [link] | |||||
@$(CC) -o $@ metro.o $(LDFLAGS) $(LDLIBS) | |||||
motor: motor.o | |||||
@echo [link] | |||||
@$(CC) -o $@ motor.o $(LDFLAGS) $(LDLIBS) | |||||
.c.o: | |||||
@echo [CC] $< | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | |||||
clean: | |||||
@echo "[Clean]" | |||||
@rm -f $(OBJ) *~ core tags $(BINS) | |||||
tags: $(SRC) | |||||
@echo [ctags] | |||||
@ctags $(SRC) | |||||
depend: | |||||
makedepend -Y $(SRC) | |||||
# DO NOT DELETE |
@@ -0,0 +1,59 @@ | |||||
/* | |||||
* blink.c: | |||||
* Simple "blink" test for the PiFace interface board. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
// Use 200 as the pin-base for the PiFace board, and pick a pin | |||||
// for the LED that's not connected to a relay | |||||
#define PIFACE 200 | |||||
#define LED (PIFACE+2) | |||||
int main (int argc, char *argv []) | |||||
{ | |||||
printf ("Raspberry Pi PiFace Blink\n") ; | |||||
printf ("=========================\n") ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
// Setup the PiFace board | |||||
piFaceSetup (PIFACE) ; | |||||
for (;;) | |||||
{ | |||||
digitalWrite (LED, HIGH) ; // On | |||||
delay (500) ; // mS | |||||
digitalWrite (LED, LOW) ; // Off | |||||
delay (500) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,103 @@ | |||||
/* | |||||
* buttons.c: | |||||
* Simple test for the PiFace interface board. | |||||
* | |||||
* Read the buttons and output the same to the LEDs | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
int outputs [4] = { 0,0,0,0 } ; | |||||
// Use 200 as the pin-base for the PiFace board | |||||
#define PIFACE_BASE 200 | |||||
/* | |||||
* scanButton: | |||||
* Read the guiven button - if it's pressed, then flip the state | |||||
* of the correspoinding output pin | |||||
********************************************************************************* | |||||
*/ | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (PIFACE_BASE + button) == LOW) | |||||
{ | |||||
outputs [button] ^= 1 ; | |||||
digitalWrite (PIFACE_BASE + button, outputs [button]) ; | |||||
printf ("Button %d pushed - output now: %s\n", | |||||
button, (outputs [button] == 0) ? "Off" : "On") ; | |||||
} | |||||
while (digitalRead (PIFACE_BASE + button) == LOW) | |||||
delay (1) ; | |||||
} | |||||
/* | |||||
* start here | |||||
********************************************************************************* | |||||
*/ | |||||
int main (void) | |||||
{ | |||||
int pin, button ; | |||||
printf ("Raspberry Pi wiringPi + PiFace test program\n") ; | |||||
printf ("===========================================\n") ; | |||||
printf ("\n") ; | |||||
printf ( | |||||
"This program reads the buttons and uses them to toggle the first 4\n" | |||||
"outputs. Push a button once to turn an output on, and push it again to\n" | |||||
"turn it off again.\n\n") ; | |||||
// Always initialise wiringPi. Use wiringPiSys() if you don't need | |||||
// (or want) to run as root | |||||
wiringPiSetupSys () ; | |||||
piFaceSetup (PIFACE_BASE) ; | |||||
// Enable internal pull-ups & start with all off | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
{ | |||||
pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ; | |||||
digitalWrite (PIFACE_BASE + pin, 0) ; | |||||
} | |||||
// Loop, scanning the buttons | |||||
for (;;) | |||||
{ | |||||
for (button = 0 ; button < 4 ; ++button) | |||||
scanButton (button) ; | |||||
delay (5) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,337 @@ | |||||
/* | |||||
* ladder.c: | |||||
* | |||||
* Gordon Henderson, June 2012 | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
#undef DEBUG | |||||
#define NUM_LEDS 8 | |||||
// Map the LEDs to the hardware pins | |||||
// using PiFace pin numbers here | |||||
#define PIFACE 200 | |||||
const int ledMap [NUM_LEDS] = | |||||
{ | |||||
// 0, 1, 2, 3, 4, 5, 6, 7, 8 | |||||
200, 201, 202, 203, 204, 205, 206, 207 | |||||
} ; | |||||
// Some constants for our circuit simulation | |||||
const double vBatt = 9.0 ; // Volts (ie. a PP3) | |||||
const double capacitor = 0.001 ; // 1000uF | |||||
const double rCharge = 2200.0 ; // ohms | |||||
const double rDischarge = 68000.0 ; // ohms | |||||
const double timeInc = 0.01 ; // Seconds | |||||
double vCharge, vCap, vCapLast ; | |||||
/* | |||||
* setup: | |||||
* Program the GPIO correctly and initialise the lamps | |||||
*********************************************************************** | |||||
*/ | |||||
void setup (void) | |||||
{ | |||||
int i ; | |||||
wiringPiSetupSys () ; | |||||
if (piFaceSetup (200) == -1) | |||||
exit (1) ; | |||||
// Enable internal pull-ups | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
pullUpDnControl (PIFACE + i, PUD_UP) ; | |||||
// Calculate the actual charging voltage - standard calculation of | |||||
// vCharge = r2 / (r1 + r2) * vBatt | |||||
// | |||||
// | |||||
// -----+--- vBatt | |||||
// | | |||||
// R1 | |||||
// | | |||||
// +---+---- vCharge | |||||
// | | | |||||
// R2 C | |||||
// | | | |||||
// -----+---+----- | |||||
vCharge = rDischarge / (rCharge + rDischarge) * vBatt ; | |||||
// Start with no charge | |||||
vCap = vCapLast = 0.0 ; | |||||
} | |||||
/* | |||||
* introLeds | |||||
* Put a little pattern on the LEDs to start with | |||||
********************************************************************************* | |||||
*/ | |||||
void introLeds (void) | |||||
{ | |||||
int i, j ; | |||||
printf ("Pi Ladder\n") ; | |||||
printf ("=========\n\n") ; | |||||
printf (" vBatt: %6.2f volts\n", vBatt) ; | |||||
printf (" rCharge: %6.0f ohms\n", rCharge) ; | |||||
printf (" rDischarge: %6.0f ohms\n", rDischarge) ; | |||||
printf (" vCharge: %6.2f volts\n", vCharge) ; | |||||
printf (" capacitor: %6.0f uF\n", capacitor * 1000.0) ; | |||||
// Flash 3 times: | |||||
for (j = 0 ; j < 3 ; ++j) | |||||
{ | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 1) ; | |||||
delay (500) ; | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 0) ; | |||||
delay (100) ; | |||||
} | |||||
// All On | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 1) ; | |||||
delay (500) ; | |||||
// Countdown... | |||||
for (i = NUM_LEDS - 1 ; i >= 0 ; --i) | |||||
{ | |||||
digitalWrite (ledMap [i], 0) ; | |||||
delay (100) ; | |||||
} | |||||
delay (500) ; | |||||
} | |||||
/* | |||||
* winningLeds | |||||
* Put a little pattern on the LEDs to start with | |||||
********************************************************************************* | |||||
*/ | |||||
void winningLeds (void) | |||||
{ | |||||
int i, j ; | |||||
// Flash 3 times: | |||||
for (j = 0 ; j < 3 ; ++j) | |||||
{ | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 1) ; | |||||
delay (500) ; | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 0) ; | |||||
delay (100) ; | |||||
} | |||||
// All On | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 1) ; | |||||
delay (500) ; | |||||
// Countup... | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
{ | |||||
digitalWrite (ledMap [i], 0) ; | |||||
delay (100) ; | |||||
} | |||||
delay (500) ; | |||||
} | |||||
/* | |||||
* chargeCapacitor: dischargeCapacitor: | |||||
* Add or remove charge to the capacitor. | |||||
* Standard capacitor formulae. | |||||
********************************************************************************* | |||||
*/ | |||||
void chargeCapacitor (void) | |||||
{ | |||||
vCap = (vCapLast - vCharge) * | |||||
exp (- timeInc / (rCharge * capacitor)) + vCharge ; | |||||
#ifdef DEBUG | |||||
printf ("+vCap: %7.4f\n", vCap) ; | |||||
#endif | |||||
vCapLast = vCap ; | |||||
} | |||||
void dischargeCapacitor (void) | |||||
{ | |||||
vCap = vCapLast * | |||||
exp (- timeInc / (rDischarge * capacitor)) ; | |||||
#ifdef DEBUG | |||||
printf ("-vCap: %7.4f\n", vCap) ; | |||||
#endif | |||||
vCapLast = vCap ; | |||||
} | |||||
/* | |||||
* ledBargraph: | |||||
* Output the supplied number as a bargraph on the LEDs | |||||
********************************************************************************* | |||||
*/ | |||||
void ledBargraph (double value, int topLedOn) | |||||
{ | |||||
int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ; | |||||
int i ; | |||||
if (topLed > NUM_LEDS) | |||||
topLed = NUM_LEDS ; | |||||
if (!topLedOn) | |||||
--topLed ; | |||||
for (i = 0 ; i < topLed ; ++i) | |||||
digitalWrite (ledMap [i], 1) ; | |||||
for (i = topLed ; i < NUM_LEDS ; ++i) | |||||
digitalWrite (ledMap [i], 0) ; | |||||
} | |||||
/* | |||||
* ledOnAction: | |||||
* Make sure the leading LED is on and check the button | |||||
********************************************************************************* | |||||
*/ | |||||
void ledOnAction (void) | |||||
{ | |||||
if (digitalRead (PIFACE) == LOW) | |||||
{ | |||||
chargeCapacitor () ; | |||||
ledBargraph (vCap, TRUE) ; | |||||
} | |||||
} | |||||
/* | |||||
* ledOffAction: | |||||
* Make sure the leading LED is off and check the button | |||||
********************************************************************************* | |||||
*/ | |||||
void ledOffAction (void) | |||||
{ | |||||
dischargeCapacitor () ; | |||||
// Are we still pushing the button? | |||||
if (digitalRead (PIFACE) == LOW) | |||||
{ | |||||
vCap = vCapLast = 0.0 ; | |||||
ledBargraph (vCap, FALSE) ; | |||||
// Wait until we release the button | |||||
while (digitalRead (PIFACE) == LOW) | |||||
delay (10) ; | |||||
} | |||||
} | |||||
/* | |||||
*********************************************************************** | |||||
* The main program | |||||
*********************************************************************** | |||||
*/ | |||||
int main (void) | |||||
{ | |||||
unsigned int then, ledOnTime, ledOffTime ; | |||||
unsigned int ourDelay = (int)(1000.0 * timeInc) ; | |||||
setup () ; | |||||
introLeds () ; | |||||
// Setup the LED times - TODO reduce the ON time as the game progresses | |||||
ledOnTime = 1000 ; | |||||
ledOffTime = 1000 ; | |||||
// This is our Gate/Squarewave loop | |||||
for (;;) | |||||
{ | |||||
// LED ON: | |||||
(void)ledBargraph (vCap, TRUE) ; | |||||
then = millis () + ledOnTime ; | |||||
while (millis () < then) | |||||
{ | |||||
ledOnAction () ; | |||||
delay (ourDelay) ; | |||||
} | |||||
// Have we won yet? | |||||
// We need vCap to be in the top NUM_LEDS of the vCharge | |||||
if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge)) // Woo hoo! | |||||
{ | |||||
winningLeds () ; | |||||
while (digitalRead (PIFACE) == HIGH) | |||||
delay (10) ; | |||||
while (digitalRead (PIFACE) == LOW) | |||||
delay (10) ; | |||||
vCap = vCapLast = 0.0 ; | |||||
} | |||||
// LED OFF: | |||||
(void)ledBargraph (vCap, FALSE) ; | |||||
then = millis () + ledOffTime ; | |||||
while (millis () < then) | |||||
{ | |||||
ledOffAction () ; | |||||
delay (ourDelay) ; | |||||
} | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,111 @@ | |||||
/* | |||||
* metronome.c: | |||||
* Simple test for the PiFace interface board. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
#define PIFACE 200 | |||||
/* | |||||
* middleA: | |||||
* Play middle A (on the relays - yea!) | |||||
********************************************************************************* | |||||
*/ | |||||
static void middleA (void) | |||||
{ | |||||
unsigned int next ; | |||||
for (;;) | |||||
{ | |||||
next = micros () + 1136 ; | |||||
digitalWrite (PIFACE + 0, 0) ; | |||||
digitalWrite (PIFACE + 1, 0) ; | |||||
while (micros () < next) | |||||
delayMicroseconds (1) ; | |||||
next = micros () + 1137 ; | |||||
digitalWrite (PIFACE + 0, 1) ; | |||||
digitalWrite (PIFACE + 1, 1) ; | |||||
while (micros () < next) | |||||
delayMicroseconds (1) ; | |||||
} | |||||
} | |||||
int main (int argc, char *argv []) | |||||
{ | |||||
int bpm, msPerBeat, state = 0 ; | |||||
unsigned int end ; | |||||
printf ("Raspberry Pi PiFace Metronome\n") ; | |||||
printf ("=============================\n") ; | |||||
piHiPri (50) ; | |||||
wiringPiSetupSys () ; // Needed for timing functions | |||||
piFaceSetup (PIFACE) ; | |||||
if (argc != 2) | |||||
{ | |||||
printf ("Usage: %s <beates per minute>\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
if (strcmp (argv [1], "a") == 0) | |||||
middleA () ; | |||||
bpm = atoi (argv [1]) ; | |||||
if ((bpm < 40) || (bpm > 208)) | |||||
{ | |||||
printf ("%s range is 40 through 208 beats per minute\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
msPerBeat = 60000 / bpm ; | |||||
// Main loop: | |||||
// Put some random LED pairs up for a few seconds, then blank ... | |||||
for (;;) | |||||
{ | |||||
end = millis () + msPerBeat ; | |||||
digitalWrite (PIFACE + 0, state) ; | |||||
digitalWrite (PIFACE + 1, state) ; | |||||
while (millis () < end) | |||||
delayMicroseconds (500) ; | |||||
state ^= 1 ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,120 @@ | |||||
/* | |||||
* motor.c: | |||||
* Use the PiFace board to demonstrate an H bridge | |||||
* circuit via the 2 relays. | |||||
* Then add on an external transsitor to help with PWM. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
#include <softPwm.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
int outputs [2] = { 0,0 } ; | |||||
#define PIFACE_BASE 200 | |||||
#define PWM_OUT_PIN 204 | |||||
#define PWM_UP 202 | |||||
#define PWM_DOWN 203 | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (PIFACE_BASE + button) == LOW) | |||||
{ | |||||
outputs [button] ^= 1 ; | |||||
digitalWrite (PIFACE_BASE + button, outputs [button]) ; | |||||
printf ("Button %d pushed - output now: %s\n", | |||||
button, (outputs [button] == 0) ? "Off" : "On") ; | |||||
} | |||||
while (digitalRead (PIFACE_BASE + button) == LOW) | |||||
delay (1) ; | |||||
} | |||||
int main (void) | |||||
{ | |||||
int pin, button ; | |||||
int pwmValue = 0 ; | |||||
printf ("Raspberry Pi PiFace - Motor control\n") ; | |||||
printf ("==================================\n") ; | |||||
printf ("\n") ; | |||||
printf ( | |||||
"This program is designed to be used with a motor connected to the relays\n" | |||||
"in an H-Bridge type configuration with optional speeed control via PWM.\n" | |||||
"\n" | |||||
"Use the leftmost buttons to turn each relay on and off, and the rigthmost\n" | |||||
"buttons to increase ot decrease the PWM output on the control pin (pin\n" | |||||
"4)\n\n") ; | |||||
wiringPiSetup () ; | |||||
piFaceSetup (PIFACE_BASE) ; | |||||
softPwmCreate (PWM_OUT_PIN, 100, 100) ; | |||||
// Enable internal pull-ups & start with all off | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
{ | |||||
pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ; | |||||
digitalWrite (PIFACE_BASE + pin, 0) ; | |||||
} | |||||
for (;;) | |||||
{ | |||||
for (button = 0 ; button < 2 ; ++button) | |||||
scanButton (button) ; | |||||
if (digitalRead (PWM_UP) == LOW) | |||||
{ | |||||
pwmValue += 10 ; | |||||
if (pwmValue > 100) | |||||
pwmValue = 100 ; | |||||
softPwmWrite (PWM_OUT_PIN, pwmValue) ; | |||||
printf ("PWM -> %3d\n", pwmValue) ; | |||||
while (digitalRead (PWM_UP) == LOW) | |||||
delay (5) ; | |||||
} | |||||
if (digitalRead (PWM_DOWN) == LOW) | |||||
{ | |||||
pwmValue -= 10 ; | |||||
if (pwmValue < 0) | |||||
pwmValue = 0 ; | |||||
softPwmWrite (PWM_OUT_PIN, pwmValue) ; | |||||
printf ("PWM -> %3d\n", pwmValue) ; | |||||
while (digitalRead (PWM_DOWN) == LOW) | |||||
delay (5) ; | |||||
} | |||||
delay (5) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,194 @@ | |||||
/* | |||||
* reaction.c: | |||||
* Simple test for the PiFace interface board. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <wiringPi.h> | |||||
#include <piFace.h> | |||||
int outputs [4] = { 0,0,0,0 } ; | |||||
#define PIFACE 200 | |||||
/* | |||||
* light: | |||||
* Light up the given LED - actually lights up a pair | |||||
********************************************************************************* | |||||
*/ | |||||
void light (int led, int value) | |||||
{ | |||||
led *= 2 ; | |||||
digitalWrite (PIFACE + led + 0, value) ; | |||||
digitalWrite (PIFACE + led + 1, value) ; | |||||
} | |||||
/* | |||||
* lightAll: | |||||
* All On or Off | |||||
********************************************************************************* | |||||
*/ | |||||
void lightAll (int onoff) | |||||
{ | |||||
light (0, onoff) ; | |||||
light (1, onoff) ; | |||||
light (2, onoff) ; | |||||
light (3, onoff) ; | |||||
} | |||||
/* | |||||
* waitForNoButtons: | |||||
* Wait for all buttons to be released | |||||
********************************************************************************* | |||||
*/ | |||||
void waitForNoButtons (void) | |||||
{ | |||||
int i, button ; | |||||
for (;;) | |||||
{ | |||||
button = 0 ; | |||||
for (i = 0 ; i < 4 ; ++i) | |||||
button += digitalRead (PIFACE + i) ; | |||||
if (button == 4) | |||||
break ; | |||||
} | |||||
} | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (PIFACE + button) == LOW) | |||||
{ | |||||
outputs [button] ^= 1 ; | |||||
digitalWrite (PIFACE + button, outputs [button]) ; | |||||
} | |||||
while (digitalRead (PIFACE + button) == LOW) | |||||
delay (1) ; | |||||
} | |||||
int main (void) | |||||
{ | |||||
int i, j ; | |||||
int led, button ; | |||||
unsigned int start, stop ; | |||||
printf ("Raspberry Pi PiFace Reaction Timer\n") ; | |||||
printf ("==================================\n") ; | |||||
if (piFaceSetup (PIFACE) == -1) | |||||
exit (1) ; | |||||
// Enable internal pull-ups | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
pullUpDnControl (PIFACE + i, PUD_UP) ; | |||||
// Main game loop: | |||||
// Put some random LED pairs up for a few seconds, then blank ... | |||||
for (;;) | |||||
{ | |||||
printf ("Press any button to start ... \n") ; fflush (stdout) ; | |||||
for (;;) | |||||
{ | |||||
led = rand () % 4 ; | |||||
light (led, 1) ; | |||||
delay (10) ; | |||||
light (led, 0) ; | |||||
button = 0 ; | |||||
for (j = 0 ; j < 4 ; ++j) | |||||
button += digitalRead (PIFACE + j) ; | |||||
if (button != 4) | |||||
break ; | |||||
} | |||||
waitForNoButtons () ; | |||||
printf ("Wait for it ... ") ; fflush (stdout) ; | |||||
led = rand () % 4 ; | |||||
delay (rand () % 500 + 1000) ; | |||||
light (led, 1) ; | |||||
start = millis () ; | |||||
for (button = -1 ; button == -1 ; ) | |||||
{ | |||||
for (j = 0 ; j < 4 ; ++j) | |||||
if (digitalRead (PIFACE + j) == 0) // Pushed | |||||
{ | |||||
button = j ; | |||||
break ; | |||||
} | |||||
} | |||||
stop = millis () ; | |||||
button = 3 - button ; // Correct for the buttons/LEDs reversed | |||||
light (led, 0) ; | |||||
waitForNoButtons () ; | |||||
light (led, 1) ; | |||||
if (button == led) | |||||
{ | |||||
printf ("You got it in %3d mS\n", stop - start) ; | |||||
} | |||||
else | |||||
{ | |||||
printf ("Missed: You pushed %d - LED was %d\n", button, led) ; | |||||
for (;;) | |||||
{ | |||||
light (button, 1) ; | |||||
delay (100) ; | |||||
light (button, 0) ; | |||||
delay (100) ; | |||||
i = 0 ; | |||||
for (j = 0 ; j < 4 ; ++j) | |||||
i += digitalRead (PIFACE + j) ; | |||||
if (i != 4) | |||||
break ; | |||||
} | |||||
waitForNoButtons () ; | |||||
} | |||||
light (led, 0) ; | |||||
delay (4000) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -34,16 +34,14 @@ int main (void) | |||||
{ | { | ||||
printf ("Raspberry Pi blink\n") ; | printf ("Raspberry Pi blink\n") ; | ||||
if (wiringPiSetup () == -1) | |||||
return 1 ; | |||||
wiringPiSetup () ; | |||||
pinMode (LED, OUTPUT) ; | pinMode (LED, OUTPUT) ; | ||||
for (;;) | for (;;) | ||||
{ | { | ||||
digitalWrite (LED, 1) ; // On | |||||
digitalWrite (LED, HIGH) ; // On | |||||
delay (500) ; // mS | delay (500) ; // mS | ||||
digitalWrite (LED, 0) ; // Off | |||||
digitalWrite (LED, LOW) ; // Off | |||||
delay (500) ; | delay (500) ; | ||||
} | } | ||||
return 0 ; | return 0 ; | ||||
@@ -1,8 +1,7 @@ | |||||
/* | /* | ||||
* test1.c: | |||||
* Simple test program to test the wiringPi functions | |||||
* This is a sequencer to make a patter appear on 8 LEDs | |||||
* connected to the GPIO pins. | |||||
* blink12.c: | |||||
* Simple sequence over the first 12 GPIO pins - LEDs | |||||
* Aimed at the Gertboard, but it's fairly generic. | |||||
* | * | ||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | ||||
*********************************************************************** | *********************************************************************** | ||||
@@ -24,17 +23,13 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <wiringPi.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <wiringPi.h> | |||||
// Simple sequencer data | // Simple sequencer data | ||||
// Triplets of LED, On/Off and delay | // Triplets of LED, On/Off and delay | ||||
uint8_t data [] = | |||||
int data [] = | |||||
{ | { | ||||
0, 1, 1, | 0, 1, 1, | ||||
1, 1, 1, | 1, 1, 1, | ||||
@@ -44,15 +39,23 @@ uint8_t data [] = | |||||
3, 0, 0, 5, 1, 1, | 3, 0, 0, 5, 1, 1, | ||||
4, 0, 0, 6, 1, 1, | 4, 0, 0, 6, 1, 1, | ||||
5, 0, 0, 7, 1, 1, | 5, 0, 0, 7, 1, 1, | ||||
6, 0, 1, | |||||
7, 0, 1, | |||||
6, 0, 0, 11, 1, 1, | |||||
7, 0, 0, 10, 1, 1, | |||||
11, 0, 0, 13, 1, 1, | |||||
10, 0, 0, 12, 1, 1, | |||||
13, 0, 1, | |||||
12, 0, 1, | |||||
0, 0, 1, // Extra delay | 0, 0, 1, // Extra delay | ||||
// Back again | // Back again | ||||
7, 1, 1, | |||||
6, 1, 1, | |||||
12, 1, 1, | |||||
13, 1, 1, | |||||
12, 0, 0, 10, 1, 1, | |||||
13, 0, 0, 11, 1, 1, | |||||
10, 0, 0, 7, 1, 1, | |||||
11, 0, 0, 6, 1, 1, | |||||
7, 0, 0, 5, 1, 1, | 7, 0, 0, 5, 1, 1, | ||||
6, 0, 0, 4, 1, 1, | 6, 0, 0, 4, 1, 1, | ||||
5, 0, 0, 3, 1, 1, | 5, 0, 0, 3, 1, 1, | ||||
@@ -64,7 +67,7 @@ uint8_t data [] = | |||||
0, 0, 1, // Extra delay | 0, 0, 1, // Extra delay | ||||
9, 9, 9, // End marker | |||||
0, 9, 0, // End marker | |||||
} ; | } ; | ||||
@@ -75,16 +78,17 @@ int main (void) | |||||
int dataPtr ; | int dataPtr ; | ||||
int l, s, d ; | int l, s, d ; | ||||
printf ("Raspberry Pi wiringPi test program\n") ; | |||||
printf ("Raspberry Pi - 12-LED Sequence\n") ; | |||||
printf ("==============================\n") ; | |||||
printf ("\n") ; | |||||
printf ("Connect LEDs up to the first 8 GPIO pins, then pins 11, 10, 13, 12 in\n") ; | |||||
printf (" that order, then sit back and watch the show!\n") ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
wiringPiSetup () ; | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
for (pin = 0 ; pin < 14 ; ++pin) | |||||
pinMode (pin, OUTPUT) ; | pinMode (pin, OUTPUT) ; | ||||
pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor | |||||
dataPtr = 0 ; | dataPtr = 0 ; | ||||
for (;;) | for (;;) | ||||
@@ -93,18 +97,14 @@ int main (void) | |||||
s = data [dataPtr++] ; // State | s = data [dataPtr++] ; // State | ||||
d = data [dataPtr++] ; // Duration (10ths) | d = data [dataPtr++] ; // Duration (10ths) | ||||
if ((l + s + d) == 27) | |||||
if (s == 9) // 9 -> End Marker | |||||
{ | { | ||||
dataPtr = 0 ; | dataPtr = 0 ; | ||||
continue ; | continue ; | ||||
} | } | ||||
digitalWrite (l, s) ; | digitalWrite (l, s) ; | ||||
if (digitalRead (8) == 0) // Pressed as our switch shorts to ground | |||||
delay (d * 10) ; // Faster! | |||||
else | |||||
delay (d * 100) ; | |||||
delay (d * 100) ; | |||||
} | } | ||||
return 0 ; | return 0 ; |
@@ -1,6 +1,7 @@ | |||||
/* | /* | ||||
* test2.c: | |||||
* This tests the hardware PWM channel. | |||||
* blink8.c: | |||||
* Simple sequence over the first 8 GPIO pins - LEDs | |||||
* Aimed at the Gertboard, but it's fairly generic. | |||||
* | * | ||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | ||||
*********************************************************************** | *********************************************************************** | ||||
@@ -22,37 +23,35 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <wiringPi.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <wiringPi.h> | |||||
int main (void) | int main (void) | ||||
{ | { | ||||
int bright ; | |||||
int i, led ; | |||||
printf ("Raspberry Pi wiringPi PWM test program\n") ; | |||||
printf ("Raspberry Pi - 8-LED Sequencer\n") ; | |||||
printf ("==============================\n") ; | |||||
printf ("\n") ; | |||||
printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
wiringPiSetup () ; | |||||
pinMode (1, PWM_OUTPUT) ; | |||||
for (i = 0 ; i < 8 ; ++i) | |||||
pinMode (i, OUTPUT) ; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
for (bright = 0 ; bright < 1024 ; ++bright) | |||||
for (led = 0 ; led < 8 ; ++led) | |||||
{ | { | ||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
digitalWrite (led, 1) ; | |||||
delay (100) ; | |||||
} | } | ||||
for (bright = 1023 ; bright >= 0 ; --bright) | |||||
for (led = 0 ; led < 8 ; ++led) | |||||
{ | { | ||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
digitalWrite (led, 0) ; | |||||
delay (100) ; | |||||
} | } | ||||
} | } | ||||
return 0 ; | |||||
} | } |
@@ -0,0 +1,201 @@ | |||||
/* | |||||
* clock.c: | |||||
* Demo of the 128x64 graphics based LCD driver. | |||||
* This is designed to drive the parallel interface LCD drivers | |||||
* based on the popular 12864H controller chip. | |||||
* | |||||
* This test program assumes the following: | |||||
* (Which is currently hard-wired into the driver) | |||||
* | |||||
* GPIO 0-7 is connected to display data pins 0-7. | |||||
* GPIO 10 is CS1 | |||||
* GPIO 11 is CS2 | |||||
* GPIO 12 is STROBE | |||||
* GPIO 10 is RS | |||||
* | |||||
* 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 <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <unistd.h> | |||||
#include <string.h> | |||||
#include <errno.h> | |||||
#include <time.h> | |||||
#include <math.h> | |||||
#include <wiringPi.h> | |||||
#include <lcd128x64.h> | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
double clockRadius ; | |||||
double thickness, barLen ; | |||||
int maxX, maxY ; | |||||
double rads (double degs) | |||||
{ | |||||
return degs * M_PI / 180.0 ; | |||||
} | |||||
void drawClockHands (void) | |||||
{ | |||||
time_t t ; | |||||
struct tm *now ; | |||||
double angle, p, x0, y0, x1, y1 ; | |||||
int h24, h, m, s ; | |||||
char text [20] ; | |||||
time (&t) ; | |||||
now = localtime (&t) ; | |||||
h24 = now->tm_hour ; | |||||
m = now->tm_min ; | |||||
s = now->tm_sec ; | |||||
h = h24 ; | |||||
if (h > 12) | |||||
h -= 12 ; | |||||
// Hour hand | |||||
angle = h * 30 + m * 0.5 ; | |||||
x0 = sin (rads (angle)) * (clockRadius * 0.75) ; | |||||
y0 = cos (rads (angle)) * (clockRadius * 0.75) ; | |||||
for (p = -3.0 ; p <= 3.0 ; p += 0.2) | |||||
{ | |||||
x1 = sin (rads (angle + p)) * (clockRadius * 0.7) ; | |||||
y1 = cos (rads (angle + p)) * (clockRadius * 0.7) ; | |||||
lcd128x64line (0, 0, x1, y1, 1) ; | |||||
lcd128x64lineTo (x0, y0, 1) ; | |||||
} | |||||
// Minute hand | |||||
angle = m * 6 ; | |||||
x0 = sin (rads (angle)) * (clockRadius * 0.9) ; | |||||
y0 = cos (rads (angle)) * (clockRadius * 0.9) ; | |||||
for (p = -1.0 ; p <= 1.0 ; p += 0.2) | |||||
{ | |||||
x1 = sin (rads (angle + p)) * (clockRadius * 0.85) ; | |||||
y1 = cos (rads (angle + p)) * (clockRadius * 0.85) ; | |||||
lcd128x64line (0, 0, x1, y1, 1) ; | |||||
lcd128x64lineTo (x0, y0, 1) ; | |||||
} | |||||
// Second hand | |||||
angle = s * 6 ; | |||||
x0 = sin (rads (angle)) * (clockRadius * 0.2) ; | |||||
y0 = cos (rads (angle)) * (clockRadius * 0.2) ; | |||||
x1 = sin (rads (angle)) * (clockRadius * 0.95) ; | |||||
y1 = cos (rads (angle)) * (clockRadius * 0.95) ; | |||||
lcd128x64line (0 - x0, 0 - y0, x1, y1, 1) ; | |||||
lcd128x64circle (0, 0, clockRadius * 0.1, 0, 1) ; | |||||
lcd128x64circle (0, 0, clockRadius * 0.05, 1, 1) ; | |||||
// Text: | |||||
sprintf (text, "%02d:%02d:%02d", h24, m, s) ; | |||||
lcd128x64puts (32, 24, text, 0, 1) ; | |||||
sprintf (text, "%2d/%2d/%2d", now->tm_mday, now->tm_mon + 1, now->tm_year - 100) ; | |||||
lcd128x64puts (32, -23, text, 0, 1) ; | |||||
} | |||||
void drawClockFace (void) | |||||
{ | |||||
int m ; | |||||
double d, px1, py1, px2, py2 ; | |||||
lcd128x64clear (0) ; | |||||
lcd128x64circle (0,0, clockRadius, 1, TRUE) ; | |||||
lcd128x64circle (0,0, clockRadius - thickness, 0, TRUE) ; | |||||
// The four big indicators for 12,15,30 and 45 | |||||
lcd128x64rectangle (- 3, clockRadius - barLen, 3, clockRadius, 1, TRUE) ; // 12 | |||||
lcd128x64rectangle (clockRadius - barLen, 3, clockRadius, -3, 1, TRUE) ; // 3 | |||||
lcd128x64rectangle (- 3, -clockRadius + barLen, 3, -clockRadius, 1, TRUE) ; // 6 | |||||
lcd128x64rectangle (-clockRadius + barLen, 3, -clockRadius, -3, 1, TRUE) ; // 9 | |||||
// Smaller 5 and 1 minute ticks | |||||
for (m = 0 ; m < 60 ; ++m) | |||||
{ | |||||
px1 = sin (rads (m * 6)) * clockRadius ; | |||||
py1 = cos (rads (m * 6)) * clockRadius ; | |||||
if ((m % 5) == 0) | |||||
d = barLen ; | |||||
else | |||||
d = barLen / 2.0 ; | |||||
px2 = sin (rads (m * 6)) * (clockRadius - d) ; | |||||
py2 = cos (rads (m * 6)) * (clockRadius - d) ; | |||||
lcd128x64line (px1, py1, px2, py2, 1) ; | |||||
} | |||||
} | |||||
void setup (void) | |||||
{ | |||||
lcd128x64getScreenSize (&maxX, &maxY) ; | |||||
clockRadius = maxY / 2 - 1 ; | |||||
thickness = maxX / 48 ; | |||||
barLen = thickness * 4 ; | |||||
lcd128x64setOrigin (32, 32) ; | |||||
} | |||||
/* | |||||
*********************************************************************** | |||||
* The main program | |||||
*********************************************************************** | |||||
*/ | |||||
int main (int argc, char *argv []) | |||||
{ | |||||
time_t now ; | |||||
wiringPiSetup () ; | |||||
lcd128x64setup () ; | |||||
setup () ; | |||||
for (;;) | |||||
{ | |||||
drawClockFace () ; | |||||
drawClockHands () ; | |||||
lcd128x64update () ; | |||||
now = time (NULL) ; | |||||
while (time (NULL) == now) | |||||
delay (10) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -0,0 +1,238 @@ | |||||
/* | |||||
* ds1302.c: | |||||
* Real Time clock | |||||
* | |||||
* 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 <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <string.h> | |||||
#include <time.h> | |||||
#include <wiringPi.h> | |||||
#include <ds1302.h> | |||||
// Register defines | |||||
#define RTC_SECS 0 | |||||
#define RTC_MINS 1 | |||||
#define RTC_HOURS 2 | |||||
#define RTC_DATE 3 | |||||
#define RTC_MONTH 4 | |||||
#define RTC_DAY 5 | |||||
#define RTC_YEAR 6 | |||||
#define RTC_WP 7 | |||||
#define RTC_TC 8 | |||||
#define RTC_BM 31 | |||||
static unsigned int masks [] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF } ; | |||||
/* | |||||
* bcdToD: dToBCD: | |||||
* BCD decode/encode | |||||
********************************************************************************* | |||||
*/ | |||||
static int bcdToD (unsigned int byte, unsigned int mask) | |||||
{ | |||||
unsigned int b1, b2 ; | |||||
byte &= mask ; | |||||
b1 = byte & 0x0F ; | |||||
b2 = ((byte >> 4) & 0x0F) * 10 ; | |||||
return b1 + b2 ; | |||||
} | |||||
static unsigned int dToBcd (unsigned int byte) | |||||
{ | |||||
return ((byte / 10) << 4) + (byte % 10) ; | |||||
} | |||||
/* | |||||
* ramTest: | |||||
* Simple test of the 31 bytes of RAM inside the DS1302 chip | |||||
********************************************************************************* | |||||
*/ | |||||
static int ramTestValues [] = | |||||
{ 0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0xF0, 0x0F, -1 } ; | |||||
static int ramTest (void) | |||||
{ | |||||
int addr ; | |||||
int got ; | |||||
int i = 0 ; | |||||
int errors = 0 ; | |||||
int testVal ; | |||||
printf ("DS1302 RAM TEST\n") ; | |||||
testVal = ramTestValues [i] ; | |||||
while (testVal != -1) | |||||
{ | |||||
for (addr = 0 ; addr < 31 ; ++addr) | |||||
ds1302ramWrite (addr, testVal) ; | |||||
for (addr = 0 ; addr < 31 ; ++addr) | |||||
if ((got = ds1302ramRead (addr)) != testVal) | |||||
{ | |||||
printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n", | |||||
addr, testVal, got) ; | |||||
++errors ; | |||||
} | |||||
testVal = ramTestValues [++i] ; | |||||
} | |||||
for (addr = 0 ; addr < 31 ; ++addr) | |||||
ds1302ramWrite (addr, addr) ; | |||||
for (addr = 0 ; addr < 31 ; ++addr) | |||||
if ((got = ds1302ramRead (addr)) != addr) | |||||
{ | |||||
printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n", | |||||
addr, addr, got) ; | |||||
++errors ; | |||||
} | |||||
if (errors == 0) | |||||
printf ("-- DS1302 RAM TEST: OK\n") ; | |||||
else | |||||
printf ("-- DS1302 RAM TEST FAILURE. %d errors.\n", errors) ; | |||||
return 0 ; | |||||
} | |||||
/* | |||||
* setLinuxClock: | |||||
* Set the Linux clock from the hardware | |||||
********************************************************************************* | |||||
*/ | |||||
static int setLinuxClock (void) | |||||
{ | |||||
char dateTime [20] ; | |||||
char command [64] ; | |||||
int clock [8] ; | |||||
printf ("Setting the Linux Clock from the DS1302... ") ; fflush (stdout) ; | |||||
ds1302clockRead (clock) ; | |||||
// [MMDDhhmm[[CC]YY][.ss]] | |||||
sprintf (dateTime, "%02d%02d%02d%02d%02d%02d.%02d", | |||||
bcdToD (clock [RTC_MONTH], masks [RTC_MONTH]), | |||||
bcdToD (clock [RTC_DATE], masks [RTC_DATE]), | |||||
bcdToD (clock [RTC_HOURS], masks [RTC_HOURS]), | |||||
bcdToD (clock [RTC_MINS], masks [RTC_MINS]), | |||||
20, | |||||
bcdToD (clock [RTC_YEAR], masks [RTC_YEAR]), | |||||
bcdToD (clock [RTC_SECS], masks [RTC_SECS])) ; | |||||
sprintf (command, "/bin/date %s", dateTime) ; | |||||
system (command) ; | |||||
return 0 ; | |||||
} | |||||
/* | |||||
* setDSclock: | |||||
* Set the DS1302 block from Linux time | |||||
********************************************************************************* | |||||
*/ | |||||
static int setDSclock (void) | |||||
{ | |||||
struct tm t ; | |||||
time_t now ; | |||||
int clock [8] ; | |||||
printf ("Setting the clock in the DS1302 from Linux time... ") ; | |||||
now = time (NULL) ; | |||||
gmtime_r (&now, &t) ; | |||||
clock [ 0] = dToBcd (t.tm_sec) ; // seconds | |||||
clock [ 1] = dToBcd (t.tm_min) ; // mins | |||||
clock [ 2] = dToBcd (t.tm_hour) ; // hours | |||||
clock [ 3] = dToBcd (t.tm_mday) ; // date | |||||
clock [ 4] = dToBcd (t.tm_mon + 1) ; // months 0-11 --> 1-12 | |||||
clock [ 5] = dToBcd (t.tm_wday + 1) ; // weekdays (sun 0) | |||||
clock [ 6] = dToBcd (t.tm_year - 100) ; // years | |||||
clock [ 7] = 0 ; // W-Protect off | |||||
ds1302clockWrite (clock) ; | |||||
printf ("OK\n") ; | |||||
return 0 ; | |||||
} | |||||
int main (int argc, char *argv []) | |||||
{ | |||||
int i ; | |||||
int clock [8] ; | |||||
wiringPiSetup () ; | |||||
ds1302setup (0, 1, 2) ; | |||||
if (argc == 2) | |||||
{ | |||||
/**/ if (strcmp (argv [1], "-slc") == 0) | |||||
return setLinuxClock () ; | |||||
else if (strcmp (argv [1], "-sdsc") == 0) | |||||
return setDSclock () ; | |||||
else if (strcmp (argv [1], "-rtest") == 0) | |||||
return ramTest () ; | |||||
else | |||||
{ | |||||
printf ("Usage: ds1302 [-slc | -sdsc | -rtest]\n") ; | |||||
return EXIT_FAILURE ; | |||||
} | |||||
} | |||||
for (i = 0 ;; ++i) | |||||
{ | |||||
printf ("%5d: ", i) ; | |||||
ds1302clockRead (clock) ; | |||||
printf (" %2d:%02d:%02d", | |||||
bcdToD (clock [2], masks [2]), bcdToD (clock [1], masks [1]), bcdToD (clock [0], masks [0])) ; | |||||
printf (" %2d/%02d/%04d", | |||||
bcdToD (clock [3], masks [3]), bcdToD (clock [4], masks [4]), bcdToD (clock [6], masks [6]) + 2000) ; | |||||
printf ("\n") ; | |||||
delay (200) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -38,16 +38,11 @@ | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
// What GPIO input are we using? | |||||
// This is a wiringPi pin number | |||||
#define BUTTON_PIN 0 | |||||
// globalCounter: | // globalCounter: | ||||
// Global variable to count interrupts | // Global variable to count interrupts | ||||
// Should be declared volatile to make sure the compiler doesn't cache it. | // Should be declared volatile to make sure the compiler doesn't cache it. | ||||
static volatile int globalCounter = 0 ; | |||||
static volatile int globalCounter [8] ; | |||||
/* | /* | ||||
@@ -55,10 +50,14 @@ static volatile int globalCounter = 0 ; | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void myInterrupt (void) | |||||
{ | |||||
++globalCounter ; | |||||
} | |||||
void myInterrupt0 (void) { ++globalCounter [0] ; } | |||||
void myInterrupt1 (void) { ++globalCounter [1] ; } | |||||
void myInterrupt2 (void) { ++globalCounter [2] ; } | |||||
void myInterrupt3 (void) { ++globalCounter [3] ; } | |||||
void myInterrupt4 (void) { ++globalCounter [4] ; } | |||||
void myInterrupt5 (void) { ++globalCounter [5] ; } | |||||
void myInterrupt6 (void) { ++globalCounter [6] ; } | |||||
void myInterrupt7 (void) { ++globalCounter [7] ; } | |||||
/* | /* | ||||
@@ -69,30 +68,42 @@ void myInterrupt (void) | |||||
int main (void) | int main (void) | ||||
{ | { | ||||
int myCounter = 0 ; | |||||
int gotOne, pin ; | |||||
int myCounter [8] ; | |||||
if (wiringPiSetup () < 0) | |||||
{ | |||||
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
globalCounter [pin] = myCounter [pin] = 0 ; | |||||
if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0) | |||||
{ | |||||
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
wiringPiSetup () ; | |||||
wiringPiISR (0, INT_EDGE_FALLING, &myInterrupt0) ; | |||||
wiringPiISR (1, INT_EDGE_FALLING, &myInterrupt1) ; | |||||
wiringPiISR (2, INT_EDGE_FALLING, &myInterrupt2) ; | |||||
wiringPiISR (3, INT_EDGE_FALLING, &myInterrupt3) ; | |||||
wiringPiISR (4, INT_EDGE_FALLING, &myInterrupt4) ; | |||||
wiringPiISR (5, INT_EDGE_FALLING, &myInterrupt5) ; | |||||
wiringPiISR (6, INT_EDGE_FALLING, &myInterrupt6) ; | |||||
wiringPiISR (7, INT_EDGE_FALLING, &myInterrupt7) ; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
gotOne = 0 ; | |||||
printf ("Waiting ... ") ; fflush (stdout) ; | printf ("Waiting ... ") ; fflush (stdout) ; | ||||
while (myCounter == globalCounter) | |||||
delay (100) ; | |||||
printf (" Done. counter: %5d\n", globalCounter) ; | |||||
myCounter = globalCounter ; | |||||
for (;;) | |||||
{ | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
{ | |||||
if (globalCounter [pin] != myCounter [pin]) | |||||
{ | |||||
printf (" Int on pin %d: Counter: %5d\n", pin, globalCounter [pin]) ; | |||||
myCounter [pin] = globalCounter [pin] ; | |||||
++gotOne ; | |||||
} | |||||
} | |||||
if (gotOne != 0) | |||||
break ; | |||||
} | |||||
} | } | ||||
return 0 ; | return 0 ; | ||||
@@ -4,7 +4,19 @@ | |||||
* This is designed to drive the parallel interface LCD drivers | * This is designed to drive the parallel interface LCD drivers | ||||
* based in the Hitachi HD44780U controller and compatables. | * based in the Hitachi HD44780U controller and compatables. | ||||
* | * | ||||
* Copyright (c) 2012 Gordon Henderson. | |||||
* This test program assumes the following: | |||||
* | |||||
* 8-bit displays: | |||||
* GPIO 0-7 is connected to display data pins 0-7. | |||||
* GPIO 11 is the RS pin. | |||||
* GPIO 10 is the Strobe/E pin. | |||||
* | |||||
* For 4-bit interface: | |||||
* GPIO 4-7 is connected to display data pins 4-7. | |||||
* GPIO 11 is the RS pin. | |||||
* GPIO 10 is the Strobe/E pin. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -35,94 +47,208 @@ | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
#include <lcd.h> | #include <lcd.h> | ||||
int main (void) | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
static unsigned char newChar [8] = | |||||
{ | { | ||||
int i, j ; | |||||
int fd1, fd2 ; | |||||
0b11111, | |||||
0b10001, | |||||
0b10001, | |||||
0b10101, | |||||
0b11111, | |||||
0b10001, | |||||
0b10001, | |||||
0b11111, | |||||
} ; | |||||
int usage (const char *progName) | |||||
{ | |||||
fprintf (stderr, "Usage: %s bits cols rows\n", progName) ; | |||||
return EXIT_FAILURE ; | |||||
} | |||||
static const char *message = | |||||
" " | |||||
"Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/" | |||||
" " ; | |||||
void scrollMessage (int lcd, int line, int width) | |||||
{ | |||||
char buf [32] ; | |||||
static int position = 0 ; | |||||
strncpy (buf, &message [position], width) ; | |||||
buf [width] = 0 ; | |||||
lcdPosition (lcd, 0, line) ; | |||||
lcdPuts (lcd, buf) ; | |||||
if (++position == (strlen (message) - width)) | |||||
position = 0 ; | |||||
} | |||||
static void pingPong (int lcd, int cols) | |||||
{ | |||||
static int position = 0 ; | |||||
static int dir = 0 ; | |||||
if (dir == 0) // Setup | |||||
{ | |||||
dir = 1 ; | |||||
lcdPosition (lcd, 0, 3) ; | |||||
lcdPutchar (lcd, '*') ; | |||||
return ; | |||||
} | |||||
char message1 [256] ; | |||||
char message2 [256] ; | |||||
char buf1 [30] ; | |||||
char buf2 [30] ; | |||||
lcdPosition (lcd, position, 3) ; | |||||
lcdPutchar (lcd, ' ') ; | |||||
position += dir ; | |||||
if (position == cols) | |||||
{ | |||||
dir = -1 ; | |||||
--position ; | |||||
} | |||||
if (position < 0) | |||||
{ | |||||
dir = 1 ; | |||||
++position ; | |||||
} | |||||
lcdPosition (lcd, position, 3) ; | |||||
lcdPutchar (lcd, '#') ; | |||||
} | |||||
static void waitForEnter (void) | |||||
{ | |||||
printf ("Press ENTER to continue: ") ; | |||||
(void)fgetc (stdin) ; | |||||
} | |||||
int main (int argc, char *argv[]) | |||||
{ | |||||
int i ; | |||||
int lcd ; | |||||
int bits, rows, cols ; | |||||
struct tm *t ; | struct tm *t ; | ||||
time_t tim ; | time_t tim ; | ||||
printf ("Raspberry Pi LCD test program\n") ; | |||||
char buf [32] ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
if (argc != 4) | |||||
return usage (argv [0]) ; | |||||
fd1 = lcdInit (4, 20, 4, 8, 9, 4,5,6,7,0,0,0,0) ; | |||||
fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ; | |||||
printf ("Raspberry Pi LCD test\n") ; | |||||
printf ("=====================\n") ; | |||||
//fd1 = lcdInit (4, 20, 8, 8, 9, 0,1,2,3,4,5,6,7) ; | |||||
//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ; | |||||
bits = atoi (argv [1]) ; | |||||
cols = atoi (argv [2]) ; | |||||
rows = atoi (argv [3]) ; | |||||
if (fd1 == -1) | |||||
if (!((rows == 1) || (rows == 2) || (rows == 4))) | |||||
{ | { | ||||
printf ("lcdInit 1 failed\n") ; | |||||
return 1 ; | |||||
fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ; | |||||
return EXIT_FAILURE ; | |||||
} | } | ||||
if (fd2 == -1) | |||||
if (!((cols == 16) || (cols == 20))) | |||||
{ | { | ||||
printf ("lcdInit 2 failed\n") ; | |||||
return 1 ; | |||||
fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ; | |||||
return EXIT_FAILURE ; | |||||
} | } | ||||
sleep (1) ; | |||||
wiringPiSetup () ; | |||||
lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ; | |||||
lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, " --------------") ; | |||||
/* | |||||
lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, " 00:00:00") ; | |||||
lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, " DD:MM:YY") ; | |||||
*/ | |||||
if (bits == 4) | |||||
lcd = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ; | |||||
else | |||||
lcd = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ; | |||||
if (lcd < 0) | |||||
{ | |||||
fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ; | |||||
return -1 ; | |||||
} | |||||
lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "Gordon Henderson") ; | |||||
lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ; | |||||
lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ; | |||||
if (rows > 1) | |||||
{ | |||||
lcdPosition (lcd, 0, 1) ; | |||||
for (i = 0 ; i < (cols - 1) ; ++i) | |||||
lcdPutchar (lcd, '*') ; | |||||
lcdPutchar (lcd, '2') ; | |||||
if (rows == 4) | |||||
{ | |||||
lcdPosition (lcd, 0, 2) ; | |||||
for (i = 0 ; i < ((cols - 1) / 2) ; ++i) | |||||
lcdPuts (lcd, "=-") ; | |||||
lcdPuts (lcd, "=3") ; | |||||
lcdPosition (lcd, 0, 3) ; | |||||
for (i = 0 ; i < ((cols - 1) / 2) ; ++i) | |||||
lcdPuts (lcd, "-=") ; | |||||
lcdPuts (lcd, "-4") ; | |||||
} | |||||
} | |||||
sleep (2) ; | sleep (2) ; | ||||
sprintf (message1, "%s", " http://projects.drogon.net/ ") ; | |||||
sprintf (message2, "%s", " This is a long message to go into the smaller display just for a demonstration of what we can do. ") ; | |||||
lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, " wiringpi.com ") ; | |||||
waitForEnter () ; | |||||
lcdCharDef (lcd, 2, newChar) ; | |||||
lcdClear (lcd) ; | |||||
lcdPosition (lcd, 0, 0) ; | |||||
lcdPuts (lcd, "User Char: ") ; | |||||
lcdPutchar (lcd, 2) ; | |||||
lcdCursor (lcd, TRUE) ; | |||||
lcdCursorBlink (lcd, TRUE) ; | |||||
waitForEnter () ; | |||||
lcdCursor (lcd, FALSE) ; | |||||
lcdCursorBlink (lcd, FALSE) ; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
i = 0 ; | |||||
j = 0 ; | |||||
for (;;) | |||||
{ | |||||
strncpy (buf1, &message1 [i], 20) ; | |||||
buf1 [20] = 0 ; | |||||
lcdPosition (fd1, 0, 1) ; | |||||
lcdPuts (fd1, buf1) ; | |||||
++i ; | |||||
if (i == strlen (message1) - 20) | |||||
i = 0 ; | |||||
strncpy (buf2, &message2 [j], 16) ; | |||||
buf2 [16] = 0 ; | |||||
lcdPosition (fd2, 0, 1) ; | |||||
lcdPuts (fd2, buf2) ; | |||||
++j ; | |||||
if (j == strlen (message2) - 16) | |||||
j = 0 ; | |||||
tim = time (NULL) ; | |||||
t = localtime (&tim) ; | |||||
sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; | |||||
lcdPosition (fd1, 5, 2) ; | |||||
lcdPuts (fd1, buf1) ; | |||||
sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; | |||||
lcdPosition (fd1, 4, 3) ; | |||||
lcdPuts (fd1, buf1) ; | |||||
delay (250) ; | |||||
} | |||||
delay (250) ; | |||||
scrollMessage (lcd, 0, cols) ; | |||||
if (rows == 1) | |||||
continue ; | |||||
tim = time (NULL) ; | |||||
t = localtime (&tim) ; | |||||
sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; | |||||
lcdPosition (lcd, (cols - 8) / 2, 1) ; | |||||
lcdPuts (lcd, buf) ; | |||||
if (rows == 2) | |||||
continue ; | |||||
sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; | |||||
lcdPosition (lcd, (cols - 10) / 2, 2) ; | |||||
lcdPuts (lcd, buf) ; | |||||
pingPong (lcd, cols) ; | |||||
} | } | ||||
return 0 ; | return 0 ; | ||||
@@ -39,27 +39,26 @@ | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
#include <softPwm.h> | #include <softPwm.h> | ||||
// The OK/Act LED is connected to BCM_GPIO pin 16 | |||||
#define OK_LED 16 | #define OK_LED 16 | ||||
int main () | int main () | ||||
{ | { | ||||
int fd, i ; | int fd, i ; | ||||
wiringPiSetupGpio () ; | |||||
// Change the trigger on the OK/Act LED to "none" | |||||
if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0) | if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0) | ||||
{ | { | ||||
fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ; | fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ; | ||||
return 1 ; | return 1 ; | ||||
} | } | ||||
write (fd, "none\n", 5) ; | write (fd, "none\n", 5) ; | ||||
close (fd) ; | close (fd) ; | ||||
if (wiringPiSetupGpio () < 0) | |||||
{ | |||||
fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
softPwmCreate (OK_LED, 0, 100) ; | softPwmCreate (OK_LED, 0, 100) ; | ||||
for (;;) | for (;;) | ||||
@@ -1,7 +1,6 @@ | |||||
/* | /* | ||||
* pwm.c: | * pwm.c: | ||||
* Test of the software PWM driver. Needs 12 LEDs connected | |||||
* to the Pi. | |||||
* This tests the hardware PWM channel. | |||||
* | * | ||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | ||||
*********************************************************************** | *********************************************************************** | ||||
@@ -23,71 +22,37 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <stdio.h> | |||||
#include <errno.h> | |||||
#include <string.h> | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
#include <softPwm.h> | |||||
#define RANGE 100 | |||||
#define NUM_LEDS 12 | |||||
int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ; | |||||
int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ; | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
int main () | |||||
int main (void) | |||||
{ | { | ||||
int i, j ; | |||||
char buf [80] ; | |||||
int bright ; | |||||
if (wiringPiSetup () == -1) | |||||
{ | |||||
fprintf (stdout, "oops: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
{ | |||||
softPwmCreate (ledMap [i], 0, RANGE) ; | |||||
printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ; | |||||
} | |||||
printf ("Raspberry Pi wiringPi PWM test program\n") ; | |||||
fgets (buf, 80, stdin) ; | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
// Bring all up one by one: | |||||
pinMode (1, PWM_OUTPUT) ; | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
for (j = 0 ; j <= 100 ; ++j) | |||||
for (;;) | |||||
{ | |||||
for (bright = 0 ; bright < 1024 ; ++bright) | |||||
{ | { | ||||
softPwmWrite (ledMap [i], j) ; | |||||
delay (10) ; | |||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
} | } | ||||
fgets (buf, 80, stdin) ; | |||||
// Down fast | |||||
for (i = 100 ; i > 0 ; --i) | |||||
{ | |||||
for (j = 0 ; j < NUM_LEDS ; ++j) | |||||
softPwmWrite (ledMap [j], i) ; | |||||
delay (10) ; | |||||
for (bright = 1023 ; bright >= 0 ; --bright) | |||||
{ | |||||
pwmWrite (1, bright) ; | |||||
delay (1) ; | |||||
} | |||||
} | } | ||||
fgets (buf, 80, stdin) ; | |||||
for (;;) | |||||
{ | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
softPwmWrite (ledMap [i], values [i]) ; | |||||
delay (50) ; | |||||
i = values [0] ; | |||||
for (j = 0 ; j < NUM_LEDS - 1 ; ++j) | |||||
values [j] = values [j + 1] ; | |||||
values [NUM_LEDS - 1] = i ; | |||||
} | |||||
return 0 ; | |||||
} | } |
@@ -1,8 +1,6 @@ | |||||
/* | /* | ||||
* piFace.c: | |||||
* Simple test for the PiFace interface board. | |||||
* | |||||
* Read the buttons and output the same to the LEDs | |||||
* rht03.c: | |||||
* Driver for the MaxDetect series sensors | |||||
* | * | ||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | ||||
*********************************************************************** | *********************************************************************** | ||||
@@ -24,47 +22,42 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <wiringPi.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
int outputs [4] = { 0,0,0,0 } ; | |||||
void scanButton (int button) | |||||
{ | |||||
if (digitalRead (button) == LOW) | |||||
{ | |||||
outputs [button] ^= 1 ; | |||||
digitalWrite (button, outputs [button]) ; | |||||
} | |||||
#include <wiringPi.h> | |||||
#include <maxdetect.h> | |||||
while (digitalRead (button) == LOW) | |||||
delay (1) ; | |||||
} | |||||
#define RHT03_PIN 0 | |||||
/* | |||||
*********************************************************************** | |||||
* The main program | |||||
*********************************************************************** | |||||
*/ | |||||
int main (void) | int main (void) | ||||
{ | { | ||||
int pin, button ; | |||||
printf ("Raspberry Pi wiringPiFace test program\n") ; | |||||
int temp, rh ; | |||||
int newTemp, newRh ; | |||||
if (wiringPiSetupPiFace () == -1) | |||||
exit (1) ; | |||||
// Enable internal pull-ups | |||||
for (pin = 0 ; pin < 8 ; ++pin) | |||||
pullUpDnControl (pin, PUD_UP) ; | |||||
temp = rh = newTemp = newRh = 0 ; | |||||
wiringPiSetup () ; | |||||
piHiPri (55) ; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
for (button = 0 ; button < 4 ; ++button) | |||||
scanButton (button) ; | |||||
delay (1) ; | |||||
delay (100) ; | |||||
if (!readRHT03 (RHT03_PIN, &newTemp, &newRh)) | |||||
continue ; | |||||
if ((temp != newTemp) || (rh != newRh)) | |||||
{ | |||||
temp = newTemp ; | |||||
rh = newRh ; | |||||
printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ; | |||||
} | |||||
} | } | ||||
return 0 ; | return 0 ; |
@@ -0,0 +1,89 @@ | |||||
/* | |||||
* softPwm.c: | |||||
* Test of the software PWM driver. Needs 8 LEDs connected | |||||
* to the Pi - e.g. Ladder board. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as published by | |||||
* the Free Software Foundation, either version 3 of the License, or | |||||
* (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <errno.h> | |||||
#include <string.h> | |||||
#include <wiringPi.h> | |||||
#include <softPwm.h> | |||||
#define RANGE 100 | |||||
#define NUM_LEDS 8 | |||||
int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7 } ; | |||||
int values [NUM_LEDS] = { 0, 25, 50, 75, 100, 75, 50, 25 } ; | |||||
int main () | |||||
{ | |||||
int i, j ; | |||||
char buf [80] ; | |||||
wiringPiSetup () ; | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
{ | |||||
softPwmCreate (ledMap [i], 0, RANGE) ; | |||||
printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ; | |||||
} | |||||
fgets (buf, 80, stdin) ; | |||||
// Bring all up one by one: | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
for (j = 0 ; j <= 100 ; ++j) | |||||
{ | |||||
softPwmWrite (ledMap [i], j) ; | |||||
delay (10) ; | |||||
} | |||||
fgets (buf, 80, stdin) ; | |||||
// All Down | |||||
for (i = 100 ; i > 0 ; --i) | |||||
{ | |||||
for (j = 0 ; j < NUM_LEDS ; ++j) | |||||
softPwmWrite (ledMap [j], i) ; | |||||
delay (10) ; | |||||
} | |||||
fgets (buf, 80, stdin) ; | |||||
for (;;) | |||||
{ | |||||
for (i = 0 ; i < NUM_LEDS ; ++i) | |||||
softPwmWrite (ledMap [i], values [i]) ; | |||||
delay (50) ; | |||||
i = values [0] ; | |||||
for (j = 0 ; j < NUM_LEDS - 1 ; ++j) | |||||
values [j] = values [j + 1] ; | |||||
values [NUM_LEDS - 1] = i ; | |||||
} | |||||
} |
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* tone.c: | |||||
* softTone.c: | |||||
* Test of the softTone module in wiringPi | * Test of the softTone module in wiringPi | ||||
* Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v | * Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v | ||||
* | * | ||||
@@ -38,11 +38,7 @@ int main () | |||||
{ | { | ||||
int i ; | int i ; | ||||
if (wiringPiSetup () == -1) | |||||
{ | |||||
fprintf (stdout, "oops: %s\n", strerror (errno)) ; | |||||
return 1 ; | |||||
} | |||||
wiringPiSetup () ; | |||||
softToneCreate (PIN) ; | softToneCreate (PIN) ; | ||||
@@ -55,5 +51,4 @@ int main () | |||||
delay (500) ; | delay (500) ; | ||||
} | } | ||||
} | } | ||||
} | } |
@@ -31,93 +31,65 @@ | |||||
#define FAST_COUNT 10000000 | #define FAST_COUNT 10000000 | ||||
#define SLOW_COUNT 1000000 | #define SLOW_COUNT 1000000 | ||||
#define PASSES 5 | |||||
int main (void) | |||||
void speedTest (int pin, int maxCount) | |||||
{ | { | ||||
int i ; | |||||
uint32_t start, end, count, sum, perSec ; | |||||
printf ("Raspberry Pi wiringPi speed test program\n") ; | |||||
// Start the standard way | |||||
if (wiringPiSetup () == -1) | |||||
exit (1) ; | |||||
printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ; | |||||
pinMode (0, OUTPUT) ; | |||||
int count, sum, perSec, i ; | |||||
unsigned int start, end ; | |||||
sum = 0 ; | sum = 0 ; | ||||
for (i = 0 ; i < 3 ; ++i) | |||||
{ | |||||
printf (" Pass: %d: ", i) ; | |||||
fflush (stdout) ; | |||||
for (i = 0 ; i < PASSES ; ++i) | |||||
{ | |||||
start = millis () ; | start = millis () ; | ||||
for (count = 0 ; count < FAST_COUNT ; ++count) | |||||
digitalWrite (0, 1) ; | |||||
for (count = 0 ; count < maxCount ; ++count) | |||||
digitalWrite (pin, 1) ; | |||||
end = millis () ; | end = millis () ; | ||||
printf (" %8dmS\n", end - start) ; | |||||
printf (" %6d", end - start) ; | |||||
fflush (stdout) ; | |||||
sum += (end - start) ; | sum += (end - start) ; | ||||
} | } | ||||
digitalWrite (0, 0) ; | |||||
printf (" Average: %8dmS", sum / 3) ; | |||||
perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; | |||||
printf (": %6d/sec\n", perSec) ; | |||||
digitalWrite (pin, 0) ; | |||||
printf (". Av: %6dmS", sum / PASSES) ; | |||||
perSec = (int)(double)maxCount / (double)((double)sum / (double)PASSES) * 1000.0 ; | |||||
printf (": %7d/sec\n", perSec) ; | |||||
} | |||||
printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ; | |||||
if (wiringPiSetupGpio () == -1) | |||||
exit (1) ; | |||||
pinMode (17, OUTPUT) ; | |||||
int main (void) | |||||
{ | |||||
printf ("Raspberry Pi wiringPi GPIO speed test program\n") ; | |||||
printf ("=============================================\n") ; | |||||
sum = 0 ; | |||||
for (i = 0 ; i < 3 ; ++i) | |||||
{ | |||||
printf (" Pass: %d: ", i) ; | |||||
fflush (stdout) ; | |||||
// Start the standard way | |||||
start = millis () ; | |||||
for (count = 0 ; count < 10000000 ; ++count) | |||||
digitalWrite (17, 1) ; | |||||
end = millis () ; | |||||
printf (" %8dmS\n", end - start) ; | |||||
sum += (end - start) ; | |||||
} | |||||
digitalWrite (17, 0) ; | |||||
printf (" Average: %8dmS", sum / 3) ; | |||||
perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; | |||||
printf (": %6d/sec\n", perSec) ; | |||||
printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ; | |||||
wiringPiSetup () ; | |||||
pinMode (0, OUTPUT) ; | |||||
speedTest (0, FAST_COUNT) ; | |||||
// GPIO | |||||
// Switch to SYS mode: | |||||
printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ; | |||||
wiringPiSetupGpio () ; | |||||
pinMode (17, OUTPUT) ; | |||||
speedTest (17, FAST_COUNT) ; | |||||
if (wiringPiSetupSys () == -1) | |||||
exit (1) ; | |||||
// Phys | |||||
printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; | |||||
printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ; | |||||
wiringPiSetupPhys () ; | |||||
pinMode (11, OUTPUT) ; | |||||
speedTest (11, FAST_COUNT) ; | |||||
sum = 0 ; | |||||
for (i = 0 ; i < 3 ; ++i) | |||||
{ | |||||
printf (" Pass: %d: ", i) ; | |||||
fflush (stdout) ; | |||||
// Switch to SYS mode: | |||||
start = millis () ; | |||||
for (count = 0 ; count < SLOW_COUNT ; ++count) | |||||
digitalWrite (17, 1) ; | |||||
end = millis () ; | |||||
printf (" %8dmS\n", end - start) ; | |||||
sum += (end - start) ; | |||||
} | |||||
digitalWrite (17, 0) ; | |||||
printf (" Average: %8dmS", sum / 3) ; | |||||
perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ; | |||||
printf (": %6d/sec\n", perSec) ; | |||||
system ("/usr/local/bin/gpio export 17 out") ; | |||||
printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; | |||||
wiringPiSetupSys () ; | |||||
speedTest (17, SLOW_COUNT) ; | |||||
return 0 ; | return 0 ; | ||||
} | } |
@@ -30,20 +30,20 @@ INCLUDE = -I/usr/local/include | |||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | ||||
LDFLAGS = -L/usr/local/lib | LDFLAGS = -L/usr/local/lib | ||||
LIBS = -lwiringPi -lpthread -lm | |||||
LIBS = -lwiringPi -lwiringPiDev -lpthread -lm | |||||
# May not need to alter anything below this line | # May not need to alter anything below this line | ||||
############################################################################### | ############################################################################### | ||||
SRC = gpio.c | |||||
SRC = gpio.c extensions.c | |||||
OBJ = $(SRC:.c=.o) | OBJ = $(SRC:.c=.o) | ||||
all: gpio | all: gpio | ||||
gpio: gpio.o | |||||
gpio: $(OBJ) | |||||
@echo [Link] | @echo [Link] | ||||
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) | |||||
@$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) | |||||
.c.o: | .c.o: | ||||
@echo [Compile] $< | @echo [Compile] $< | ||||
@@ -51,7 +51,8 @@ gpio: gpio.o | |||||
.PHONEY: clean | .PHONEY: clean | ||||
clean: | clean: | ||||
rm -f $(OBJ) gpio *~ core tags *.bak | |||||
@echo "[Clean]" | |||||
@rm -f $(OBJ) gpio *~ core tags *.bak | |||||
.PHONEY: tags | .PHONEY: tags | ||||
tags: $(SRC) | tags: $(SRC) | ||||
@@ -78,3 +79,6 @@ depend: | |||||
makedepend -Y $(SRC) | makedepend -Y $(SRC) | ||||
# DO NOT DELETE | # DO NOT DELETE | ||||
gpio.o: extensions.h | |||||
extensions.o: extensions.h |
@@ -0,0 +1,329 @@ | |||||
/* | |||||
* extensions.c: | |||||
* Part of the GPIO program to test, peek, poke and otherwise | |||||
* noodle with the GPIO hardware on the Raspberry Pi. | |||||
* 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 <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdint.h> | |||||
#include <ctype.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <errno.h> | |||||
#include <sys/types.h> | |||||
#include <fcntl.h> | |||||
#include <wiringPi.h> | |||||
#include <mcp23008.h> | |||||
#include <mcp23017.h> | |||||
#include <mcp23s08.h> | |||||
#include <mcp23s17.h> | |||||
#include <sr595.h> | |||||
#include "extensions.h" | |||||
extern int wiringPiDebug ; | |||||
#ifndef TRUE | |||||
# define TRUE (1==1) | |||||
# define FALSE (1==2) | |||||
#endif | |||||
// Local structure to hold details | |||||
struct extensionFunctionStruct | |||||
{ | |||||
const char *name ; | |||||
int (*function)(char *progName, int pinBase, char *params) ; | |||||
} ; | |||||
/* | |||||
* extractInt: | |||||
* Check & return an integer at the given location (prefixed by a :) | |||||
********************************************************************************* | |||||
*/ | |||||
static char *extractInt (char *progName, char *p, int *num) | |||||
{ | |||||
if (*p != ':') | |||||
{ | |||||
fprintf (stderr, "%s: colon expected\n", progName) ; | |||||
return NULL ; | |||||
} | |||||
++p ; | |||||
if (!isdigit (*p)) | |||||
{ | |||||
fprintf (stderr, "%s: digit expected\n", progName) ; | |||||
return NULL ; | |||||
} | |||||
*num = strtol (p, NULL, 0) ; | |||||
while (isdigit (*p)) | |||||
++p ; | |||||
return p ; | |||||
} | |||||
/* | |||||
* doExtensionMcp23008: | |||||
* MCP23008 - 8-bit I2C GPIO expansion chip | |||||
* mcp23002:base:i2cAddr | |||||
********************************************************************************* | |||||
*/ | |||||
static int doExtensionMcp23008 (char *progName, int pinBase, char *params) | |||||
{ | |||||
int i2c ; | |||||
if ((params = extractInt (progName, params, &i2c)) == NULL) | |||||
return FALSE ; | |||||
if ((i2c < 0x03) || (i2c > 0x77)) | |||||
{ | |||||
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ; | |||||
return FALSE ; | |||||
} | |||||
mcp23008Setup (pinBase, i2c) ; | |||||
return TRUE ; | |||||
} | |||||
/* | |||||
* doExtensionMcp23017: | |||||
* MCP23008 - 16-bit I2C GPIO expansion chip | |||||
* mcp23002:base:i2cAddr | |||||
********************************************************************************* | |||||
*/ | |||||
static int doExtensionMcp23017 (char *progName, int pinBase, char *params) | |||||
{ | |||||
int i2c ; | |||||
if ((params = extractInt (progName, params, &i2c)) == NULL) | |||||
return FALSE ; | |||||
if ((i2c < 0x03) || (i2c > 0x77)) | |||||
{ | |||||
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ; | |||||
return FALSE ; | |||||
} | |||||
mcp23017Setup (pinBase, i2c) ; | |||||
return TRUE ; | |||||
} | |||||
/* | |||||
* doExtensionMcp23s08: | |||||
* MCP23s08 - 8-bit SPI GPIO expansion chip | |||||
* mcp23s08:base:spi:port | |||||
********************************************************************************* | |||||
*/ | |||||
static int doExtensionMcp23s08 (char *progName, int pinBase, char *params) | |||||
{ | |||||
int spi, port ; | |||||
if ((params = extractInt (progName, params, &spi)) == NULL) | |||||
return FALSE ; | |||||
if ((spi < 0) || (spi > 1)) | |||||
{ | |||||
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ; | |||||
return FALSE ; | |||||
} | |||||
if ((params = extractInt (progName, params, &port)) == NULL) | |||||
return FALSE ; | |||||
if ((port < 0) || (port > 7)) | |||||
{ | |||||
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ; | |||||
return FALSE ; | |||||
} | |||||
mcp23s08Setup (pinBase, spi, port) ; | |||||
return TRUE ; | |||||
} | |||||
/* | |||||
* doExtensionMcp23s17: | |||||
* MCP23s17 - 16-bit SPI GPIO expansion chip | |||||
* mcp23s17:base:spi:port | |||||
********************************************************************************* | |||||
*/ | |||||
static int doExtensionMcp23s17 (char *progName, int pinBase, char *params) | |||||
{ | |||||
int spi, port ; | |||||
if ((params = extractInt (progName, params, &spi)) == NULL) | |||||
return FALSE ; | |||||
if ((spi < 0) || (spi > 1)) | |||||
{ | |||||
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ; | |||||
return FALSE ; | |||||
} | |||||
if ((params = extractInt (progName, params, &port)) == NULL) | |||||
return FALSE ; | |||||
if ((port < 0) || (port > 7)) | |||||
{ | |||||
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ; | |||||
return FALSE ; | |||||
} | |||||
mcp23s17Setup (pinBase, spi, port) ; | |||||
return TRUE ; | |||||
} | |||||
/* | |||||
* doExtensionSr595: | |||||
* Shift Register 74x595 | |||||
* sr595:base:pins:data:clock:latch | |||||
********************************************************************************* | |||||
*/ | |||||
static int doExtensionSr595 (char *progName, int pinBase, char *params) | |||||
{ | |||||
int pins, data, clock, latch ; | |||||
// Extract pins | |||||
if ((params = extractInt (progName, params, &pins)) == NULL) | |||||
return FALSE ; | |||||
if ((pins < 8) || (pins > 32)) | |||||
{ | |||||
fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ; | |||||
return FALSE ; | |||||
} | |||||
if ((params = extractInt (progName, params, &data)) == NULL) | |||||
return FALSE ; | |||||
if ((params = extractInt (progName, params, &clock)) == NULL) | |||||
return FALSE ; | |||||
if ((params = extractInt (progName, params, &latch)) == NULL) | |||||
return FALSE ; | |||||
sr595Setup (pinBase, pins, data, clock, latch) ; | |||||
return TRUE ; | |||||
} | |||||
/* | |||||
* Function list | |||||
********************************************************************************* | |||||
*/ | |||||
struct extensionFunctionStruct extensionFunctions [] = | |||||
{ | |||||
{ "mcp23008", &doExtensionMcp23008 }, | |||||
{ "mcp23017", &doExtensionMcp23017 }, | |||||
{ "mcp23s08", &doExtensionMcp23s08 }, | |||||
{ "mcp23s17", &doExtensionMcp23s17 }, | |||||
{ "sr595", &doExtensionSr595 }, | |||||
{ NULL, NULL }, | |||||
} ; | |||||
/* | |||||
* doExtension: | |||||
* Load in a wiringPi extension | |||||
********************************************************************************* | |||||
*/ | |||||
int doExtension (char *progName, char *extensionData) | |||||
{ | |||||
char *p ; | |||||
char *extension = extensionData ; | |||||
struct extensionFunctionStruct *extensionFn ; | |||||
int pinBase = 0 ; | |||||
// Get the extension extension name by finding the first colon | |||||
p = extension ; | |||||
while (*p != ':') | |||||
{ | |||||
if (!*p) // ran out of characters | |||||
{ | |||||
fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ; | |||||
return FALSE ; | |||||
} | |||||
++p ; | |||||
} | |||||
*p++ = 0 ; | |||||
if (!isdigit (*p)) | |||||
{ | |||||
fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ; | |||||
return FALSE ; | |||||
} | |||||
while (isdigit (*p)) | |||||
{ | |||||
if (pinBase > 1000000000) | |||||
{ | |||||
fprintf (stderr, "%s: pinBase too large\n", progName) ; | |||||
return FALSE ; | |||||
} | |||||
pinBase = pinBase * 10 + (*p - '0') ; | |||||
++p ; | |||||
} | |||||
if (pinBase < 64) | |||||
{ | |||||
fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ; | |||||
return FALSE ; | |||||
} | |||||
// Search for extensions: | |||||
for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn) | |||||
{ | |||||
if (strcmp (extensionFn->name, extension) == 0) | |||||
return extensionFn->function (progName, pinBase, p) ; | |||||
} | |||||
fprintf (stderr, "%s: extension %s not found\n", progName, extension) ; | |||||
return FALSE ; | |||||
} |
@@ -0,0 +1,26 @@ | |||||
/* | |||||
* extensions.h: | |||||
* Part of the GPIO program to test, peek, poke and otherwise | |||||
* noodle with the GPIO hardware on the Raspberry Pi. | |||||
* Copyright (c) 2012-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/>. | |||||
*********************************************************************** | |||||
*/ | |||||
extern int doExtension (char *progName, char *extensionData) ; |
@@ -1,15 +1,19 @@ | |||||
.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" | |||||
.TH "GPIO" "March 2013" "Command-Line access to Raspberry Pi's GPIO" | |||||
.SH NAME | .SH NAME | ||||
gpio \- Command-line access to Raspberry Pi and PiFace GPIO | |||||
gpio \- Command-line access to Raspberry Pi's GPIO | |||||
.SH SYNOPSIS | .SH SYNOPSIS | ||||
.B gpio | .B gpio | ||||
.B \-v | .B \-v | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B [ \-g ] | |||||
.B read/write/wb/pwm/clock/mode ... | |||||
.B [ \-g | \-1 ] | |||||
.B mode/read/write/aread/awrite/wb/pwm/clock ... | |||||
.PP | |||||
.B gpio | |||||
.B [ \-x extension:params ] | |||||
.B mode/read/write/aread/awrite/pwm ... | |||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B [ \-p ] | .B [ \-p ] | ||||
@@ -17,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO | |||||
.B ... | .B ... | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B readall | |||||
.B readall/reset | |||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B unexportall/exports | .B unexportall/exports | ||||
@@ -27,6 +31,10 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO | |||||
.B ... | .B ... | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B wfi | |||||
.B ... | |||||
.PP | |||||
.B gpio | |||||
.B drive | .B drive | ||||
group value | group value | ||||
.PP | .PP | ||||
@@ -73,12 +81,28 @@ Output the current version including the board revision of the Raspberry Pi. | |||||
.TP | .TP | ||||
.B \-g | .B \-g | ||||
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. | Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. | ||||
\fINOTE:\fR The BCM_GPIO pin numbers are always used with the | |||||
\fINote:\fR The BCM_GPIO pin numbers are always used with the | |||||
export and edge commands. | export and edge commands. | ||||
.TP | .TP | ||||
.B \-1 | |||||
Use the physical pin numbers rather than wiringPi pin numbers. | |||||
\fINote:\fR that this applies to the P1 connector only. It is not possible to | |||||
use pins on the Revision 2 P5 connector this way, and as with \-g the | |||||
BCM_GPIO pin numbers are always used with the export and edge commands. | |||||
.TP | |||||
.B \-x extension | |||||
This causes the named extension to be initialised. Extensions | |||||
comprise of a name (e.g. mcp23017) followed by a colon, then the | |||||
pin-base, then more optional parameters depending on the extension type. | |||||
See the web page on http://wiringpi.com/the-gpio-utility/ | |||||
.TP | |||||
.B \-p | .B \-p | ||||
Use the PiFace interface board and its corresponding pin numbers. | |||||
Use the PiFace interface board and its corresponding pin numbers. The PiFace | |||||
will always appear at pin number 200 in the gpio command. You can assign any | |||||
pin numbers you like in your own programs though. | |||||
.TP | .TP | ||||
.B read <pin> | .B read <pin> | ||||
@@ -103,6 +127,11 @@ if the pin is in input mode, or the last value written if the pin is in output | |||||
mode. | mode. | ||||
.TP | .TP | ||||
.B reset | |||||
Resets the GPIO - As much as it's possible to do. All pins are set to input | |||||
mode and all the internal pull-up/down resistors are disconnected (tristate mode). | |||||
.TP | |||||
.B pwm <pin> <value> | .B pwm <pin> <value> | ||||
Write a PWM value (0-1023) to the given pin. The pin needs to be put | Write a PWM value (0-1023) to the given pin. The pin needs to be put | ||||
into PWM mode first. | into PWM mode first. | ||||
@@ -158,6 +187,12 @@ requiring root/sudo. | |||||
Un-Export a GPIO pin in the /sys/class/gpio directory. | Un-Export a GPIO pin in the /sys/class/gpio directory. | ||||
.TP | .TP | ||||
.B wfi <pin> <mode> | |||||
This set the given pin to the supplied interrupt mode: rising, falling | |||||
or both then waits for the interrupt to happen. It's a non-busy wait, | |||||
so does not consume and CPU while it's waiting. | |||||
.TP | |||||
.B drive | .B drive | ||||
group value | group value | ||||
@@ -207,26 +242,26 @@ The board jumpers need to be in-place to do this operation. | |||||
.PP | .PP | ||||
.TS | .TS | ||||
r r r l. | |||||
WiringPi GPIO-r1 GPIO-r2 Function | |||||
c c c c l. | |||||
WiringPi GPIO-r1 GPIO-r2 P1-Phys Function | |||||
_ | _ | ||||
0 17 17 | |||||
1 18 18 (PWM) | |||||
2 21 27 | |||||
3 22 22 | |||||
4 23 23 | |||||
5 24 24 | |||||
6 25 25 | |||||
7 4 4 | |||||
8 0 2 I2C: SDA0 | |||||
9 1 3 I2C: SCL0 | |||||
10 8 8 SPI: CE0 | |||||
11 7 7 SPI: CE1 | |||||
12 10 10 SPI: MOSI | |||||
13 9 9 SPI: MISO | |||||
14 11 11 SPI: SCLK | |||||
15 14 14 TxD | |||||
16 15 16 RxD | |||||
0 17 17 11 | |||||
1 18 18 12 (PWM) | |||||
2 21 27 13 | |||||
3 22 22 15 | |||||
4 23 23 16 | |||||
5 24 24 18 | |||||
6 25 25 22 | |||||
7 4 4 7 | |||||
8 0 2 3 I2C: SDA0 | |||||
9 1 3 5 I2C: SCL0 | |||||
10 8 8 24 SPI: CE0 | |||||
11 7 7 26 SPI: CE1 | |||||
12 10 10 19 SPI: MOSI | |||||
13 9 9 21 SPI: MISO | |||||
14 11 11 23 SPI: SCLK | |||||
15 14 14 8 TxD | |||||
16 15 16 10 RxD | |||||
17 - 28 | 17 - 28 | ||||
18 - 29 | 18 - 29 | ||||
19 - 30 | 19 - 30 | ||||
@@ -272,7 +307,7 @@ pin numbers. | |||||
.LP | .LP | ||||
WiringPi's home page | WiringPi's home page | ||||
.IP | .IP | ||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
http://wiringpi.com/ | |||||
.SH AUTHOR | .SH AUTHOR | ||||
@@ -284,7 +319,7 @@ Please report bugs to <projects@drogon.net> | |||||
.SH COPYRIGHT | .SH COPYRIGHT | ||||
Copyright (c) 2012 Gordon Henderson | |||||
Copyright (c) 2012-2013 Gordon Henderson | |||||
This is free software; see the source for copying conditions. There is NO | This is free software; see the source for copying conditions. There is NO | ||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
@@ -2,7 +2,7 @@ | |||||
* gpio.c: | * gpio.c: | ||||
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry | * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry | ||||
* Pi's GPIO. | * Pi's GPIO. | ||||
* Copyright (c) 2012 Gordon Henderson | |||||
* Copyright (c) 2012-2013 Gordon Henderson | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -26,14 +26,20 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <ctype.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <sys/types.h> | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <sys/types.h> | |||||
#include <sys/stat.h> | |||||
#include <wiringPi.h> | #include <wiringPi.h> | ||||
#include <gertboard.h> | #include <gertboard.h> | ||||
#include <piFace.h> | |||||
#include "extensions.h" | |||||
extern int wiringPiDebug ; | extern int wiringPiDebug ; | ||||
@@ -42,22 +48,26 @@ extern int wiringPiDebug ; | |||||
# define FALSE (1==2) | # define FALSE (1==2) | ||||
#endif | #endif | ||||
#define VERSION "1.12" | |||||
#define VERSION "2.02" | |||||
#define I2CDETECT "/usr/sbin/i2cdetect" | |||||
static int wpMode ; | static int wpMode ; | ||||
char *usage = "Usage: gpio -v\n" | char *usage = "Usage: gpio -v\n" | ||||
" gpio -h\n" | " gpio -h\n" | ||||
" gpio [-g] <read/write/wb/pwm/clock/mode> ...\n" | |||||
" gpio [-g|-1] [-x extension:params] ...\n" | |||||
" gpio [-p] <read/write/wb> ...\n" | " gpio [-p] <read/write/wb> ...\n" | ||||
" gpio readall\n" | |||||
" gpio unexportall/exports ...\n" | |||||
" gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n" | |||||
" gpio readall/reset\n" | |||||
" gpio unexportall/exports\n" | |||||
" gpio export/edge/unexport ...\n" | " gpio export/edge/unexport ...\n" | ||||
" gpio wfi <pin> <mode>\n" | |||||
" gpio drive <group> <value>\n" | " gpio drive <group> <value>\n" | ||||
" gpio pwm-bal/pwm-ms \n" | " gpio pwm-bal/pwm-ms \n" | ||||
" gpio pwmr <range> \n" | " gpio pwmr <range> \n" | ||||
" gpio pwmc <divider> \n" | " gpio pwmc <divider> \n" | ||||
" gpio load spi/i2c\n" | " gpio load spi/i2c\n" | ||||
" gpio i2cd/i2cdetect\n" | |||||
" gpio gbr <channel>\n" | " gpio gbr <channel>\n" | ||||
" gpio gbw <channel> <value>" ; // No trailing newline needed here. | " gpio gbw <channel> <value>" ; // No trailing newline needed here. | ||||
@@ -196,6 +206,37 @@ static void doLoad (int argc, char *argv []) | |||||
/* | /* | ||||
* doI2Cdetect: | |||||
* Run the i2cdetect command with the right runes for this Pi revision | |||||
********************************************************************************* | |||||
*/ | |||||
static void doI2Cdetect (int argc, char *argv []) | |||||
{ | |||||
int port = piBoardRev () == 1 ? 0 : 1 ; | |||||
char command [128] ; | |||||
struct stat statBuf ; | |||||
if (stat (I2CDETECT, &statBuf) < 0) | |||||
{ | |||||
fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ; | |||||
return ; | |||||
} | |||||
if (!moduleLoaded ("i2c_dev")) | |||||
{ | |||||
fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ; | |||||
return ; | |||||
} | |||||
sprintf (command, "%s -y %d", I2CDETECT, port) ; | |||||
if (system (command) < 0) | |||||
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ; | |||||
} | |||||
/* | |||||
* doReadall: | * doReadall: | ||||
* Read all the GPIO pins | * Read all the GPIO pins | ||||
********************************************************************************* | ********************************************************************************* | ||||
@@ -215,27 +256,39 @@ static char *alts [] = | |||||
"IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" | "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" | ||||
} ; | } ; | ||||
static int wpiToPhys [64] = | |||||
{ | |||||
11, 12, 13, 15, 16, 18, 22, 7, // 0...7 | |||||
3, 5, // 8...9 | |||||
24, 26, 19, 21, 23, // 10..14 | |||||
8, 10, // 15..16 | |||||
3, 4, 5, 6, // 17..20 | |||||
0,0,0,0,0,0,0,0,0,0,0, // 20..31 | |||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32..47 | |||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63 | |||||
} ; | |||||
static void doReadall (void) | static void doReadall (void) | ||||
{ | { | ||||
int pin ; | int pin ; | ||||
printf ("+----------+------+--------+------+-------+\n") ; | |||||
printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ; | |||||
printf ("+----------+------+--------+------+-------+\n") ; | |||||
printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ; | |||||
printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ; | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
for (pin = 0 ; pin < 64 ; ++pin) | |||||
for (pin = 0 ; pin < 64 ; ++pin) // Crude, but effective | |||||
{ | { | ||||
if (wpiPinToGpio (pin) == -1) | if (wpiPinToGpio (pin) == -1) | ||||
continue ; | continue ; | ||||
printf ("| %6d | %3d | %s | %s | %s |\n", | |||||
pin, wpiPinToGpio (pin), | |||||
printf ("| %6d | %3d | %3d | %s | %s | %s |\n", | |||||
pin, wpiPinToGpio (pin), wpiToPhys [pin], | |||||
pinNames [pin], | pinNames [pin], | ||||
alts [getAlt (pin)], | alts [getAlt (pin)], | ||||
digitalRead (pin) == HIGH ? "High" : "Low ") ; | digitalRead (pin) == HIGH ? "High" : "Low ") ; | ||||
} | } | ||||
printf ("+----------+------+--------+------+-------+\n") ; | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
} | } | ||||
@@ -252,9 +305,7 @@ static void doExports (int argc, char *argv []) | |||||
char fName [128] ; | char fName [128] ; | ||||
char buf [16] ; | char buf [16] ; | ||||
// Rather crude, but who knows what others are up to... | |||||
for (first = 0, i = 0 ; i < 64 ; ++i) | |||||
for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective | |||||
{ | { | ||||
// Try to read the direction | // Try to read the direction | ||||
@@ -387,6 +438,52 @@ void doExport (int argc, char *argv []) | |||||
/* | /* | ||||
* doWfi: | |||||
* gpio wfi pin mode | |||||
* Wait for Interrupt on a given pin. | |||||
* Slight cheat here - it's easier to actually use ISR now (which calls | |||||
* gpio to set the pin modes!) then we simply sleep, and expect the thread | |||||
* to exit the program. Crude but effective. | |||||
********************************************************************************* | |||||
*/ | |||||
static void wfi (void) | |||||
{ exit (0) ; } | |||||
void doWfi (int argc, char *argv []) | |||||
{ | |||||
int pin, mode ; | |||||
if (argc != 4) | |||||
{ | |||||
fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
pin = atoi (argv [2]) ; | |||||
/**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; | |||||
else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; | |||||
else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; | |||||
else | |||||
{ | |||||
fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; | |||||
exit (1) ; | |||||
} | |||||
if (wiringPiISR (pin, mode, &wfi) < 0) | |||||
{ | |||||
fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; | |||||
exit (1) ; | |||||
} | |||||
for (;;) | |||||
delay (9999) ; | |||||
} | |||||
/* | |||||
* doEdge: | * doEdge: | ||||
* gpio edge pin mode | * gpio edge pin mode | ||||
* Easy access to changing the edge trigger on a GPIO pin | * Easy access to changing the edge trigger on a GPIO pin | ||||
@@ -499,7 +596,7 @@ void doUnexport (int argc, char *argv []) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void doUnexportall (int argc, char *argv []) | |||||
void doUnexportall (char *progName) | |||||
{ | { | ||||
FILE *fd ; | FILE *fd ; | ||||
int pin ; | int pin ; | ||||
@@ -508,7 +605,7 @@ void doUnexportall (int argc, char *argv []) | |||||
{ | { | ||||
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) | if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) | ||||
{ | { | ||||
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; | |||||
fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
fprintf (fd, "%d\n", pin) ; | fprintf (fd, "%d\n", pin) ; | ||||
@@ -518,6 +615,30 @@ void doUnexportall (int argc, char *argv []) | |||||
/* | /* | ||||
* doReset: | |||||
* Reset the GPIO pins - as much as we can do | |||||
********************************************************************************* | |||||
*/ | |||||
static void doReset (char *progName) | |||||
{ | |||||
int pin ; | |||||
doUnexportall (progName) ; | |||||
for (pin = 0 ; pin < 64 ; ++pin) | |||||
{ | |||||
if (wpiPinToGpio (pin) == -1) | |||||
continue ; | |||||
digitalWrite (pin, LOW) ; | |||||
pinMode (pin, INPUT) ; | |||||
pullUpDnControl (pin, PUD_OFF) ; | |||||
} | |||||
} | |||||
/* | |||||
* doMode: | * doMode: | ||||
* gpio mode pin mode ... | * gpio mode pin mode ... | ||||
********************************************************************************* | ********************************************************************************* | ||||
@@ -536,9 +657,6 @@ void doMode (int argc, char *argv []) | |||||
pin = atoi (argv [2]) ; | pin = atoi (argv [2]) ; | ||||
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) | |||||
return ; | |||||
mode = argv [3] ; | mode = argv [3] ; | ||||
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; | /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; | ||||
@@ -604,7 +722,7 @@ static void doGbw (int argc, char *argv []) | |||||
if (argc != 4) | if (argc != 4) | ||||
{ | { | ||||
fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ; | |||||
fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
@@ -613,23 +731,23 @@ static void doGbw (int argc, char *argv []) | |||||
if ((channel < 0) || (channel > 1)) | if ((channel < 0) || (channel > 1)) | ||||
{ | { | ||||
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ; | |||||
fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
if ((value < 0) || (value > 1023)) | if ((value < 0) || (value > 1023)) | ||||
{ | { | ||||
fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ; | |||||
fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
if (gertboardSPISetup () == -1) | |||||
if (gertboardAnalogSetup (64) < 0) | |||||
{ | { | ||||
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; | fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; | ||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
gertboardAnalogWrite (channel, value) ; | |||||
analogWrite (64 + channel, value) ; | |||||
} | } | ||||
@@ -654,21 +772,20 @@ static void doGbr (int argc, char *argv []) | |||||
if ((channel < 0) || (channel > 1)) | if ((channel < 0) || (channel > 1)) | ||||
{ | { | ||||
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ; | |||||
fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
if (gertboardSPISetup () == -1) | |||||
if (gertboardAnalogSetup (64) < 0) | |||||
{ | { | ||||
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; | fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; | ||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
printf ("%d\n",gertboardAnalogRead (channel)) ; | |||||
printf ("%d\n", analogRead (64 + channel)) ; | |||||
} | } | ||||
/* | /* | ||||
* doWrite: | * doWrite: | ||||
* gpio write pin value | * gpio write pin value | ||||
@@ -687,9 +804,6 @@ static void doWrite (int argc, char *argv []) | |||||
pin = atoi (argv [2]) ; | pin = atoi (argv [2]) ; | ||||
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) | |||||
return ; | |||||
/**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0)) | /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0)) | ||||
val = 1 ; | val = 1 ; | ||||
else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0)) | else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0)) | ||||
@@ -703,6 +817,31 @@ static void doWrite (int argc, char *argv []) | |||||
digitalWrite (pin, HIGH) ; | digitalWrite (pin, HIGH) ; | ||||
} | } | ||||
/* | |||||
* doAwriterite: | |||||
* gpio awrite pin value | |||||
********************************************************************************* | |||||
*/ | |||||
static void doAwrite (int argc, char *argv []) | |||||
{ | |||||
int pin, val ; | |||||
if (argc != 4) | |||||
{ | |||||
fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
pin = atoi (argv [2]) ; | |||||
val = atoi (argv [3]) ; | |||||
analogWrite (pin, val) ; | |||||
} | |||||
/* | /* | ||||
* doWriteByte: | * doWriteByte: | ||||
* gpio write value | * gpio write value | ||||
@@ -742,20 +881,58 @@ void doRead (int argc, char *argv []) | |||||
} | } | ||||
pin = atoi (argv [2]) ; | pin = atoi (argv [2]) ; | ||||
val = digitalRead (pin) ; | |||||
printf ("%s\n", val == 0 ? "0" : "1") ; | |||||
} | |||||
/* | |||||
* doAread: | |||||
* Read an analog pin and return the value | |||||
********************************************************************************* | |||||
*/ | |||||
void doAread (int argc, char *argv []) | |||||
{ | |||||
int pin, val ; | |||||
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) | |||||
if (argc != 3) | |||||
{ | { | ||||
printf ("0\n") ; | |||||
return ; | |||||
fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | } | ||||
val = digitalRead (pin) ; | |||||
pin = atoi (argv [2]) ; | |||||
val = analogRead (pin) ; | |||||
printf ("%s\n", val == 0 ? "0" : "1") ; | printf ("%s\n", val == 0 ? "0" : "1") ; | ||||
} | } | ||||
/* | /* | ||||
* doToggle: | |||||
* Toggle an IO pin | |||||
********************************************************************************* | |||||
*/ | |||||
void doToggle (int argc, char *argv []) | |||||
{ | |||||
int pin ; | |||||
if (argc != 3) | |||||
{ | |||||
fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
pin = atoi (argv [2]) ; | |||||
digitalWrite (pin, !digitalRead (pin)) ; | |||||
} | |||||
/* | |||||
* doClock: | * doClock: | ||||
* Output a clock on a pin | * Output a clock on a pin | ||||
********************************************************************************* | ********************************************************************************* | ||||
@@ -773,9 +950,6 @@ void doClock (int argc, char *argv []) | |||||
pin = atoi (argv [2]) ; | pin = atoi (argv [2]) ; | ||||
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) | |||||
return ; | |||||
freq = atoi (argv [3]) ; | freq = atoi (argv [3]) ; | ||||
gpioClockSet (pin, freq) ; | gpioClockSet (pin, freq) ; | ||||
@@ -800,9 +974,6 @@ void doPwm (int argc, char *argv []) | |||||
pin = atoi (argv [2]) ; | pin = atoi (argv [2]) ; | ||||
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) | |||||
return ; | |||||
val = atoi (argv [3]) ; | val = atoi (argv [3]) ; | ||||
pwmWrite (pin, val) ; | pwmWrite (pin, val) ; | ||||
@@ -885,16 +1056,34 @@ int main (int argc, char *argv []) | |||||
return 1 ; | return 1 ; | ||||
} | } | ||||
// Help | |||||
if (strcasecmp (argv [1], "-h") == 0) | if (strcasecmp (argv [1], "-h") == 0) | ||||
{ | { | ||||
printf ("%s: %s\n", argv [0], usage) ; | printf ("%s: %s\n", argv [0], usage) ; | ||||
return 0 ; | return 0 ; | ||||
} | } | ||||
if (strcasecmp (argv [1], "-v") == 0) | |||||
// Sort of a special: | |||||
if (strcmp (argv [1], "-R") == 0) | |||||
{ | |||||
printf ("%d\n", piBoardRev ()) ; | |||||
return 0 ; | |||||
} | |||||
// Version & Warranty | |||||
if (strcmp (argv [1], "-V") == 0) | |||||
{ | |||||
printf ("%d\n", piBoardRev ()) ; | |||||
return 0 ; | |||||
} | |||||
if (strcmp (argv [1], "-v") == 0) | |||||
{ | { | ||||
printf ("gpio version: %s\n", VERSION) ; | printf ("gpio version: %s\n", VERSION) ; | ||||
printf ("Copyright (c) 2012 Gordon Henderson\n") ; | |||||
printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ; | |||||
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; | printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; | ||||
printf ("For details type: %s -warranty\n", argv [0]) ; | printf ("For details type: %s -warranty\n", argv [0]) ; | ||||
printf ("\n") ; | printf ("\n") ; | ||||
@@ -905,7 +1094,7 @@ int main (int argc, char *argv []) | |||||
if (strcasecmp (argv [1], "-warranty") == 0) | if (strcasecmp (argv [1], "-warranty") == 0) | ||||
{ | { | ||||
printf ("gpio version: %s\n", VERSION) ; | printf ("gpio version: %s\n", VERSION) ; | ||||
printf ("Copyright (c) 2012 Gordon Henderson\n") ; | |||||
printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ; | |||||
printf ("\n") ; | printf ("\n") ; | ||||
printf (" This program is free software; you can redistribute it and/or modify\n") ; | printf (" This program is free software; you can redistribute it and/or modify\n") ; | ||||
printf (" it under the terms of the GNU Leser General Public License as published\n") ; | printf (" it under the terms of the GNU Leser General Public License as published\n") ; | ||||
@@ -934,8 +1123,8 @@ int main (int argc, char *argv []) | |||||
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; } | /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; } | ||||
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; } | else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; } | ||||
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; } | else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; } | ||||
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } | |||||
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } | else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } | ||||
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; } | |||||
// Check for load command: | // Check for load command: | ||||
@@ -948,13 +1137,9 @@ int main (int argc, char *argv []) | |||||
// Check for -g argument | // Check for -g argument | ||||
if (strcasecmp (argv [1], "-g") == 0) | |||||
/**/ if (strcasecmp (argv [1], "-g") == 0) | |||||
{ | { | ||||
if (wiringPiSetupGpio () == -1) | |||||
{ | |||||
fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
wiringPiSetupGpio () ; | |||||
for (i = 2 ; i < argc ; ++i) | for (i = 2 ; i < argc ; ++i) | ||||
argv [i - 1] = argv [i] ; | argv [i - 1] = argv [i] ; | ||||
@@ -962,15 +1147,23 @@ int main (int argc, char *argv []) | |||||
wpMode = WPI_MODE_GPIO ; | wpMode = WPI_MODE_GPIO ; | ||||
} | } | ||||
// Check for -1 argument | |||||
else if (strcasecmp (argv [1], "-1") == 0) | |||||
{ | |||||
wiringPiSetupPhys () ; | |||||
for (i = 2 ; i < argc ; ++i) | |||||
argv [i - 1] = argv [i] ; | |||||
--argc ; | |||||
wpMode = WPI_MODE_PHYS ; | |||||
} | |||||
// Check for -p argument for PiFace | // Check for -p argument for PiFace | ||||
else if (strcasecmp (argv [1], "-p") == 0) | else if (strcasecmp (argv [1], "-p") == 0) | ||||
{ | { | ||||
if (wiringPiSetupPiFaceForGpioProg () == -1) | |||||
{ | |||||
fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
piFaceSetup (200) ; | |||||
for (i = 2 ; i < argc ; ++i) | for (i = 2 ; i < argc ; ++i) | ||||
argv [i - 1] = argv [i] ; | argv [i - 1] = argv [i] ; | ||||
@@ -982,38 +1175,65 @@ int main (int argc, char *argv []) | |||||
else | else | ||||
{ | { | ||||
if (wiringPiSetup () == -1) | |||||
{ | |||||
fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ; | |||||
exit (1) ; | |||||
} | |||||
wiringPiSetup () ; | |||||
wpMode = WPI_MODE_PINS ; | wpMode = WPI_MODE_PINS ; | ||||
} | } | ||||
// Check for PWM or Pad Drive operations | |||||
// Check for -x argument to load in a new extension | |||||
if (wpMode != WPI_MODE_PIFACE) | |||||
if (strcasecmp (argv [1], "-x") == 0) | |||||
{ | { | ||||
if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; } | |||||
if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; } | |||||
if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; } | |||||
if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; } | |||||
if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } | |||||
if (argc < 3) | |||||
{ | |||||
fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | |||||
if (!doExtension (argv [0], argv [2])) // Prints its own error messages | |||||
exit (EXIT_FAILURE) ; | |||||
for (i = 3 ; i < argc ; ++i) | |||||
argv [i - 2] = argv [i] ; | |||||
argc -= 2 ; | |||||
} | } | ||||
// Check for wiring commands | |||||
if (argc <= 1) | |||||
{ | |||||
fprintf (stderr, "%s: no command given\n", argv [0]) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | |||||
/**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; | |||||
else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; | |||||
// Core wiringPi functions | |||||
/**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ; | |||||
// GPIO Nicies | |||||
else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ; | |||||
// Pi Specifics | |||||
else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ; | |||||
else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ; | |||||
else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; | |||||
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ; | |||||
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; | |||||
else | else | ||||
{ | { | ||||
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | ||||
exit (1) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | } | ||||
return 0 ; | return 0 ; | ||||
} | } |
@@ -0,0 +1,193 @@ | |||||
#!/bin/bash | |||||
# | |||||
# pintest | |||||
# Test the Pi's GPIO port | |||||
# Copyright (c) 2013 Gordon Henderson | |||||
################################################################################# | |||||
# This file is part of wiringPi: | |||||
# Wiring Compatable library for the Raspberry Pi | |||||
# | |||||
# wiringPi is free software: you can redistribute it and/or modify | |||||
# it under the terms of the GNU Lesser General Public License as published by | |||||
# the Free Software Foundation, either version 3 of the License, or | |||||
# (at your option) any later version. | |||||
# | |||||
# wiringPi is distributed in the hope that it will be useful, | |||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
# GNU Lesser General Public License for more details. | |||||
# | |||||
# You should have received a copy of the GNU Lesser General Public License | |||||
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||||
################################################################################# | |||||
# logErr pin, expected got | |||||
################################################################################ | |||||
logErr () | |||||
{ | |||||
if [ $errs = 0 ]; then | |||||
echo "" | |||||
fi | |||||
echo " --> Pin $1 failure. Expected $2, got $3" | |||||
let errs+=1 | |||||
} | |||||
# printErrorCount | |||||
################################################################################ | |||||
printErrCount() | |||||
{ | |||||
if [ $errs = 0 ]; then | |||||
echo "No faults detected." | |||||
elif [ $errs = 1 ]; then | |||||
echo "One fault detected." | |||||
else | |||||
echo "$errs faults detected" | |||||
fi | |||||
} | |||||
# testPins start end | |||||
################################################################################ | |||||
testPins() | |||||
{ | |||||
start=$1 | |||||
end=$2 | |||||
errs=0 | |||||
printf "%30s %2d:%2d: " "$3" $1 $2 | |||||
# Set range to inputs | |||||
for i in `seq $start $end`; do | |||||
gpio mode $i in | |||||
done | |||||
# Enable internal pull-ups and expect to read high | |||||
for i in `seq $start $end`; do | |||||
gpio mode $i up | |||||
if [ `gpio read $i` = 0 ]; then | |||||
logErr $i 1 0 | |||||
fi | |||||
done | |||||
# Enable internal pull-downs and expect to read low | |||||
for i in `seq $start $end`; do | |||||
gpio mode $i down | |||||
if [ `gpio read $i` = 1 ]; then | |||||
echo "Pin $i failure - expected 0, got 1" | |||||
let errs+=1 | |||||
fi | |||||
done | |||||
# Remove the internal pull up/downs | |||||
for i in `seq $start $end`; do | |||||
gpio mode $i tri | |||||
done | |||||
if [ $errs = 0 ]; then | |||||
echo " OK" | |||||
else | |||||
printErrCount | |||||
fi | |||||
let totErrs+=errs | |||||
} | |||||
intro() | |||||
{ | |||||
revision=`gpio -V` | |||||
cat <<EOF | |||||
PinTest | |||||
======= | |||||
This is a simple utility to test the GPIO pins on your revision $revision | |||||
Raspberry Pi. | |||||
NOTE: All GPIO peripherals must be removed to perform this test. This | |||||
includes serial, I2C and SPI connections. You may get incorrect results | |||||
if something is connected and it interferes with the test. | |||||
This test can only test the input side of things. It uses the internal | |||||
pull-up and pull-down resistors to simulate inputs. It does not test | |||||
the output drivers. | |||||
You will need to reboot your Pi after this test if you wish to use the | |||||
serial port as it will be left in GPIO mode rather than serial mode. | |||||
Please make sure everything is removed and press the ENTER key to continue, | |||||
EOF | |||||
echo -n "or Control-C to abort... " | |||||
read a | |||||
} | |||||
# Start here | |||||
################################################################################ | |||||
intro | |||||
gpio unexportall | |||||
gpio reset | |||||
errs=0 | |||||
totErrs=0 | |||||
echo "" | |||||
# Main pins | |||||
testPins 0 7 "The main 8 GPIO pins" | |||||
# P5 pins, if a rev 2: | |||||
if [ $revision = 2 ]; then | |||||
testPins 17 20 "The 4 pins on the P5 connector" | |||||
fi | |||||
# SPI | |||||
testPins 10 14 "The 5 SPI pins" | |||||
# Serial | |||||
testPins 15 16 "The serial pins" | |||||
# I2C - Needs somewhat different testing | |||||
# due to the on-board pull-up's | |||||
echo -n " The I2C pins 8: 9: " | |||||
errs=0 | |||||
gpio mode 8 in | |||||
gpio mode 9 in | |||||
if [ `gpio read 8` = 0 ]; then | |||||
echo "Pin 8 failure - expected 1, got 0" | |||||
let errs+=1 | |||||
fi | |||||
if [ `gpio read 9` = 0 ]; then | |||||
echo "Pin 9 failure - expected 1, got 0" | |||||
let errs+=1 | |||||
fi | |||||
if [ $errs = 0 ]; then | |||||
echo " OK" | |||||
else | |||||
printErrCount | |||||
fi | |||||
echo "" | |||||
if [ $totErrs != 0 ]; then | |||||
echo "" | |||||
echo "Faults detected! Output of 'readall':" | |||||
gpio readall | |||||
fi |
@@ -0,0 +1,18 @@ | |||||
SRC = pins.tex | |||||
all: ${SRC} | |||||
@echo Generating DVI | |||||
@latex pins.tex | |||||
pins.dvi: pins.tex | |||||
@latex pins.tex | |||||
pdf: pins.dvi | |||||
@dvipdf pins.dvi | |||||
.PHONEY: clean | |||||
clean: | |||||
@rm -f *.dvi *.aux *.log *.ps *.toc *.bak *~ |
@@ -0,0 +1,116 @@ | |||||
\documentclass[12pt,a4paper]{article} | |||||
\parskip 1ex | |||||
\parindent 0em | |||||
\thispagestyle{empty} | |||||
\pagestyle{plain} | |||||
\pagenumbering{arabic} | |||||
\setlength{\topmargin}{0pt} | |||||
\setlength{\headheight}{0pt} | |||||
\setlength{\headsep}{0pt} | |||||
\setlength{\topskip}{0pt} | |||||
\setlength{\textheight}{240mm} | |||||
\setlength{\footskip}{5ex} | |||||
\setlength{\oddsidemargin}{0pt} | |||||
\setlength{\evensidemargin}{0pt} | |||||
\setlength{\textwidth}{160mm} | |||||
\usepackage[dvips]{graphics,color} | |||||
\usepackage{helvet} | |||||
\renewcommand{\familydefault}{\sfdefault} | |||||
\begin{document} | |||||
\begin{sffamily} | |||||
\definecolor{rtb-black}{rgb} {0.0, 0.0, 0.0} | |||||
\definecolor{rtb-navy}{rgb} {0.0, 0.0, 0.5} | |||||
\definecolor{rtb-green}{rgb} {0.0, 0.5, 0.0} | |||||
\definecolor{rtb-teal}{rgb} {0.0, 0.5, 0.5} | |||||
\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0} | |||||
\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5} | |||||
\definecolor{rtb-olive}{rgb} {0.5, 0.5, 0.0} | |||||
\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7} | |||||
\definecolor{rtb-grey}{rgb} {0.5, 0.5, 0.5} | |||||
\definecolor{rtb-blue}{rgb} {0.0, 0.0, 1.0} | |||||
\definecolor{rtb-lime}{rgb} {0.0, 1.0, 0.0} | |||||
\definecolor{rtb-aqua}{rgb} {0.0, 1.0, 1.0} | |||||
\definecolor{rtb-red}{rgb} {1.0, 0.0, 0.0} | |||||
\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0} | |||||
\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0} | |||||
\definecolor{rtb-white}{rgb} {1.0, 1.0, 1.0} | |||||
\begin{center} | |||||
\bfseries{WiringPi: GPIO Pin Numbering Tables}\\ | |||||
\tt{http://wiringpi.com/} | |||||
\end{center} | |||||
\begin{center} | |||||
\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} | |||||
\hline | |||||
\multicolumn{8}{|c|}{\bfseries{P1: The Main GPIO connector}}\\ | |||||
\hline | |||||
\hline | |||||
WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ | |||||
\hline | |||||
\hline | |||||
& & \textcolor{rtb-red}{3.3v} & \raggedleft{1} & 2 & \textcolor{rtb-maroon}{5v} & & \\ | |||||
\hline | |||||
8 & Rv1:0 - Rv2:2 & \textcolor{rtb-aqua}{SDA} & \raggedleft{3} & 4 & \textcolor{rtb-maroon}{5v} & & \\ | |||||
\hline | |||||
9 & Rv1:1 - Rv2:3 & \textcolor{rtb-aqua}{SCL} & \raggedleft{5} & 6 & \textcolor{rtb-black}{0v} & & \\ | |||||
\hline | |||||
7 & 4 & \textcolor{rtb-green}{GPIO7} & \raggedleft{7} & 8 & \textcolor{rtb-yellow}{TxD} & 14 & 15\\ | |||||
\hline | |||||
& & \textcolor{rtb-black}{0v} & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD} & 15 & 16\\ | |||||
\hline | |||||
0 & 17 & \textcolor{rtb-green}{GPIO0} & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1} & 18 & 1\\ | |||||
\hline | |||||
2 & Rv1:21 - Rv2:27 & \textcolor{rtb-green}{GPIO2} & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v} & & \\ | |||||
\hline | |||||
3 & 22 & \textcolor{rtb-green}{GPIO3} & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4} & 23 & 4\\ | |||||
\hline | |||||
& & \textcolor{rtb-red}{3.3v} & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5} & 24 & 5\\ | |||||
\hline | |||||
12 & 10 & \textcolor{rtb-teal}{MOSI} & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v} & & \\ | |||||
\hline | |||||
13 & 9 & \textcolor{rtb-teal}{MISO} & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6} & 25 & 6\\ | |||||
\hline | |||||
14 & 11 & \textcolor{rtb-teal}{SCLK} & \raggedleft{23} & 24 & \textcolor{rtb-teal}{CE0} & 8 & 10\\ | |||||
\hline | |||||
& & \textcolor{rtb-black}{0v} & \raggedleft{25} & 26 & \textcolor{rtb-teal}{CE1} & 7 & 11\\ | |||||
\hline | |||||
\hline | |||||
WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ | |||||
\hline | |||||
\end{tabular} | |||||
\end{center} | |||||
Note the differences between Revision 1 and Revision 2 Raspberry | |||||
Pi's. The Revision 2 is readily identifiable by the presence of the 2 | |||||
mounting holes. | |||||
The revision 2 Raspberry Pi has an additional GPIO connector, P5, which is next to the main P1 GPIO | |||||
connector: | |||||
\begin{center} | |||||
\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} | |||||
\hline | |||||
\multicolumn{8}{|c|}{\bfseries{P5: Secondary GPIO connector (Rev. 2 Pi only)}}\\ | |||||
\hline | |||||
\hline | |||||
WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ | |||||
\hline | |||||
\hline | |||||
& & \textcolor{rtb-maroon}{5v} & \raggedleft{1} & 2 & \textcolor{rtb-red}{3.3v} & & \\ | |||||
\hline | |||||
17 & 28 & \textcolor{rtb-green}{GPIO8} & \raggedleft{3} & 4 & \textcolor{rtb-green}{GPIO9} & 29 & 18 \\ | |||||
\hline | |||||
19 & 30 & \textcolor{rtb-green}{GPIO10} & \raggedleft{5} & 6 & \textcolor{rtb-green}{GPIO11} & 31 & 20 \\ | |||||
\hline | |||||
& & \textcolor{rtb-black}{0v} & \raggedleft{7} & 8 & \textcolor{rtb-black}{0v} & & \\ | |||||
\hline | |||||
\hline | |||||
WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ | |||||
\hline | |||||
\end{tabular} | |||||
\end{center} | |||||
\end{sffamily} | |||||
\end{document} |
@@ -21,7 +21,7 @@ | |||||
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | # along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | ||||
################################################################################# | ################################################################################# | ||||
DYN_VERS_MAJ=1 | |||||
DYN_VERS_MAJ=2 | |||||
DYN_VERS_MIN=0 | DYN_VERS_MIN=0 | ||||
VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) | VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) | ||||
@@ -35,26 +35,25 @@ DYNAMIC=libwiringPi.so.$(VERSION) | |||||
DEBUG = -O2 | DEBUG = -O2 | ||||
CC = gcc | CC = gcc | ||||
INCLUDE = -I. | INCLUDE = -I. | ||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC | |||||
CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC | |||||
LIBS = | LIBS = | ||||
# Should not alter anything below this line | # 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 = $(SRC:.c=.o) | ||||
OBJ_I2C = $(SRC_I2C:.c=.o) | |||||
all: $(DYNAMIC) | all: $(DYNAMIC) | ||||
static: $(STATIC) | static: $(STATIC) | ||||
@@ -67,11 +66,7 @@ $(STATIC): $(OBJ) | |||||
$(DYNAMIC): $(OBJ) | $(DYNAMIC): $(OBJ) | ||||
@echo "[Link (Dynamic)]" | @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: | .c.o: | ||||
@echo [Compile] $< | @echo [Compile] $< | ||||
@@ -79,37 +74,48 @@ i2c: $(OBJ) $(OBJ_I2C) | |||||
.PHONEY: clean | .PHONEY: clean | ||||
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 | .PHONEY: tags | ||||
tags: $(SRC) | tags: $(SRC) | ||||
@echo [ctags] | @echo [ctags] | ||||
@ctags $(SRC) | @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 0755 -d $(DESTDIR)$(PREFIX)/include | ||||
@install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include | @install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include | ||||
@install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include | @install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include | ||||
@install -m 0644 wiringShift.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 softPwm.h $(DESTDIR)$(PREFIX)/include | ||||
@install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include | |||||
@install -m 0644 softTone.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 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include | ||||
@install -m 0644 wiringPiI2C.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 | @ldconfig | ||||
.PHONEY: install-static | .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 | @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib | ||||
.PHONEY: uninstall | .PHONEY: uninstall | ||||
@@ -118,14 +124,19 @@ uninstall: | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h | @rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h | ||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h | @rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h | ||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.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/softPwm.h | ||||
@rm -f $(DESTDIR)$(PREFIX)/include/softServo.h | |||||
@rm -f $(DESTDIR)$(PREFIX)/include/softTone.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/wiringPiSPI.h | ||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.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.* | @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.* | ||||
@ldconfig | @ldconfig | ||||
@@ -137,16 +148,21 @@ depend: | |||||
# DO NOT DELETE | # DO NOT DELETE | ||||
wiringPi.o: wiringPi.h | wiringPi.o: wiringPi.h | ||||
wiringPiFace.o: wiringPi.h | |||||
wiringSerial.o: wiringSerial.h | wiringSerial.o: wiringSerial.h | ||||
wiringShift.o: wiringPi.h wiringShift.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 | piHiPri.o: wiringPi.h | ||||
piThread.o: wiringPi.h | piThread.o: wiringPi.h | ||||
wiringPiSPI.o: wiringPiSPI.h | |||||
wiringPiSPI.o: wiringPi.h wiringPiSPI.h | |||||
wiringPiI2C.o: wiringPi.h wiringPiI2C.h | |||||
softPwm.o: wiringPi.h softPwm.h | softPwm.o: wiringPi.h softPwm.h | ||||
softServo.o: wiringPi.h softServo.h | |||||
softTone.o: wiringPi.h softTone.h | softTone.o: wiringPi.h softTone.h | ||||
wiringPiI2C.o: wiringPi.h wiringPiI2C.h | |||||
mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h | |||||
mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h | |||||
mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h | |||||
mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h | |||||
sr595.o: wiringPi.h sr595.h | |||||
pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h | |||||
mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h | |||||
mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h | |||||
mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h | |||||
drc.o: wiringPi.h wiringSerial.h drc.h |
@@ -1,9 +0,0 @@ | |||||
WiringPi: An implementation of most of the Arduino Wiring | |||||
functions for the Raspberry Pi, | |||||
along with many more features and libraries to support | |||||
hardware, etc. on the Raspberry Pi | |||||
Full details at: | |||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
@@ -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 ; | |||||
} |
@@ -0,0 +1,34 @@ | |||||
/* | |||||
* 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/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 of the | |||||
* License, or (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public | |||||
* License along with wiringPi. | |||||
* If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
int drcSetup (const int pinBase, const int numPins, const char *device) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -0,0 +1,43 @@ | |||||
/* | |||||
* mcp3422.c: | |||||
* Extend wiringPi with the MCP3422 I2C ADC chip | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 of the | |||||
* License, or (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public | |||||
* License along with wiringPi. | |||||
* If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#define MCP3422_SR_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 | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern int mcp3422Setup (int pinBase, int i2cAddress, int channels, int sampleRate, int gain) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -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 ; | |||||
} |
@@ -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 |
@@ -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 ; | |||||
} |
@@ -0,0 +1,33 @@ | |||||
/* | |||||
* pfc8574.h: | |||||
* Extend wiringPi with the PFC8574 I2C GPIO expander chip | |||||
* Copyright (c) 2013 Gordon Henderson | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 of the | |||||
* License, or (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public | |||||
* License along with wiringPi. | |||||
* If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern int pfc8574Setup (const int pinBase, const int i2cAddress) ; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -36,15 +36,16 @@ | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int piHiPri (int pri) | |||||
int piHiPri (const int pri) | |||||
{ | { | ||||
struct sched_param sched ; | struct sched_param sched ; | ||||
memset (&sched, 0, sizeof(sched)) ; | memset (&sched, 0, sizeof(sched)) ; | ||||
if (pri > sched_get_priority_max (SCHED_RR)) | 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) ; | return sched_setscheduler (0, SCHED_RR, &sched) ; | ||||
} | } |
@@ -28,7 +28,7 @@ | |||||
#include "wiringPi.h" | #include "wiringPi.h" | ||||
#include "softPwm.h" | #include "softPwm.h" | ||||
#define MAX_PINS 64 | |||||
#define MAX_PINS 1024 | |||||
// The PWM Frequency is derived from the "pulse time" below. Essentially, | // The PWM Frequency is derived from the "pulse time" below. Essentially, | ||||
// the frequency is a function of the range and this pulse time. | // 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) | void softPwmWrite (int pin, int value) | ||||
{ | { | ||||
pin &= 63 ; | |||||
pin &= (MAX_PINS - 1) ; | |||||
/**/ if (value < 0) | /**/ if (value < 0) | ||||
value = 0 ; | value = 0 ; | ||||
@@ -36,7 +36,7 @@ | |||||
#define PULSE_TIME 100 | #define PULSE_TIME 100 | ||||
static int frewqs [MAX_PINS] ; | |||||
static int freqs [MAX_PINS] ; | |||||
static int newPin = -1 ; | static int newPin = -1 ; | ||||
@@ -49,7 +49,7 @@ static int newPin = -1 ; | |||||
static PI_THREAD (softToneThread) | static PI_THREAD (softToneThread) | ||||
{ | { | ||||
int pin, frewq, halfPeriod ; | |||||
int pin, freq, halfPeriod ; | |||||
pin = newPin ; | pin = newPin ; | ||||
newPin = -1 ; | newPin = -1 ; | ||||
@@ -58,12 +58,12 @@ static PI_THREAD (softToneThread) | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
frewq = frewqs [pin] ; | |||||
if (frewq == 0) | |||||
freq = freqs [pin] ; | |||||
if (freq == 0) | |||||
delay (1) ; | delay (1) ; | ||||
else | else | ||||
{ | { | ||||
halfPeriod = 500000 / frewq ; | |||||
halfPeriod = 500000 / freq ; | |||||
digitalWrite (pin, HIGH) ; | digitalWrite (pin, HIGH) ; | ||||
delayMicroseconds (halfPeriod) ; | delayMicroseconds (halfPeriod) ; | ||||
@@ -83,16 +83,16 @@ static PI_THREAD (softToneThread) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void softToneWrite (int pin, int frewq) | |||||
void softToneWrite (int pin, int freq) | |||||
{ | { | ||||
pin &= 63 ; | 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) ; | pinMode (pin, OUTPUT) ; | ||||
digitalWrite (pin, LOW) ; | digitalWrite (pin, LOW) ; | ||||
frewqs [pin] = 0 ; | |||||
freqs [pin] = 0 ; | |||||
newPin = pin ; | newPin = pin ; | ||||
res = piThreadCreate (softToneThread) ; | res = piThreadCreate (softToneThread) ; | ||||
@@ -31,7 +31,7 @@ extern "C" { | |||||
#endif | #endif | ||||
extern int softToneCreate (int pin) ; | extern int softToneCreate (int pin) ; | ||||
extern void softToneWrite (int pin, int frewq) ; | |||||
extern void softToneWrite (int pin, int freq) ; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -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 ; | |||||
} |
@@ -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 |
@@ -29,7 +29,8 @@ | |||||
#define WPI_MODE_PINS 0 | #define WPI_MODE_PINS 0 | ||||
#define WPI_MODE_GPIO 1 | #define WPI_MODE_GPIO 1 | ||||
#define WPI_MODE_GPIO_SYS 2 | #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 | #define WPI_MODE_UNINITIALISED -1 | ||||
// Pin modes | // Pin modes | ||||
@@ -64,6 +65,42 @@ | |||||
#define PI_THREAD(X) void *X (void *dummy) | #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 | // Function prototypes | ||||
// c++ wrappers thanks to a comment by Nick Lott | // c++ wrappers thanks to a comment by Nick Lott | ||||
@@ -73,46 +110,61 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #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 wiringPiSetup (void) ; | ||||
extern int wiringPiSetupSys (void) ; | extern int wiringPiSetupSys (void) ; | ||||
extern int wiringPiSetupGpio (void) ; | extern int wiringPiSetupGpio (void) ; | ||||
extern int wiringPiSetupPiFace (void) ; | |||||
extern int wiringPiSetupPhys (void) ; | |||||
extern int piBoardRev (void) ; | |||||
extern int wpiPinToGpio (int wpiPin) ; | |||||
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 | 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) ; | |||||
// On-Board Raspberry Pi hardware specific stuff | |||||
extern int piBoardRev (void) ; | |||||
extern int wpiPinToGpio (int wpiPin) ; | |||||
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 | // 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)) ; | extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; | ||||
// Threads | // 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 | // Schedulling priority | ||||
extern int piHiPri (int pri) ; | |||||
extern int piHiPri (const int pri) ; | |||||
// Extras from arduino land | // Extras from arduino land | ||||
@@ -1,362 +0,0 @@ | |||||
/* | |||||
* wiringPiFace: | |||||
* Arduino compatable (ish) Wiring library for the Raspberry Pi | |||||
* Copyright (c) 2012 Gordon Henderson | |||||
* | |||||
* This file to interface with the PiFace peripheral device which | |||||
* has an MCP23S17 GPIO device connected via the SPI bus. | |||||
* | |||||
*********************************************************************** | |||||
* This file is part of wiringPi: | |||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | |||||
* | |||||
* wiringPi is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 of the | |||||
* License, or (at your option) any later version. | |||||
* | |||||
* wiringPi is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public | |||||
* License along with wiringPi. | |||||
* If not, see <http://www.gnu.org/licenses/>. | |||||
*********************************************************************** | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdint.h> | |||||
#include <fcntl.h> | |||||
#include <sys/ioctl.h> | |||||
#include <sys/types.h> | |||||
#include <linux/spi/spidev.h> | |||||
#include "wiringPi.h" | |||||
// The SPI bus parameters | |||||
// Variables as they need to be passed as pointers later on | |||||
static char *spiDevice = "/dev/spidev0.0" ; | |||||
static uint8_t spiMode = 0 ; | |||||
static uint8_t spiBPW = 8 ; | |||||
static uint32_t spiSpeed = 5000000 ; | |||||
static uint16_t spiDelay = 0; | |||||
// Locals here to keep track of everything | |||||
static int spiFd ; | |||||
// The MCP23S17 doesn't have bit-set operations, so it's | |||||
// cheaper to keep a copy here than to read/modify/write it | |||||
uint8_t dataOutRegister = 0 ; | |||||
uint8_t pudRegister = 0 ; | |||||
// MCP23S17 Registers | |||||
#define IOCON 0x0A | |||||
#define IODIRA 0x00 | |||||
#define IPOLA 0x02 | |||||
#define GPINTENA 0x04 | |||||
#define DEFVALA 0x06 | |||||
#define INTCONA 0x08 | |||||
#define GPPUA 0x0C | |||||
#define INTFA 0x0E | |||||
#define INTCAPA 0x10 | |||||
#define GPIOA 0x12 | |||||
#define OLATA 0x14 | |||||
#define IODIRB 0x01 | |||||
#define IPOLB 0x03 | |||||
#define GPINTENB 0x05 | |||||
#define DEFVALB 0x07 | |||||
#define INTCONB 0x09 | |||||
#define GPPUB 0x0D | |||||
#define INTFB 0x0F | |||||
#define INTCAPB 0x11 | |||||
#define GPIOB 0x13 | |||||
#define OLATB 0x15 | |||||
// Bits in the IOCON register | |||||
#define IOCON_BANK_MODE 0x80 | |||||
#define IOCON_MIRROR 0x40 | |||||
#define IOCON_SEQOP 0x20 | |||||
#define IOCON_DISSLW 0x10 | |||||
#define IOCON_HAEN 0x08 | |||||
#define IOCON_ODR 0x04 | |||||
#define IOCON_INTPOL 0x02 | |||||
#define IOCON_UNUSED 0x01 | |||||
// Default initialisation mode | |||||
#define IOCON_INIT (IOCON_SEQOP) | |||||
// Command codes | |||||
#define CMD_WRITE 0x40 | |||||
#define CMD_READ 0x41 | |||||
/* | |||||
* writeByte: | |||||
* Write a byte to a register on the MCP23S17 on the SPI bus. | |||||
* This is using the synchronous access mechanism. | |||||
********************************************************************************* | |||||
*/ | |||||
static void writeByte (uint8_t reg, uint8_t data) | |||||
{ | |||||
uint8_t spiBufTx [3] ; | |||||
uint8_t spiBufRx [3] ; | |||||
struct spi_ioc_transfer spi ; | |||||
spiBufTx [0] = CMD_WRITE ; | |||||
spiBufTx [1] = reg ; | |||||
spiBufTx [2] = data ; | |||||
spi.tx_buf = (unsigned long)spiBufTx ; | |||||
spi.rx_buf = (unsigned long)spiBufRx ; | |||||
spi.len = 3 ; | |||||
spi.delay_usecs = spiDelay ; | |||||
spi.speed_hz = spiSpeed ; | |||||
spi.bits_per_word = spiBPW ; | |||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; | |||||
} | |||||
/* | |||||
* readByte: | |||||
* Read a byte from a register on the MCP23S17 on the SPI bus. | |||||
* This is the synchronous access mechanism. | |||||
* What appears to happen is that the data returned is at | |||||
* the same offset as the number of bytes written to the device. So if we | |||||
* write 2 bytes (e.g. command then register number), then the data returned | |||||
* will by at the 3rd byte... | |||||
********************************************************************************* | |||||
*/ | |||||
static uint8_t readByte (uint8_t reg) | |||||
{ | |||||
uint8_t tx [4] ; | |||||
uint8_t rx [4] ; | |||||
struct spi_ioc_transfer spi ; | |||||
tx [0] = CMD_READ ; | |||||
tx [1] = reg ; | |||||
tx [2] = 0 ; | |||||
spi.tx_buf = (unsigned long)tx ; | |||||
spi.rx_buf = (unsigned long)rx ; | |||||
spi.len = 3 ; | |||||
spi.delay_usecs = spiDelay ; | |||||
spi.speed_hz = spiSpeed ; | |||||
spi.bits_per_word = spiBPW ; | |||||
ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; | |||||
return rx [2] ; | |||||
} | |||||
/* | |||||
* digitalWritePiFace: | |||||
* Perform the digitalWrite function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void digitalWritePiFace (int pin, int value) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if (value == 0) | |||||
dataOutRegister &= (~mask) ; | |||||
else | |||||
dataOutRegister |= mask ; | |||||
writeByte (GPIOA, dataOutRegister) ; | |||||
} | |||||
void digitalWriteBytePiFace (int value) | |||||
{ | |||||
writeByte (GPIOA, value) ; | |||||
} | |||||
void digitalWritePiFaceSpecial (int pin, int value) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
uint8_t old ; | |||||
old = readByte (GPIOA) ; | |||||
if (value == 0) | |||||
old &= (~mask) ; | |||||
else | |||||
old |= mask ; | |||||
writeByte (GPIOA, old) ; | |||||
} | |||||
/* | |||||
* digitalReadPiFace: | |||||
* Perform the digitalRead function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
int digitalReadPiFace (int pin) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if ((readByte (GPIOB) & mask) != 0) | |||||
return HIGH ; | |||||
else | |||||
return LOW ; | |||||
} | |||||
/* | |||||
* pullUpDnControlPiFace: | |||||
* Perform the pullUpDnControl function on the PiFace board | |||||
********************************************************************************* | |||||
*/ | |||||
void pullUpDnControlPiFace (int pin, int pud) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
if (pud == PUD_UP) | |||||
pudRegister |= mask ; | |||||
else | |||||
pudRegister &= (~mask) ; | |||||
writeByte (GPPUB, pudRegister) ; | |||||
} | |||||
void pullUpDnControlPiFaceSpecial (int pin, int pud) | |||||
{ | |||||
uint8_t mask = 1 << pin ; | |||||
uint8_t old ; | |||||
old = readByte (GPPUB) ; | |||||
if (pud == PUD_UP) | |||||
old |= mask ; | |||||
else | |||||
old &= (~mask) ; | |||||
writeByte (GPPUB, old) ; | |||||
} | |||||
/* | |||||
* Dummy functions that are not used in this mode | |||||
********************************************************************************* | |||||
*/ | |||||
void pinModePiFace (int pin, int mode) {} | |||||
void pwmWritePiFace (int pin, int value) {} | |||||
int waitForInterruptPiFace (int pin, int mS) { return 0 ; } | |||||
/* | |||||
* wiringPiSetupPiFace | |||||
* Setup the SPI interface and initialise the MCP23S17 chip | |||||
********************************************************************************* | |||||
*/ | |||||
static int _wiringPiSetupPiFace (void) | |||||
{ | |||||
if ((spiFd = open (spiDevice, O_RDWR)) < 0) | |||||
return -1 ; | |||||
// Set SPI parameters | |||||
// Why are we doing a read after write? | |||||
// I don't know - just blindliy copying an example elsewhere... -GH- | |||||
if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0) | |||||
return -1 ; | |||||
if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0) | |||||
return -1 ; | |||||
// Setup the MCP23S17 | |||||
writeByte (IOCON, IOCON_INIT) ; | |||||
writeByte (IODIRA, 0x00) ; // Port A -> Outputs | |||||
writeByte (IODIRB, 0xFF) ; // Port B -> Inputs | |||||
return 0 ; | |||||
} | |||||
int wiringPiSetupPiFace (void) | |||||
{ | |||||
int x = _wiringPiSetupPiFace () ; | |||||
if (x != 0) | |||||
return x ; | |||||
writeByte (GPIOA, 0x00) ; // Set all outptus off | |||||
writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B | |||||
pinMode = pinModePiFace ; | |||||
pullUpDnControl = pullUpDnControlPiFace ; | |||||
digitalWrite = digitalWritePiFace ; | |||||
digitalWriteByte = digitalWriteBytePiFace ; | |||||
pwmWrite = pwmWritePiFace ; | |||||
digitalRead = digitalReadPiFace ; | |||||
waitForInterrupt = waitForInterruptPiFace ; | |||||
return 0 ; | |||||
} | |||||
/* | |||||
* wiringPiSetupPiFaceForGpioProg: | |||||
* Setup the SPI interface and initialise the MCP23S17 chip | |||||
* Special version for the gpio program | |||||
********************************************************************************* | |||||
*/ | |||||
int wiringPiSetupPiFaceForGpioProg (void) | |||||
{ | |||||
int x = _wiringPiSetupPiFace () ; | |||||
if (x != 0) | |||||
return x ; | |||||
pinMode = pinModePiFace ; | |||||
pullUpDnControl = pullUpDnControlPiFaceSpecial ; | |||||
digitalWrite = digitalWritePiFaceSpecial ; | |||||
digitalWriteByte = digitalWriteBytePiFace ; | |||||
pwmWrite = pwmWritePiFace ; | |||||
digitalRead = digitalReadPiFace ; | |||||
waitForInterrupt = waitForInterruptPiFace ; | |||||
return 0 ; | |||||
} |
@@ -22,15 +22,93 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
/* | |||||
* Notes: | |||||
* The Linux I2C code is actually the same (almost) as the SMBus code. | |||||
* SMBus is System Management Bus - and in essentially I2C with some | |||||
* additional functionality added, and stricter controls on the electrical | |||||
* specifications, etc. however I2C does work well with it and the | |||||
* protocols work over both. | |||||
* | |||||
* I'm directly including the SMBus functions here as some Linux distros | |||||
* lack the correct header files, and also some header files are GPLv2 | |||||
* rather than the LGPL that wiringPi is released under - presumably because | |||||
* originally no-one expected I2C/SMBus to be used outside the kernel - | |||||
* however enter the Raspberry Pi with people now taking directly to I2C | |||||
* devices without going via the kernel... | |||||
* | |||||
* This may ultimately reduce the flexibility of this code, but it won't be | |||||
* hard to maintain it and keep it current, should things change. | |||||
* | |||||
* Information here gained from: kernel/Documentation/i2c/dev-interface | |||||
* as well as other online resources. | |||||
********************************************************************************* | |||||
*/ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdint.h> | |||||
#include <errno.h> | |||||
#include <string.h> | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <linux/i2c-dev.h> | |||||
#include "wiringPi.h" | #include "wiringPi.h" | ||||
#include "wiringPiI2C.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: | * wiringPiI2CRead: | ||||
@@ -40,7 +118,12 @@ | |||||
int wiringPiI2CRead (int fd) | 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) | 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) | 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) | 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) | if (rev == 1) | ||||
device = "/dev/i2c-0" ; | device = "/dev/i2c-0" ; | ||||
else | else | ||||
device = "/dev/i2c-1" ; | device = "/dev/i2c-1" ; | ||||
if ((fd = open (device, O_RDWR)) < 0) | |||||
return -1 ; | |||||
if (ioctl (fd, I2C_SLAVE, devId) < 0) | |||||
return -1 ; | |||||
return fd ; | |||||
return wiringPiI2CSetupInterface (device, devId) ; | |||||
} | } |
@@ -26,15 +26,16 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #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 | #ifdef __cplusplus | ||||
} | } | ||||
@@ -25,20 +25,24 @@ | |||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <errno.h> | |||||
#include <string.h> | |||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <linux/spi/spidev.h> | #include <linux/spi/spidev.h> | ||||
#include "wiringPi.h" | |||||
#include "wiringPiSPI.h" | #include "wiringPiSPI.h" | ||||
// The SPI bus parameters | // The SPI bus parameters | ||||
// Variables as they need to be passed as pointers later on | // 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 uint32_t spiSpeeds [2] ; | ||||
static int spiFds [2] ; | static int spiFds [2] ; | ||||
@@ -95,7 +99,7 @@ int wiringPiSPISetup (int channel, int speed) | |||||
channel &= 1 ; | channel &= 1 ; | ||||
if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) | 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 ; | spiSpeeds [channel] = speed ; | ||||
spiFds [channel] = fd ; | 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 | // Why are we reading it afterwriting it? I've no idea, but for now I'm blindly | ||||
// copying example code I've seen online... | // 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_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 ; | return fd ; | ||||
} | } |
@@ -41,7 +41,7 @@ | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int serialOpen (char *device, int baud) | |||||
int serialOpen (const char *device, const int baud) | |||||
{ | { | ||||
struct termios options ; | struct termios options ; | ||||
speed_t myBaud ; | speed_t myBaud ; | ||||
@@ -60,6 +60,7 @@ int serialOpen (char *device, int baud) | |||||
case 1200: myBaud = B1200 ; break ; | case 1200: myBaud = B1200 ; break ; | ||||
case 1800: myBaud = B1800 ; break ; | case 1800: myBaud = B1800 ; break ; | ||||
case 2400: myBaud = B2400 ; break ; | case 2400: myBaud = B2400 ; break ; | ||||
case 4800: myBaud = B4800 ; break ; | |||||
case 9600: myBaud = B9600 ; break ; | case 9600: myBaud = B9600 ; break ; | ||||
case 19200: myBaud = B19200 ; break ; | case 19200: myBaud = B19200 ; break ; | ||||
case 38400: myBaud = B38400 ; 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) ; | tcflush (fd, TCIOFLUSH) ; | ||||
} | } | ||||
@@ -128,7 +129,7 @@ void serialFlush (int fd) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void serialClose (int fd) | |||||
void serialClose (const int fd) | |||||
{ | { | ||||
close (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) ; | 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)) ; | 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 ; | va_list argp ; | ||||
char buffer [1024] ; | char buffer [1024] ; | ||||
@@ -182,7 +183,7 @@ void serialPrintf (int fd, char *message, ...) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int serialDataAvail (int fd) | |||||
int serialDataAvail (const int fd) | |||||
{ | { | ||||
int result ; | int result ; | ||||
@@ -201,7 +202,7 @@ int serialDataAvail (int fd) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int serialGetchar (int fd) | |||||
int serialGetchar (const int fd) | |||||
{ | { | ||||
uint8_t x ; | uint8_t x ; | ||||
@@ -24,14 +24,14 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #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 | #ifdef __cplusplus | ||||
} | } | ||||
@@ -56,7 +56,6 @@ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) | |||||
return value; | return value; | ||||
} | } | ||||
/* | /* | ||||
* shiftOut: | * shiftOut: | ||||
* Shift data out to a clocked source | * Shift data out to a clocked source | ||||
@@ -33,8 +33,8 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #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 | #ifdef __cplusplus | ||||
} | } | ||||