Browse Source

Latest changes from master repository

pull/1/merge
Gordon Henderson 12 years ago
committed by Philip Howard
parent
commit
a651323139
13 changed files with 548 additions and 137 deletions
  1. +10
    -0
      People
  2. +6
    -2
      examples/Makefile
  3. +14
    -0
      examples/README.TXT
  4. +22
    -15
      gpio/Makefile
  5. +48
    -31
      gpio/gpio.1
  6. +103
    -16
      gpio/gpio.c
  7. +21
    -0
      gpio/test.sh
  8. +65
    -32
      wiringPi/Makefile
  9. +3
    -1
      wiringPi/README
  10. +4
    -1
      wiringPi/lcd.c
  11. +4
    -4
      wiringPi/lcd.h
  12. +244
    -35
      wiringPi/wiringPi.c
  13. +4
    -0
      wiringPi/wiringPi.h

+ 10
- 0
People View File

@@ -0,0 +1,10 @@

Just a quick note to some people who've provided help, suggestions,
bug-fixes, etc. along the way...

Nick Lott: (And others)
Hints about making it work with C++

Philipp Stefan Neininger:
Minor bug in the Makefile to do with cross compiling


+ 6
- 2
examples/Makefile View File

@@ -39,7 +39,12 @@ SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c

OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o

all: test1 test2 speed lcd wfi piface gertboard nes softPwm
BINS = test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm

all:
@cat README.TXT
@echo " $(BINS)" | fmt
@echo ""

test1: test1.o
@echo [link]
@@ -77,7 +82,6 @@ softPwm: softPwm.o
@echo [link]
$(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread


delayTest: delayTest.o
@echo [link]
$(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS)


+ 14
- 0
examples/README.TXT View File

@@ -0,0 +1,14 @@

wiringPi Examples
=================

There are now too many examples to compile them all in a sensible time,
and you probably don't want to compile or run them all anyway, so they
have been separated out.

To compile an individual example, just type

make exampleName

Where exampleName is one of:


+ 22
- 15
gpio/Makefile View File

@@ -24,7 +24,7 @@


#DEBUG = -g -O0
DEBUG = -O3
DEBUG = -O2
CC = gcc
INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
@@ -32,42 +32,49 @@ CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
LIBS = -lwiringPi

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

SRC = gpio.c

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

all: gpio

gpio: gpio.o /usr/local/lib/libwiringPi.a
@echo [LD]
gpio: gpio.o
@echo [Link]
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
.c.o:
@echo [CC] $<
@echo [Compile] $<
@$(CC) -c $(CFLAGS) $< -o $@

.PHONEY: clean
clean:
rm -f $(OBJ) gpio *~ core tags
rm -f $(OBJ) gpio *~ core tags *.bak

.PHONEY: tags
tags: $(SRC)
@echo [ctags]
@ctags $(SRC)

depend:
makedepend -Y $(SRC)

.PHONEY: install
install:
cp gpio /usr/local/bin
chown root.root /usr/local/bin/gpio
chmod 4755 /usr/local/bin/gpio
mkdir -p /usr/local/man/man1
cp gpio.1 /usr/local/man/man1
@echo "[Install]"
@cp gpio /usr/local/bin
@chown root.root /usr/local/bin/gpio
@chmod 4755 /usr/local/bin/gpio
@mkdir -p /usr/local/man/man1
@cp gpio.1 /usr/local/man/man1

.PHONEY: uninstall
uninstall:
@echo "[UnInstall]"
rm -f /usr/local/bin/gpio
rm -f /usr/local/man/man1/gpio.1

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

# DO NOT DELETE

+ 48
- 31
gpio/gpio.1 View File

@@ -1,4 +1,4 @@
.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"
.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"

.SH NAME
gpio \- Command-line access to Raspberry Pi and PiFace GPIO
@@ -17,6 +17,9 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.B ...
.PP
.B gpio
.B readall
.PP
.B gpio
.B unexportall/exports
.PP
.B gpio
@@ -48,9 +51,9 @@ channel value
.SH DESCRIPTION

.B GPIO
is a swiss army knofe of a command line tool to allow the user easy
is a swiss army knife of a command line tool to allow the user easy
access to the GPIO pins on the Raspberry Pi and the SPI A/D and D/A
convertors on the Gertboard. It's designed for simple testing and
converters on the Gertboard. It's designed for simple testing and
diagnostic purposes, but can be used in shell scripts for general if
somewhat slow control of the GPIO pins.

@@ -62,7 +65,7 @@ interface without needing to be run as root.

.TP
.B \-v
Output the current version
Output the current version including the board revision of the Raspberry Pi.

.TP
.B \-g
@@ -73,20 +76,26 @@ Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
Use the PiFace interface board and its corresponding pin numbers.

.TP
.B read
.B read <pin>
Read the digital value of the given pin and print 0 or 1 to represent the
respective logic levels.

.TP
.B write
.B write <pin> <value>
Write the given value (0 or 1) to the pin.

.TP
.B pwm
.B readall
Output a table of all GPIO pins values. The values represent the actual values read
if the pin is in input mode, or the last value written if the pin is in output
mode.

.TP
.B pwm <pin> <value>
Write a PWM value (0-1023) to the given pin.

.TP
.B mode
.B mode <pin> <mode>
Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also
use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal
pull-up, pull-down or tristate (off) controls.
@@ -122,7 +131,7 @@ the direction to input and set the edge interrupt method to \fInone\fR,
above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin
numbering.

Like the export commands abovem ownership is set to that of the
Like the export commands above, ownership is set to that of the
calling user, allowing subsequent access from user programs without
requiring root/sudo.

@@ -155,7 +164,7 @@ the associated /dev/ entries so that the current user has access to them.
.B gbr
channel

This reads the analog to digital convertor on the Gertboard on the given
This reads the analog to digital converter on the Gertboard on the given
channel. The board jumpers need to be in-place to do this operation.

.TP
@@ -163,7 +172,7 @@ channel. The board jumpers need to be in-place to do this operation.
channel value

This writes the supplied value to the output channel on the Gertboards
SPI digital to analogue convertor.
SPI digital to analogue converter.
The board jumpers need to be in-place to do this operation.


@@ -171,26 +180,30 @@ The board jumpers need to be in-place to do this operation.

.PP
.TS
r r l.
WiringPi GPIO Function
r r r l.
WiringPi GPIO-r1 GPIO-r2 Function
_
0 17
1 18 (PWM)
2 21
3 22
4 23
5 24
6 25
7 4
8 0 SDA0
9 1 SCL0
10 8 SPI CE0
11 7 SPI CE1
12 10 SPI MOSI
13 9 SPI MISO
14 11 SPI SCLK
15 14 TxD
16 15 RxD
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
17 - 28
18 - 29
19 - 30
20 - 31
.TE

.SH FILES
@@ -234,10 +247,14 @@ Gordon Henderson

.SH "REPORTING BUGS"

Report bugs to <projects@drogon.net>
Please report bugs to <projects@drogon.net>

.SH COPYRIGHT

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

.SH TRADEMARKS AND ACKNOWLEDGEMENTS

Raspberry Pi is a trademark of the Raspberry Pi Foundation.

+ 103
- 16
gpio/gpio.c View File

@@ -40,7 +40,7 @@
# define FALSE (1==2)
#endif

#define VERSION "1.2"
#define VERSION "1.4"

static int wpMode ;

@@ -48,13 +48,16 @@ char *usage = "Usage: gpio -v\n"
" gpio -h\n"
" gpio [-g] <read/write/pwm/mode> ...\n"
" gpio [-p] <read/write/mode> ...\n"
" gpio export/edge/unexport/unexportall/exports ...\n"
" gpio readall\n"
" gpio unexportall/exports ...\n"
" gpio export/edge/unexport ...\n"
" gpio drive <group> <value>\n"
" gpio pwm-bal/pwm-ms \n"
" gpio pwmr <range> \n"
" gpio pwmc <divider> \n"
" gpio load spi/i2c\n"
" gpio gbr <channel>\n"
" gpio gbw <channel> <value>\n" ;
" gpio gbw <channel> <value>" ; // No trailing newline needed here.


/*
@@ -171,6 +174,65 @@ static void doLoad (int argc, char *argv [])
}


/*
* doReadall:
* Read all the GPIO pins
*********************************************************************************
*/

static char *pinNames [] =
{
"GPIO 0",
"GPIO 1",
"GPIO 2",
"GPIO 3",
"GPIO 4",
"GPIO 5",
"GPIO 6",
"GPIO 7",
"SDA ",
"SCL ",
"CE0 ",
"CE1 ",
"MOSI ",
"MISO ",
"SCLK ",
"TxD ",
"RxD ",
"GPIO 8",
"GPIO 9",
"GPIO10",
"GPIO11",
} ;

static void doReadall (void)
{
int pin ;

printf ("+----------+------+--------+-------+\n") ;
printf ("| wiringPi | GPIO | Name | Value |\n") ;
printf ("+----------+------+--------+-------+\n") ;

for (pin = 0 ; pin < NUM_PINS ; ++pin)
printf ("| %6d | %3d | %s | %s |\n",
pin, wpiPinToGpio (pin),
pinNames [pin],
digitalRead (pin) == HIGH ? "High" : "Low ") ;

printf ("+----------+------+--------+-------+\n") ;

if (piBoardRev () == 1)
return ;

for (pin = 17 ; pin <= 20 ; ++pin)
printf ("| %6d | %3d | %s | %s |\n",
pin, wpiPinToGpio (pin),
pinNames [pin],
digitalRead (pin) == HIGH ? "High" : "Low ") ;

printf ("+----------+------+--------+-------+\n") ;
}


/*
* doExports:
@@ -687,8 +749,8 @@ void doPwm (int argc, char *argv [])


/*
* doPwmMode: doPwmRange:
* Change the PWM mode and Range values
* doPwmMode: doPwmRange: doPwmClock:
* Change the PWM mode, range and clock divider values
*********************************************************************************
*/

@@ -718,6 +780,27 @@ static void doPwmRange (int argc, char *argv [])
pwmSetRange (range) ;
}

static void doPwmClock (int argc, char *argv [])
{
unsigned int clock ;

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

clock = (unsigned int)strtoul (argv [2], NULL, 10) ;

if ((clock < 1) || (clock > 4095))
{
fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
exit (1) ;
}

pwmSetClock (clock) ;
}


/*
* main:
@@ -731,7 +814,7 @@ int main (int argc, char *argv [])

if (argc == 1)
{
fprintf (stderr, "%s: %s\n", argv [0], usage) ;
fprintf (stderr, "%s\n", usage) ;
return 1 ;
}

@@ -747,6 +830,8 @@ int main (int argc, char *argv [])
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
return 0 ;
}

@@ -785,9 +870,8 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }

// Check for drive or load commands:
// Check for load command:

if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }

// Gertboard commands
@@ -839,21 +923,24 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_PINS ;
}

// Check for PWM operations
// Check for PWM or Pad Drive operations

if (wpMode != WPI_MODE_PIFACE)
{
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], "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 ; }
}

// Check for wiring commands

/**/ 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], "mode" ) == 0) doMode (argc, argv) ;
/**/ 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], "pwm" ) == 0) doPwm (argc, argv) ;
else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
else
{
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;


+ 21
- 0
gpio/test.sh View File

@@ -1,4 +1,25 @@
#!/bin/bash
#
# test.sh:
# Simple test: Assumes LEDs on Pins 0-7 and lights them
# in-turn.
#################################################################################
# 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/>.
#################################################################################

# Simple test - assumes LEDs on Pins 0-7.



+ 65
- 32
wiringPi/Makefile View File

@@ -21,64 +21,93 @@
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################

DYN_VERS_MAJ=1
DYN_VERS_MIN=0

TARGET=libwiringPi.a
STATIC=libwiringPi.a
DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN)

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

LIBS =

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

SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c lcd.c piHiPri.c piThread.c
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
gertboard.c \
piNes.c \
lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c

OBJ = wiringPi.o wiringPiFace.o wiringSerial.o wiringShift.o lcd.o piHiPri.o piThread.o
OBJ = $(SRC:.c=.o)

all: $(TARGET)
#all: $(STATIC) $(DYNAMIC)
all: $(DYNAMIC)

$(TARGET): $(OBJ)
@echo [AR] $(OBJ)
@ar rcs $(TARGET) $(OBJ)
@ranlib $(TARGET)
@size $(TARGET)
$(STATIC): $(OBJ)
@echo [Link (Static)]
@ar rcs $(STATIC) $(OBJ)
@ranlib $(STATIC)
@size $(STATIC)

$(DYNAMIC): $(OBJ)
@echo [Link]
@$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)

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

.PHONEY: clean
clean:
rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak
rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.*

.PHONEY: tags
tags: $(SRC)
@echo [ctags]
@ctags $(SRC)

depend:
makedepend -Y $(SRC)

.PHONEY: install
install: $(TARGET)
@echo [install]
install -m 0755 -d /usr/local/lib
install -m 0755 -d /usr/local/include
install -m 0644 wiringPi.h /usr/local/include
install -m 0644 wiringSerial.h /usr/local/include
install -m 0644 wiringShift.h /usr/local/include
install -m 0644 lcd.h /usr/local/include
install -m 0644 libwiringPi.a /usr/local/lib

@echo "[Install]"
@install -m 0755 -d /usr/local/lib
@install -m 0755 -d /usr/local/include
@install -m 0644 wiringPi.h /usr/local/include
@install -m 0644 wiringSerial.h /usr/local/include
@install -m 0644 wiringShift.h /usr/local/include
@install -m 0644 gertboard.h /usr/local/include
@install -m 0644 piNes.h /usr/local/include
@install -m 0644 softPwm.h /usr/local/include
@install -m 0644 lcd.h /usr/local/include
@install -m 0644 wiringPiSPI.h /usr/local/include
# @install -m 0644 libwiringPi.a /usr/local/lib
@install -m 0755 libwiringPi.so.1.0 /usr/local/lib
@ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so
@ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so.1
@ldconfig

.PHONEY: uninstall
uninstall:
@echo [uninstall]
rm -f /usr/local/include/lcd.h
rm -f /usr/local/include/wiringShift.h
rm -f /usr/local/include/wiringPi.h
rm -f /usr/local/lib/libwiringPi.a


@echo "[UnInstall]"
@rm -f /usr/local/include/wiringPi.h
@rm -f /usr/local/include/wiringSerial.h
@rm -f /usr/local/include/wiringShift.h
@rm -f /usr/local/include/gertboard.h
@rm -f /usr/local/include/piNes.h
@rm -f /usr/local/include/softPwm.h
@rm -f /usr/local/include/lcd.h
@rm -f /usr/local/include/wiringPiSPI.h
@rm -f /usr/local/lib/libwiringPi.*
@ldconfig


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

# DO NOT DELETE

@@ -86,6 +115,10 @@ wiringPi.o: wiringPi.h
wiringPiFace.o: wiringPi.h
wiringSerial.o: wiringSerial.h
wiringShift.o: wiringPi.h wiringShift.h
gertboard.o: wiringPiSPI.h gertboard.h
piNes.o: wiringPi.h piNes.h
lcd.o: wiringPi.h lcd.h
piHiPri.o: wiringPi.h
piThread.o: wiringPi.h
softPwm.o: wiringPi.h softPwm.h
wiringPiSPI.o: wiringPiSPI.h

+ 3
- 1
wiringPi/README View File

@@ -1,6 +1,8 @@

WiringPi: An implementation of most of the Arduino Wiring
functions for the Raspberry Pi
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/


+ 4
- 1
wiringPi/lcd.c View File

@@ -75,7 +75,10 @@ struct lcdDataStruct *lcds [MAX_LCDS] ;

static void strobe (struct lcdDataStruct *lcd)
{
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (1) ;

// Note timing changes for new version of delayMicroseconds ()

digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ;
digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ;
}



+ 4
- 4
wiringPi/lcd.h View File

@@ -26,6 +26,10 @@

#define MAX_LCDS 8

#ifdef __cplusplus
extern "C" {
#endif

extern void lcdHome (int fd) ;
extern void lcdClear (int fd) ;
extern void lcdPosition (int fd, int x, int y) ;
@@ -33,10 +37,6 @@ extern void lcdPutchar (int fd, uint8_t data) ;
extern void lcdPuts (int fd, char *string) ;
extern void lcdPrintf (int fd, char *message, ...) ;

#ifdef __cplusplus
extern "C" {
#endif

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



+ 244
- 35
wiringPi/wiringPi.c View File

@@ -2,6 +2,7 @@
* wiringPi:
* Arduino compatable (ish) Wiring library for the Raspberry Pi
* Copyright (c) 2012 Gordon Henderson
* Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com>
*
* Thanks to code samples from Gert Jan van Loo and the
* BCM2835 ARM Peripherals manual, however it's missing
@@ -56,6 +57,8 @@

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <poll.h>
#include <unistd.h>
#include <errno.h>
@@ -81,6 +84,7 @@ int (*waitForInterrupt) (int pin, int mS) ;
void (*delayMicroseconds) (unsigned int howLong) ;
void (*pwmSetMode) (int mode) ;
void (*pwmSetRange) (unsigned int range) ;
void (*pwmSetClock) (int divisor) ;


#ifndef TRUE
@@ -166,9 +170,12 @@ static volatile uint32_t *pwm ;
static volatile uint32_t *clk ;
static volatile uint32_t *pads ;
static volatile uint32_t *timer ;

static volatile uint32_t *timerIrqRaw ;

// Debugging

static int wiringPiDebug = FALSE ;

// The BCM2835 has 54 GPIO pins.
// BCM2835 data sheet, Page 90 onwards.
// There are 6 control registers, each control the functions of a block
@@ -198,8 +205,11 @@ static int sysFds [64] ;

// pinToGpio:
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
// Cope for 2 different board revieions here

static int *pinToGpio ;

static int pinToGpio [64] =
static int pinToGpioR1 [64] =
{
17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
0, 1, // I2C - SDA0, SCL0
@@ -209,11 +219,28 @@ static int pinToGpio [64] =

// Padding:

-1, -1, -1,-1,-1,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
} ;

static int pinToGpioR2 [64] =
{
17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
2, 3, // I2C - SDA0, SCL0 wpi 8 - 9
8, 7, // SPI - CE1, CE0 wpi 10 - 11
10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
14, 15, // UART - Tx, Rx wpi 15 - 16
28, 29, 30, 31, // New GPIOs 8 though 11 wpi 17 - 20

// Padding:

-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
} ;


// gpioToGPFSEL:
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)

@@ -227,6 +254,7 @@ static uint8_t gpioToGPFSEL [] =
5,5,5,5,5,5,5,5,5,5,
} ;


// gpioToShift
// Define the shift up for the 3 bits per pin in each GPFSEL port

@@ -239,6 +267,7 @@ static uint8_t gpioToShift [] =
0,3,6,9,12,15,18,21,24,27,
} ;


// gpioToGPSET:
// (Word) offset to the GPIO Set registers for each GPIO pin

@@ -248,6 +277,7 @@ static uint8_t gpioToGPSET [] =
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
} ;


// gpioToGPCLR:
// (Word) offset to the GPIO Clear registers for each GPIO pin

@@ -257,6 +287,7 @@ static uint8_t gpioToGPCLR [] =
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
} ;


// gpioToGPLEV:
// (Word) offset to the GPIO Input level registers for each GPIO pin

@@ -266,6 +297,7 @@ static uint8_t gpioToGPLEV [] =
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
} ;


#ifdef notYetReady
// gpioToEDS
// (Word) offset to the Event Detect Status
@@ -295,6 +327,7 @@ static uint8_t gpioToFEN [] =
} ;
#endif


// gpioToPUDCLK
// (Word) offset to the Pull Up Down Clock regsiter

@@ -306,6 +339,7 @@ static uint8_t gpioToPUDCLK [] =
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
} ;


// gpioToPwmALT
// the ALT value to put a GPIO pin into PWM mode

@@ -339,7 +373,122 @@ static uint8_t gpioToPwmPort [] =

static unsigned long long epoch ;

//////////////////////////////////////////////////////////////////////////////////
/*
* Functions
*********************************************************************************
*/


/*
* wpiPinToGpio:
* Translate a wiringPi Pin number to native GPIO pin number.
* (We don't use this here, prefering to just do the lookup directly,
* but it's been requested!)
*********************************************************************************
*/

int wpiPinToGpio (int wpiPin)
{
return pinToGpio [wpiPin & 63] ;
}


/*
* piBoardRev:
* Return a number representing the hardware revision of the board.
* Revision is currently 1 or 2. -1 is returned on error.
*
* Much confusion here )-:
* Seems there ar esome boards with 0000 in them (mistake in manufacture)
* and some board with 0005 in them (another mistake in manufacture).
* So the distinction between boards that I can see is:
* 0000 - Error
* 0001 - Not used
* 0002 - Rev 1
* 0003 - Rev 1
* 0004 - Rev 2
* 0005 - Rev 2
* 0006 - Rev 2
* 000f - Rev 2 + 512MB
*
* A small thorn is the olde style overvolting - that will add in
* 1000000
*
*********************************************************************************
*/

int piBoardRev (void)
{
FILE *cpuFd ;
char line [120] ;
char *c, lastChar ;
static int boardRev = -1 ;

// No point checking twice...

if (boardRev != -1)
return boardRev ;

if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
return -1 ;

while (fgets (line, 120, cpuFd) != NULL)
if (strncmp (line, "Revision", 8) == 0)
break ;

fclose (cpuFd) ;

if (line == NULL)
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " (No \"Revision\" line)\n") ;
errno = 0 ;
return -1 ;
}
for (c = line ; *c ; ++c)
if (isdigit (*c))
break ;

if (!isdigit (*c))
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ;
errno = 0 ;
return -1 ;
}

// If you have overvolted the Pi, then it appears that the revision
// has 100000 added to it!

if (wiringPiDebug)
if (strlen (c) != 4)
printf ("piboardRev: This Pi has/is overvolted!\n") ;

lastChar = c [strlen (c) - 2] ;

/**/ if ((lastChar == '2') || (lastChar == '3'))
boardRev = 1 ;
else
boardRev = 2 ;

#ifdef DO_WE_CARE_ABOUT_THIS_NOW
else
{
fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ;
fprintf (stderr, " -> You may want to check:\n") ;
fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ;
fprintf (stderr, " -> Assuming a Rev 1 board\n") ;
boardRev = 1 ;
}
#endif

if (wiringPiDebug)
printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ;

return boardRev ;
}



/*
@@ -350,7 +499,6 @@ static unsigned long long epoch ;

void pinModeGpio (int pin, int mode)
{
static int pwmRunning = FALSE ;
int fSel, shift, alt ;

pin &= 63 ;
@@ -371,38 +519,28 @@ void pinModeGpio (int pin, int mode)

*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;

// We didn't initialise the PWM hardware at setup time - because it's possible that
// something else is using the PWM - e.g. the Audio systems! So if we use PWM
// here, then we're assuming that nothing else is, otherwise things are going
// to sound a bit funny...

if (!pwmRunning)
{

*(pwm + PWM_CONTROL) = 0 ; // Stop PWM
delayMicroseconds (10) ;
// Gert/Doms Values
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/32 = 600KHz)
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable

delayMicroseconds (10) ;
// Page 107 of the BCM Peripherals manual talks about the GPIO clocks,
// but I'm assuming (hoping!) that this applies to other clocks too.

*(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ;
*(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ;
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
delayMicroseconds (110) ; // See comments in pwmSetClockWPi

// Enable PWMs
(void)*(pwm + PWM_CONTROL) ;
while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
delayMicroseconds (1) ;

*(pwm + PWM0_DATA) = 512 ;
*(pwm + PWM1_DATA) = 512 ;
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz)
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk

// Balanced mode (default)
// Default range regsiter of 1024

*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
*(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ;
*(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ;

pwmRunning = TRUE ;
}
// Enable PWMs in balanced mode (default)

*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
}

// When we change mode of any pin, we remove the pull up/downs
@@ -459,6 +597,55 @@ void pwmSetRangeSys (unsigned int range)
return ;
}

/*
* pwmSetClockWPi:
* Set/Change the PWM clock. Originally my code, but changed
* (for the better!) by Chris Hall, <chris@kchall.plus.com>
* after further study of the manual and testing with a 'scope
*********************************************************************************
*/

void pwmSetClockWPi (int divisor)
{
unsigned int pwm_control ;
divisor &= 4095 ;

if (wiringPiDebug)
printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;

pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL

// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
// stays high.

*(pwm + PWM_CONTROL) = 0 ; // Stop PWM

// Stop PWM clock before changing divisor. The delay after this does need to
// this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
// flag is not working properly in balanced mode. Without the delay when DIV is
// adjusted the clock sometimes switches to very slow, once slow further DIV
// adjustments do nothing and it's difficult to get out of this mode.

*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
delayMicroseconds (110) ; // prevents clock going sloooow

while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
delayMicroseconds (1) ;

*(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;

*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
*(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL

if (wiringPiDebug)
printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
}

void pwmSetClockSys (int divisor)
{
return ;
}


#ifdef notYetReady
/*
@@ -518,7 +705,7 @@ void digitalWriteSys (int pin, int value)


/*
* pwnWrite:
* pwmWrite:
* Set an output PWM value
*********************************************************************************
*/
@@ -699,8 +886,6 @@ int waitForInterruptGpio (int pin, int mS)
}




/*
* delay:
* Wait for some number of milli seconds
@@ -800,9 +985,16 @@ unsigned int millis (void)
int wiringPiSetup (void)
{
int fd ;
int boardRev ;
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
struct timeval tv ;

if (getenv ("WIRINGPI_DEBUG") != NULL)
wiringPiDebug = TRUE ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetup called\n") ;

pinMode = pinModeWPi ;
pullUpDnControl = pullUpDnControlWPi ;
digitalWrite = digitalWriteWPi ;
@@ -813,7 +1005,16 @@ int wiringPiSetup (void)
delayMicroseconds = delayMicrosecondsWPi ;
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;
if ((boardRev = piBoardRev ()) < 0)
return -1 ;

if (boardRev == 1)
pinToGpio = pinToGpioR1 ;
else
pinToGpio = pinToGpioR2 ;

// Open the master /dev/memory device

if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
@@ -954,9 +1155,12 @@ int wiringPiSetup (void)

int wiringPiSetupGpio (void)
{
int x = wiringPiSetup () ;
int x ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupGpio called\n") ;

if (x != 0)
if ((x = wiringPiSetup ()) < 0)
return x ;

pinMode = pinModeGpio ;
@@ -969,6 +1173,7 @@ int wiringPiSetupGpio (void)
delayMicroseconds = delayMicrosecondsWPi ; // Same
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;

return 0 ;
}
@@ -989,6 +1194,9 @@ int wiringPiSetupSys (void)
struct timeval tv ;
char fName [128] ;

if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;

pinMode = pinModeSys ;
pullUpDnControl = pullUpDnControlSys ;
digitalWrite = digitalWriteSys ;
@@ -999,6 +1207,7 @@ int wiringPiSetupSys (void)
delayMicroseconds = delayMicrosecondsSys ;
pwmSetMode = pwmSetModeSys ;
pwmSetRange = pwmSetRangeSys ;
pwmSetClock = pwmSetClockSys ;


// Open and scan the directory, looking for exported GPIOs, and pre-open


+ 4
- 0
wiringPi/wiringPi.h View File

@@ -62,6 +62,9 @@ extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
extern int wiringPiSetupPiFace (void) ;

extern int piBoardRev (void) ;
extern int wpiPinToGpio (int wpiPin) ;

extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only

extern void (*pinMode) (int pin, int mode) ;
@@ -73,6 +76,7 @@ extern int (*digitalRead) (int pin) ;
extern void (*delayMicroseconds) (unsigned int howLong) ;
extern void (*pwmSetMode) (int mode) ;
extern void (*pwmSetRange) (unsigned int range) ;
extern void (*pwmSetClock) (int divisor) ;

// Interrupts



Loading…
Cancel
Save