mirror of
https://github.com/clockworkpi/WiringPi.git
synced 2026-03-24 21:02:44 +01:00
Big update here.
delayMicrosecondsHard re-written - again. Added a serialRead example program, and added in the okLed to the examples too. Updated/checked some of the GPIO/PWM code. Added in some experimental servo and tone generating code and and example or 2. Tweaks to the gpio command to correctly load the I2C modules too.
This commit is contained in:
@@ -24,8 +24,12 @@
|
||||
DYN_VERS_MAJ=1
|
||||
DYN_VERS_MIN=0
|
||||
|
||||
VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
|
||||
DESTDIR=/usr
|
||||
PREFIX=/local
|
||||
|
||||
STATIC=libwiringPi.a
|
||||
DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
|
||||
DYNAMIC=libwiringPi.so.$(VERSION)
|
||||
|
||||
#DEBUG = -g -O0
|
||||
DEBUG = -O2
|
||||
@@ -41,21 +45,22 @@ LIBS =
|
||||
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
|
||||
gertboard.c \
|
||||
piNes.c \
|
||||
lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c
|
||||
lcd.c piHiPri.c piThread.c wiringPiSPI.c \
|
||||
softPwm.c softServo.c softTone.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
#all: $(STATIC) $(DYNAMIC)
|
||||
all: $(DYNAMIC)
|
||||
all: $(STATIC) $(DYNAMIC)
|
||||
#all: $(DYNAMIC)
|
||||
|
||||
$(STATIC): $(OBJ)
|
||||
@echo [Link (Static)]
|
||||
@echo "[Link (Static)]"
|
||||
@ar rcs $(STATIC) $(OBJ)
|
||||
@ranlib $(STATIC)
|
||||
@size $(STATIC)
|
||||
# @size $(STATIC)
|
||||
|
||||
$(DYNAMIC): $(OBJ)
|
||||
@echo [Link]
|
||||
@echo "[Link (Dynamic)]"
|
||||
@$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)
|
||||
|
||||
.c.o:
|
||||
@@ -74,34 +79,38 @@ tags: $(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 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
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
|
||||
@install -m 0755 -d $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringShift.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softPwm.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include
|
||||
@install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib
|
||||
@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
|
||||
@ldconfig
|
||||
|
||||
.PHONEY: uninstall
|
||||
uninstall:
|
||||
@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.*
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/softTone.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
|
||||
@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
|
||||
@ldconfig
|
||||
|
||||
|
||||
|
||||
202
wiringPi/softServo.c
Normal file
202
wiringPi/softServo.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* softServo.c:
|
||||
* Provide N channels of software driven PWM suitable for RC
|
||||
* servo motors.
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
*
|
||||
* wiringPi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* wiringPi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with wiringPi.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
//#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "softServo.h"
|
||||
|
||||
// RC Servo motors are a bit of an oddity - designed in the days when
|
||||
// radio control was experimental and people were tryin to make
|
||||
// things as simple as possible as it was all very expensive...
|
||||
//
|
||||
// So... To drive an RC Servo motor, you need to send it a modified PWM
|
||||
// signal - it needs anything from 1ms to 2ms - with 1ms meaning
|
||||
// to move the server fully left, and 2ms meaning to move it fully
|
||||
// right. Then you need a long gap before sending the next pulse.
|
||||
// The reason for this is that you send a multiplexed stream of these
|
||||
// pulses up the radio signal into the reciever which de-multiplexes
|
||||
// them into the signals for each individual servo. Typically there
|
||||
// might be 8 channels, so you need at least 8 "slots" of 2mS pulses
|
||||
// meaning the entire frame must fit into a 16mS slot - which would
|
||||
// then be repeated...
|
||||
//
|
||||
// In practice we have a total slot width of about 20mS - so we're sending 50
|
||||
// updates per second to each servo.
|
||||
//
|
||||
// In this code, we don't need to be too fussy about the gap as we're not doing
|
||||
// the multipexing, but it does need to be at least 10mS, and preferably 16
|
||||
// from what I've been able to determine.
|
||||
|
||||
|
||||
#define MAX_SERVOS 8
|
||||
|
||||
static int pinMap [MAX_SERVOS] ; // Keep track of our pins
|
||||
static int pulseWidth [MAX_SERVOS] ; // microseconds
|
||||
|
||||
|
||||
/*
|
||||
* softServoThread:
|
||||
* Thread to do the actual Servo PWM output
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static PI_THREAD (softServoThread)
|
||||
{
|
||||
register int i, j, k, m, tmp ;
|
||||
int lastDelay, pin, servo ;
|
||||
|
||||
int myDelays [MAX_SERVOS] ;
|
||||
int myPins [MAX_SERVOS] ;
|
||||
|
||||
struct timeval tNow, tStart, tPeriod, tGap, tTotal ;
|
||||
struct timespec tNs ;
|
||||
|
||||
tTotal.tv_sec = 0 ;
|
||||
tTotal.tv_usec = 8000 ;
|
||||
|
||||
piHiPri (50) ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
gettimeofday (&tStart, NULL) ;
|
||||
|
||||
memcpy (myDelays, pulseWidth, sizeof (myDelays)) ;
|
||||
memcpy (myPins, pinMap, sizeof (myPins)) ;
|
||||
|
||||
// Sort the delays (& pins), shortest first
|
||||
|
||||
for (m = MAX_SERVOS / 2 ; m > 0 ; m /= 2 )
|
||||
for (j = m ; j < MAX_SERVOS ; ++j)
|
||||
for (i = j - m ; i >= 0 ; i -= m)
|
||||
{
|
||||
k = i + m ;
|
||||
if (myDelays [k] >= myDelays [i])
|
||||
break ;
|
||||
else // Swap
|
||||
{
|
||||
tmp = myDelays [i] ; myDelays [i] = myDelays [k] ; myDelays [k] = tmp ;
|
||||
tmp = myPins [i] ; myPins [i] = myPins [k] ; myPins [k] = tmp ;
|
||||
}
|
||||
}
|
||||
|
||||
// All on
|
||||
|
||||
lastDelay = 0 ;
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
{
|
||||
if ((pin = myPins [servo]) == -1)
|
||||
continue ;
|
||||
|
||||
digitalWrite (pin, HIGH) ;
|
||||
myDelays [servo] = myDelays [servo] - lastDelay ;
|
||||
lastDelay += myDelays [servo] ;
|
||||
}
|
||||
|
||||
// Now loop, turning them all off as required
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
{
|
||||
if ((pin = myPins [servo]) == -1)
|
||||
continue ;
|
||||
|
||||
delayMicroseconds (myDelays [servo]) ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
}
|
||||
|
||||
// Wait until the end of an 8mS time-slot
|
||||
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
timersub (&tNow, &tStart, &tPeriod) ;
|
||||
timersub (&tTotal, &tPeriod, &tGap) ;
|
||||
tNs.tv_sec = tGap.tv_sec ;
|
||||
tNs.tv_nsec = tGap.tv_usec * 1000 ;
|
||||
nanosleep (&tNs, NULL) ;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softServoWrite:
|
||||
* Write a Servo value to the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softServoWrite (int servoPin, int value)
|
||||
{
|
||||
int servo ;
|
||||
|
||||
servoPin &= 63 ;
|
||||
|
||||
/**/ if (value < -250)
|
||||
value = -250 ;
|
||||
else if (value > 1250)
|
||||
value = 1250 ;
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
if (pinMap [servo] == servoPin)
|
||||
pulseWidth [servo] = value + 1000 ; // uS
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softServoSetup:
|
||||
* Setup the software servo system
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7)
|
||||
{
|
||||
int servo ;
|
||||
|
||||
if (p0 != -1) { pinMode (p0, OUTPUT) ; digitalWrite (p0, LOW) ; }
|
||||
if (p1 != -1) { pinMode (p1, OUTPUT) ; digitalWrite (p1, LOW) ; }
|
||||
if (p2 != -1) { pinMode (p2, OUTPUT) ; digitalWrite (p2, LOW) ; }
|
||||
if (p3 != -1) { pinMode (p3, OUTPUT) ; digitalWrite (p3, LOW) ; }
|
||||
if (p4 != -1) { pinMode (p4, OUTPUT) ; digitalWrite (p4, LOW) ; }
|
||||
if (p5 != -1) { pinMode (p5, OUTPUT) ; digitalWrite (p5, LOW) ; }
|
||||
if (p6 != -1) { pinMode (p6, OUTPUT) ; digitalWrite (p6, LOW) ; }
|
||||
if (p7 != -1) { pinMode (p7, OUTPUT) ; digitalWrite (p7, LOW) ; }
|
||||
|
||||
pinMap [0] = p0 ;
|
||||
pinMap [1] = p1 ;
|
||||
pinMap [2] = p2 ;
|
||||
pinMap [3] = p3 ;
|
||||
pinMap [4] = p4 ;
|
||||
pinMap [5] = p5 ;
|
||||
pinMap [6] = p6 ;
|
||||
pinMap [7] = p7 ;
|
||||
|
||||
for (servo = 0 ; servo < MAX_SERVOS ; ++servo)
|
||||
pulseWidth [servo] = 1500 ; // Mid point
|
||||
|
||||
return piThreadCreate (softServoThread) ;
|
||||
}
|
||||
35
wiringPi/softServo.h
Normal file
35
wiringPi/softServo.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* softServo.h:
|
||||
* Provide N channels of software driven PWM suitable for RC
|
||||
* servo motors.
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
*
|
||||
* wiringPi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* wiringPi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with wiringPi.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void softServoWrite (int pin, int value) ;
|
||||
extern int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
119
wiringPi/softTone.c
Normal file
119
wiringPi/softTone.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* softTone.c:
|
||||
* For that authentic retro sound...
|
||||
* Er... A little experiment to produce tones out of a Pi using
|
||||
* one (or 2) GPIO pins and a piezeo "speaker" element.
|
||||
* (Or a high impedance speaker, but don'y blame me if you blow-up
|
||||
* the GPIO pins!)
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
*
|
||||
* wiringPi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* wiringPi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with wiringPi.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "wiringPi.h"
|
||||
#include "softTone.h"
|
||||
|
||||
#define MAX_PINS 64
|
||||
|
||||
#define PULSE_TIME 100
|
||||
|
||||
static int frewqs [MAX_PINS] ;
|
||||
|
||||
static int newPin = -1 ;
|
||||
|
||||
|
||||
/*
|
||||
* softToneThread:
|
||||
* Thread to do the actual PWM output
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
static PI_THREAD (softToneThread)
|
||||
{
|
||||
int pin, frewq, halfPeriod ;
|
||||
|
||||
pin = newPin ;
|
||||
newPin = -1 ;
|
||||
|
||||
piHiPri (50) ;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
frewq = frewqs [pin] ;
|
||||
if (frewq != 0)
|
||||
{
|
||||
halfPeriod = 500000 / frewq ;
|
||||
|
||||
digitalWrite (pin, HIGH) ;
|
||||
delayMicroseconds (halfPeriod) ;
|
||||
|
||||
digitalWrite (pin, LOW) ;
|
||||
delayMicroseconds (halfPeriod) ;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softToneWrite:
|
||||
* Write a frequency value to the given pin
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void softToneWrite (int pin, int frewq)
|
||||
{
|
||||
pin &= 63 ;
|
||||
|
||||
/**/ if (frewq < 0)
|
||||
frewq = 0 ;
|
||||
else if (frewq > 5000) // Max 5KHz
|
||||
frewq = 5000 ;
|
||||
|
||||
frewqs [pin] = frewq ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* softToneCreate:
|
||||
* Create a new tone thread.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
int softToneCreate (int pin)
|
||||
{
|
||||
int res ;
|
||||
|
||||
pinMode (pin, OUTPUT) ;
|
||||
digitalWrite (pin, LOW) ;
|
||||
|
||||
frewqs [pin] = 0 ;
|
||||
|
||||
newPin = pin ;
|
||||
res = piThreadCreate (softToneThread) ;
|
||||
|
||||
while (newPin != -1)
|
||||
delay (1) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
38
wiringPi/softTone.h
Normal file
38
wiringPi/softTone.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* softTone.c:
|
||||
* For that authentic retro sound...
|
||||
* Er... A little experiment to produce tones out of a Pi using
|
||||
* one (or 2) GPIO pins and a piezeo "speaker" element.
|
||||
* (Or a high impedance speaker, but don'y blame me if you blow-up
|
||||
* the GPIO pins!)
|
||||
* Copyright (c) 2012 Gordon Henderson
|
||||
***********************************************************************
|
||||
* This file is part of wiringPi:
|
||||
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
||||
*
|
||||
* wiringPi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* wiringPi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with wiringPi.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int softToneCreate (int pin) ;
|
||||
extern void softToneWrite (int pin, int frewq) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -77,6 +77,7 @@
|
||||
void (*pinMode) (int pin, int mode) ;
|
||||
void (*pullUpDnControl) (int pin, int pud) ;
|
||||
void (*digitalWrite) (int pin, int value) ;
|
||||
void (*digitalWriteByte) (int value) ;
|
||||
void (*pwmWrite) (int pin, int value) ;
|
||||
void (*setPadDrive) (int group, int value) ;
|
||||
int (*digitalRead) (int pin) ;
|
||||
@@ -399,15 +400,15 @@ int wpiPinToGpio (int wpiPin)
|
||||
* 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).
|
||||
* Seems there are some 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
|
||||
* 0005 - Rev 2 (but error)
|
||||
* 0006 - Rev 2
|
||||
* 000f - Rev 2 + 512MB
|
||||
*
|
||||
@@ -499,6 +500,8 @@ int piBoardRev (void)
|
||||
|
||||
void pinModeGpio (int pin, int mode)
|
||||
{
|
||||
// register int barrier ;
|
||||
|
||||
int fSel, shift, alt ;
|
||||
|
||||
pin &= 63 ;
|
||||
@@ -519,30 +522,40 @@ void pinModeGpio (int pin, int mode)
|
||||
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
|
||||
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
|
||||
|
||||
// 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 + PWM_CONTROL) = 0 ; // Stop PWM
|
||||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
|
||||
(void)*(pwm + PWM_CONTROL) ;
|
||||
while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY
|
||||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
|
||||
while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
|
||||
delayMicroseconds (1) ;
|
||||
|
||||
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz)
|
||||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk
|
||||
|
||||
// Default range regsiter of 1024
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
|
||||
*(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ;
|
||||
*(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ;
|
||||
// Default range register of 1024
|
||||
|
||||
*(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ;
|
||||
*(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ;
|
||||
*(pwm + PWM0_DATA) = 0 ; delayMicroseconds (10) ;
|
||||
*(pwm + PWM1_DATA) = 0 ; delayMicroseconds (10) ;
|
||||
|
||||
// Enable PWMs in balanced mode (default)
|
||||
|
||||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
|
||||
|
||||
delay (100) ;
|
||||
}
|
||||
|
||||
|
||||
// When we change mode of any pin, we remove the pull up/downs
|
||||
// Or we used to... Hm. Commented out now because for some wieird reason,
|
||||
// it seems to block subsequent attempts to set the pull up/downs and I've
|
||||
@@ -629,7 +642,7 @@ void pwmSetClockWPi (int divisor)
|
||||
*(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
|
||||
while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
|
||||
delayMicroseconds (1) ;
|
||||
|
||||
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
|
||||
@@ -704,6 +717,50 @@ void digitalWriteSys (int pin, int value)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* digitalWriteByte:
|
||||
* Write an 8-bit byte to the first 8 GPIO pins - try to do it as
|
||||
* fast as possible.
|
||||
* However it still needs 2 operations to set the bits, so any external
|
||||
* hardware must not rely on seeing a change as there will be a change
|
||||
* to set the outputs bits to zero, then another change to set the 1's
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
void digitalWriteByteGpio (int value)
|
||||
{
|
||||
uint32_t pinSet = 0 ;
|
||||
uint32_t pinClr = 0 ;
|
||||
int mask = 1 ;
|
||||
int pin ;
|
||||
|
||||
for (pin = 0 ; pin < 8 ; ++pin)
|
||||
{
|
||||
if ((value & mask) == 0)
|
||||
pinClr |= (1 << pinToGpio [pin]) ;
|
||||
else
|
||||
pinSet |= (1 << pinToGpio [pin]) ;
|
||||
|
||||
*(gpio + gpioToGPCLR [0]) = pinClr ;
|
||||
*(gpio + gpioToGPSET [0]) = pinSet ;
|
||||
|
||||
mask <<= 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWriteByteSys (int value)
|
||||
{
|
||||
int mask = 1 ;
|
||||
int pin ;
|
||||
|
||||
for (pin = 0 ; pin < 8 ; ++pin)
|
||||
{
|
||||
digitalWriteSys (pinToGpio [pin], value & mask) ;
|
||||
mask <<= 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pwmWrite:
|
||||
* Set an output PWM value
|
||||
@@ -915,6 +972,9 @@ void delay (unsigned int howLong)
|
||||
* somewhat sub-optimal in that it uses 100% CPU, something not an issue
|
||||
* in a microcontroller, but under a multi-tasking, multi-user OS, it's
|
||||
* wastefull, however we've no real choice )-:
|
||||
*
|
||||
* Plan B: It seems all might not be well with that plan, so changing it
|
||||
* to use gettimeofday () and poll on that instead...
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
@@ -930,16 +990,31 @@ void delayMicrosecondsSys (unsigned int howLong)
|
||||
|
||||
void delayMicrosecondsHard (unsigned int howLong)
|
||||
{
|
||||
#ifdef HARD_TIMER
|
||||
volatile unsigned int dummy ;
|
||||
|
||||
*(timer + TIMER_LOAD) = howLong ;
|
||||
*(timer + TIMER_IRQ_CLR) = 0 ;
|
||||
|
||||
while (*timerIrqRaw == 0)
|
||||
;
|
||||
dummy = *timerIrqRaw ;
|
||||
while (dummy == 0)
|
||||
dummy = *timerIrqRaw ;
|
||||
#else
|
||||
struct timeval tNow, tLong, tEnd ;
|
||||
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
tLong.tv_sec = howLong / 1000000 ;
|
||||
tLong.tv_usec = howLong % 1000000 ;
|
||||
timeradd (&tNow, &tLong, &tEnd) ;
|
||||
|
||||
while (timercmp (&tNow, &tEnd, <))
|
||||
gettimeofday (&tNow, NULL) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void delayMicrosecondsWPi (unsigned int howLong)
|
||||
{
|
||||
struct timespec sleeper, dummy ;
|
||||
struct timespec sleeper ;
|
||||
|
||||
/**/ if (howLong == 0)
|
||||
return ;
|
||||
@@ -949,7 +1024,7 @@ void delayMicrosecondsWPi (unsigned int howLong)
|
||||
{
|
||||
sleeper.tv_sec = 0 ;
|
||||
sleeper.tv_nsec = (long)(howLong * 1000) ;
|
||||
nanosleep (&sleeper, &dummy) ;
|
||||
nanosleep (&sleeper, NULL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,6 +1073,7 @@ int wiringPiSetup (void)
|
||||
pinMode = pinModeWPi ;
|
||||
pullUpDnControl = pullUpDnControlWPi ;
|
||||
digitalWrite = digitalWriteWPi ;
|
||||
digitalWriteByte = digitalWriteByteGpio ; // Same code
|
||||
pwmWrite = pwmWriteWPi ;
|
||||
setPadDrive = setPadDriveWPi ;
|
||||
digitalRead = digitalReadWPi ;
|
||||
@@ -1166,6 +1242,7 @@ int wiringPiSetupGpio (void)
|
||||
pinMode = pinModeGpio ;
|
||||
pullUpDnControl = pullUpDnControlGpio ;
|
||||
digitalWrite = digitalWriteGpio ;
|
||||
digitalWriteByte = digitalWriteByteGpio ;
|
||||
pwmWrite = pwmWriteGpio ;
|
||||
setPadDrive = setPadDriveGpio ;
|
||||
digitalRead = digitalReadGpio ;
|
||||
@@ -1190,6 +1267,7 @@ int wiringPiSetupGpio (void)
|
||||
|
||||
int wiringPiSetupSys (void)
|
||||
{
|
||||
int boardRev ;
|
||||
int pin ;
|
||||
struct timeval tv ;
|
||||
char fName [128] ;
|
||||
@@ -1200,6 +1278,7 @@ int wiringPiSetupSys (void)
|
||||
pinMode = pinModeSys ;
|
||||
pullUpDnControl = pullUpDnControlSys ;
|
||||
digitalWrite = digitalWriteSys ;
|
||||
digitalWriteByte = digitalWriteByteSys ;
|
||||
pwmWrite = pwmWriteSys ;
|
||||
setPadDrive = setPadDriveSys ;
|
||||
digitalRead = digitalReadSys ;
|
||||
@@ -1209,6 +1288,14 @@ int wiringPiSetupSys (void)
|
||||
pwmSetRange = pwmSetRangeSys ;
|
||||
pwmSetClock = pwmSetClockSys ;
|
||||
|
||||
if ((boardRev = piBoardRev ()) < 0)
|
||||
return -1 ;
|
||||
|
||||
if (boardRev == 1)
|
||||
pinToGpio = pinToGpioR1 ;
|
||||
else
|
||||
pinToGpio = pinToGpioR2 ;
|
||||
|
||||
|
||||
// Open and scan the directory, looking for exported GPIOs, and pre-open
|
||||
// the 'value' interface to speed things up for later
|
||||
|
||||
@@ -70,6 +70,7 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio
|
||||
extern void (*pinMode) (int pin, int mode) ;
|
||||
extern void (*pullUpDnControl) (int pin, int pud) ;
|
||||
extern void (*digitalWrite) (int pin, int value) ;
|
||||
extern void (*digitalWriteByte) (int value) ;
|
||||
extern void (*pwmWrite) (int pin, int value) ;
|
||||
extern void (*setPadDrive) (int group, int value) ;
|
||||
extern int (*digitalRead) (int pin) ;
|
||||
|
||||
@@ -182,6 +182,11 @@ void digitalWritePiFace (int pin, int value)
|
||||
writeByte (GPIOA, dataOutRegister) ;
|
||||
}
|
||||
|
||||
void digitalWriteBytePiFace (int value)
|
||||
{
|
||||
writeByte (GPIOA, value) ;
|
||||
}
|
||||
|
||||
|
||||
void digitalWritePiFaceSpecial (int pin, int value)
|
||||
{
|
||||
@@ -318,12 +323,13 @@ int wiringPiSetupPiFace (void)
|
||||
writeByte (GPIOA, 0x00) ; // Set all outptus off
|
||||
writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B
|
||||
|
||||
pinMode = pinModePiFace ;
|
||||
pullUpDnControl = pullUpDnControlPiFace ;
|
||||
digitalWrite = digitalWritePiFace ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
pinMode = pinModePiFace ;
|
||||
pullUpDnControl = pullUpDnControlPiFace ;
|
||||
digitalWrite = digitalWritePiFace ;
|
||||
digitalWriteByte = digitalWriteBytePiFace ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
@@ -344,12 +350,13 @@ int wiringPiSetupPiFaceForGpioProg (void)
|
||||
if (x != 0)
|
||||
return x ;
|
||||
|
||||
pinMode = pinModePiFace ;
|
||||
pinMode = pinModePiFace ;
|
||||
pullUpDnControl = pullUpDnControlPiFaceSpecial ;
|
||||
digitalWrite = digitalWritePiFaceSpecial ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
digitalWriteByte = digitalWriteBytePiFace ;
|
||||
pwmWrite = pwmWritePiFace ;
|
||||
digitalRead = digitalReadPiFace ;
|
||||
waitForInterrupt = waitForInterruptPiFace ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ static int spiFds [2] ;
|
||||
|
||||
int wiringPiSPIGetFd (int channel)
|
||||
{
|
||||
return spiFds [channel &1] ;
|
||||
return spiFds [channel & 1] ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user