@ -51,9 +51,6 @@
// Added in the 2 UART pins
// Added in the 2 UART pins
// Change maxPins to numPins to more accurately reflect purpose
// Change maxPins to numPins to more accurately reflect purpose
// Pad drive current fiddling
# undef DEBUG_PADS
# include <stdio.h>
# include <stdio.h>
# include <stdint.h>
# include <stdint.h>
@ -68,15 +65,16 @@
# include <pthread.h>
# include <pthread.h>
# include <sys/time.h>
# include <sys/time.h>
# include <sys/mman.h>
# include <sys/mman.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/stat.h>
# include <sys/wait.h>
# include <sys/wait.h>
# include <sys/ioctl.h>
# include "wiringPi.h"
# include "wiringPi.h"
// Function stubs
// Function stubs
void ( * pinMode ) ( int pin , int mode ) ;
void ( * pinMode ) ( int pin , int mode ) ;
int ( * getAlt ) ( int pin ) ;
void ( * pullUpDnControl ) ( int pin , int pud ) ;
void ( * pullUpDnControl ) ( int pin , int pud ) ;
void ( * digitalWrite ) ( int pin , int value ) ;
void ( * digitalWrite ) ( int pin , int value ) ;
void ( * digitalWriteByte ) ( int value ) ;
void ( * digitalWriteByte ) ( int value ) ;
@ -84,7 +82,6 @@ void (*pwmWrite) (int pin, int value) ;
void ( * setPadDrive ) ( int group , int value ) ;
void ( * setPadDrive ) ( int group , int value ) ;
int ( * digitalRead ) ( int pin ) ;
int ( * digitalRead ) ( int pin ) ;
int ( * waitForInterrupt ) ( int pin , int mS ) ;
int ( * waitForInterrupt ) ( int pin , int mS ) ;
void ( * delayMicroseconds ) ( unsigned int howLong ) ;
void ( * pwmSetMode ) ( int mode ) ;
void ( * pwmSetMode ) ( int mode ) ;
void ( * pwmSetRange ) ( unsigned int range ) ;
void ( * pwmSetRange ) ( unsigned int range ) ;
void ( * pwmSetClock ) ( int divisor ) ;
void ( * pwmSetClock ) ( int divisor ) ;
@ -177,7 +174,7 @@ static volatile uint32_t *timerIrqRaw ;
// Time for easy calculations
// Time for easy calculations
static u nsigned long long epoch ;
static u int64_t epochMilli , epochMicro ;
// Misc
// Misc
@ -586,6 +583,38 @@ void pinModeSys (int pin, int mode)
}
}
/*
* getAlt :
* Returns the ALT bits for a given port . Only really of - use
* for the gpio readall command ( I think )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
int getAltGpio ( int pin )
{
int fSel , shift , alt ;
pin & = 63 ;
fSel = gpioToGPFSEL [ pin ] ;
shift = gpioToShift [ pin ] ;
alt = ( * ( gpio + fSel ) > > shift ) & 7 ;
return alt ;
}
int getAltWPi ( int pin )
{
return getAltGpio ( pinToGpio [ pin & 63 ] ) ;
}
int getAltSys ( int pin )
{
return 0 ;
}
/*
/*
* pwmControl :
* pwmControl :
* Allow the user to control some of the PWM functions
* Allow the user to control some of the PWM functions
@ -627,7 +656,7 @@ void pwmSetRangeSys (unsigned int range)
void pwmSetClockWPi ( int divisor )
void pwmSetClockWPi ( int divisor )
{
{
u nsigned in t pwm_control ;
u int32_ t pwm_control ;
divisor & = 4095 ;
divisor & = 4095 ;
if ( wiringPiDebug )
if ( wiringPiDebug )
@ -811,10 +840,11 @@ void setPadDriveWPi (int group, int value)
wrVal = BCM_PASSWORD | 0x18 | ( value & 7 ) ;
wrVal = BCM_PASSWORD | 0x18 | ( value & 7 ) ;
* ( pads + group + 11 ) = wrVal ;
* ( pads + group + 11 ) = wrVal ;
# ifdef DEBUG_PADS
if ( wiringPiDebug )
printf ( " setPadDrive: Group: %d, value: %d (%08X) \n " , group , value , wrVal ) ;
{
printf ( " Read : %08X \n " , * ( pads + group + 11 ) ) ;
printf ( " setPadDrive: Group: %d, value: %d (%08X) \n " , group , value , wrVal ) ;
# endif
printf ( " Read : %08X \n " , * ( pads + group + 11 ) ) ;
}
}
}
void setPadDriveGpio ( int group , int value )
void setPadDriveGpio ( int group , int value )
@ -913,22 +943,12 @@ void pullUpDnControlSys (int pin, int pud)
int waitForInterruptSys ( int pin , int mS )
int waitForInterruptSys ( int pin , int mS )
{
{
int fd , x ;
int fd , x ;
char buf [ 8 ] ;
uint8_t c ;
struct pollfd polls ;
struct pollfd polls ;
if ( ( fd = sysFds [ pin & 63 ] ) = = - 1 )
if ( ( fd = sysFds [ pin & 63 ] ) = = - 1 )
return - 2 ;
return - 2 ;
// Do a dummy read
x = read ( fd , buf , 6 ) ;
if ( x < 0 )
return x ;
// And seek
lseek ( fd , 0 , SEEK_SET ) ;
// Setup poll structure
// Setup poll structure
polls . fd = fd ;
polls . fd = fd ;
@ -936,7 +956,14 @@ int waitForInterruptSys (int pin, int mS)
// Wait for it ...
// Wait for it ...
return poll ( & polls , 1 , mS ) ;
x = poll ( & polls , 1 , mS ) ;
// Do a dummy read to clear the interrupt
// A one character read appars to be enough.
( void ) read ( fd , & c , 1 ) ;
return x ;
}
}
int waitForInterruptWPi ( int pin , int mS )
int waitForInterruptWPi ( int pin , int mS )
@ -986,6 +1013,8 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
char * modeS ;
char * modeS ;
char pinS [ 8 ] ;
char pinS [ 8 ] ;
pid_t pid ;
pid_t pid ;
int count , i ;
uint8_t c ;
pin & = 63 ;
pin & = 63 ;
@ -1027,12 +1056,18 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
}
}
// Now pre-open the /sys/class node - it may already be open if
// Now pre-open the /sys/class node - it may already be open if
// we had set it up earlier , but this will do no harm.
// we are in Sys mode , but this will do no harm.
sprintf ( fName , " /sys/class/gpio/gpio%d/value " , pin ) ;
sprintf ( fName , " /sys/class/gpio/gpio%d/value " , pin ) ;
if ( ( sysFds [ pin ] = open ( fName , O_RDWR ) ) < 0 )
if ( ( sysFds [ pin ] = open ( fName , O_RDWR ) ) < 0 )
return - 1 ;
return - 1 ;
// Clear any initial pending interrupt
ioctl ( sysFds [ pin ] , FIONREAD , & count ) ;
for ( i = 0 ; i < count ; + + i )
read ( sysFds [ pin ] , & c , 1 ) ;
isrFunctions [ pin ] = function ;
isrFunctions [ pin ] = function ;
pthread_create ( & threadId , NULL , interruptHandler , & pin ) ;
pthread_create ( & threadId , NULL , interruptHandler , & pin ) ;
@ -1043,6 +1078,22 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
}
}
/*
* initialiseEpoch :
* Initialise our start - of - time variable to be the current unix
* time in milliseconds .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static void initialiseEpoch ( void )
{
struct timeval tv ;
gettimeofday ( & tv , NULL ) ;
epochMilli = ( uint64_t ) tv . tv_sec * ( uint64_t ) 1000 + ( uint64_t ) ( tv . tv_usec / 1000 ) ;
epochMicro = ( uint64_t ) tv . tv_sec * ( uint64_t ) 1000000 + ( uint64_t ) ( tv . tv_usec ) ;
}
/*
/*
* delay :
* delay :
* Wait for some number of milli seconds
* Wait for some number of milli seconds
@ -1078,28 +1129,8 @@ void delay (unsigned int howLong)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
*/
void delayMicrosecondsSys ( unsigned int howLong )
{
struct timespec sleeper , dummy ;
sleeper . tv_sec = 0 ;
sleeper . tv_nsec = ( long ) ( howLong * 1000 ) ;
nanosleep ( & sleeper , & dummy ) ;
}
void delayMicrosecondsHard ( unsigned int howLong )
void delayMicrosecondsHard ( unsigned int howLong )
{
{
# ifdef HARD_TIMER
volatile unsigned int dummy ;
* ( timer + TIMER_LOAD ) = howLong ;
* ( timer + TIMER_IRQ_CLR ) = 0 ;
dummy = * timerIrqRaw ;
while ( dummy = = 0 )
dummy = * timerIrqRaw ;
# else
struct timeval tNow , tLong , tEnd ;
struct timeval tNow , tLong , tEnd ;
gettimeofday ( & tNow , NULL ) ;
gettimeofday ( & tNow , NULL ) ;
@ -1109,10 +1140,9 @@ void delayMicrosecondsHard (unsigned int howLong)
while ( timercmp ( & tNow , & tEnd , < ) )
while ( timercmp ( & tNow , & tEnd , < ) )
gettimeofday ( & tNow , NULL ) ;
gettimeofday ( & tNow , NULL ) ;
# endif
}
}
void delayMicroseconds WPi ( unsigned int howLong )
void delayMicroseconds ( unsigned int howLong )
{
{
struct timespec sleeper ;
struct timespec sleeper ;
@ -1138,13 +1168,30 @@ void delayMicrosecondsWPi (unsigned int howLong)
unsigned int millis ( void )
unsigned int millis ( void )
{
{
struct timeval tv ;
struct timeval tv ;
u nsigned long long t1 ;
u int64_t now ;
gettimeofday ( & tv , NULL ) ;
gettimeofday ( & tv , NULL ) ;
now = ( uint64_t ) tv . tv_sec * ( uint64_t ) 1000 + ( uint64_t ) ( tv . tv_usec / 1000 ) ;
t1 = ( tv . tv_sec * 1000000 + tv . tv_usec ) / 1000 ;
return ( uint32_t ) ( now - epochMilli ) ;
}
/*
* micros :
* Return a number of microseconds as an unsigned int .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
return ( uint32_t ) ( t1 - epoch ) ;
unsigned int micros ( void )
{
struct timeval tv ;
uint64_t now ;
gettimeofday ( & tv , NULL ) ;
now = ( uint64_t ) tv . tv_sec * ( uint64_t ) 1000000 + ( uint64_t ) tv . tv_usec ;
return ( uint32_t ) ( now - epochMicro ) ;
}
}
@ -1161,8 +1208,6 @@ int wiringPiSetup (void)
{
{
int fd ;
int fd ;
int boardRev ;
int boardRev ;
//uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ;
struct timeval tv ;
if ( geteuid ( ) ! = 0 )
if ( geteuid ( ) ! = 0 )
{
{
@ -1180,6 +1225,7 @@ int wiringPiSetup (void)
printf ( " wiringPi: wiringPiSetup called \n " ) ;
printf ( " wiringPi: wiringPiSetup called \n " ) ;
pinMode = pinModeWPi ;
pinMode = pinModeWPi ;
getAlt = getAltWPi ;
pullUpDnControl = pullUpDnControlWPi ;
pullUpDnControl = pullUpDnControlWPi ;
digitalWrite = digitalWriteWPi ;
digitalWrite = digitalWriteWPi ;
digitalWriteByte = digitalWriteByteGpio ; // Same code
digitalWriteByte = digitalWriteByteGpio ; // Same code
@ -1187,7 +1233,6 @@ int wiringPiSetup (void)
setPadDrive = setPadDriveWPi ;
setPadDrive = setPadDriveWPi ;
digitalRead = digitalReadWPi ;
digitalRead = digitalReadWPi ;
waitForInterrupt = waitForInterruptWPi ;
waitForInterrupt = waitForInterruptWPi ;
delayMicroseconds = delayMicrosecondsWPi ;
pwmSetMode = pwmSetModeWPi ;
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;
pwmSetClock = pwmSetClockWPi ;
@ -1268,11 +1313,6 @@ int wiringPiSetup (void)
return - 1 ;
return - 1 ;
}
}
# ifdef DEBUG_PADS
printf ( " Checking pads @ 0x%08X \n " , ( unsigned int ) pads ) ;
printf ( " -> %08X %08X %08X \n " , * ( pads + 11 ) , * ( pads + 12 ) , * ( pads + 13 ) ) ;
# endif
// The system timer
// The system timer
timer = ( uint32_t * ) mmap ( 0 , BLOCK_SIZE , PROT_READ | PROT_WRITE , MAP_SHARED , fd , GPIO_TIMER ) ;
timer = ( uint32_t * ) mmap ( 0 , BLOCK_SIZE , PROT_READ | PROT_WRITE , MAP_SHARED , fd , GPIO_TIMER ) ;
@ -1295,10 +1335,7 @@ int wiringPiSetup (void)
* ( timer + TIMER_PRE_DIV ) = 0x00000F9 ;
* ( timer + TIMER_PRE_DIV ) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;
// Initialise our epoch for millis()
initialiseEpoch ( ) ;
gettimeofday ( & tv , NULL ) ;
epoch = ( tv . tv_sec * 1000000 + tv . tv_usec ) / 1000 ;
wiringPiMode = WPI_MODE_PINS ;
wiringPiMode = WPI_MODE_PINS ;
@ -1332,6 +1369,7 @@ int wiringPiSetupGpio (void)
printf ( " wiringPi: wiringPiSetupGpio called \n " ) ;
printf ( " wiringPi: wiringPiSetupGpio called \n " ) ;
pinMode = pinModeGpio ;
pinMode = pinModeGpio ;
getAlt = getAltGpio ;
pullUpDnControl = pullUpDnControlGpio ;
pullUpDnControl = pullUpDnControlGpio ;
digitalWrite = digitalWriteGpio ;
digitalWrite = digitalWriteGpio ;
digitalWriteByte = digitalWriteByteGpio ;
digitalWriteByte = digitalWriteByteGpio ;
@ -1339,7 +1377,6 @@ int wiringPiSetupGpio (void)
setPadDrive = setPadDriveGpio ;
setPadDrive = setPadDriveGpio ;
digitalRead = digitalReadGpio ;
digitalRead = digitalReadGpio ;
waitForInterrupt = waitForInterruptGpio ;
waitForInterrupt = waitForInterruptGpio ;
delayMicroseconds = delayMicrosecondsWPi ; // Same
pwmSetMode = pwmSetModeWPi ;
pwmSetMode = pwmSetModeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetRange = pwmSetRangeWPi ;
pwmSetClock = pwmSetClockWPi ;
pwmSetClock = pwmSetClockWPi ;
@ -1363,7 +1400,6 @@ int wiringPiSetupSys (void)
{
{
int boardRev ;
int boardRev ;
int pin ;
int pin ;
struct timeval tv ;
char fName [ 128 ] ;
char fName [ 128 ] ;
if ( getenv ( " WIRINGPI_DEBUG " ) ! = NULL )
if ( getenv ( " WIRINGPI_DEBUG " ) ! = NULL )
@ -1373,6 +1409,7 @@ int wiringPiSetupSys (void)
printf ( " wiringPi: wiringPiSetupSys called \n " ) ;
printf ( " wiringPi: wiringPiSetupSys called \n " ) ;
pinMode = pinModeSys ;
pinMode = pinModeSys ;
getAlt = getAltSys ;
pullUpDnControl = pullUpDnControlSys ;
pullUpDnControl = pullUpDnControlSys ;
digitalWrite = digitalWriteSys ;
digitalWrite = digitalWriteSys ;
digitalWriteByte = digitalWriteByteSys ;
digitalWriteByte = digitalWriteByteSys ;
@ -1380,7 +1417,6 @@ int wiringPiSetupSys (void)
setPadDrive = setPadDriveSys ;
setPadDrive = setPadDriveSys ;
digitalRead = digitalReadSys ;
digitalRead = digitalReadSys ;
waitForInterrupt = waitForInterruptSys ;
waitForInterrupt = waitForInterruptSys ;
delayMicroseconds = delayMicrosecondsSys ;
pwmSetMode = pwmSetModeSys ;
pwmSetMode = pwmSetModeSys ;
pwmSetRange = pwmSetRangeSys ;
pwmSetRange = pwmSetRangeSys ;
pwmSetClock = pwmSetClockSys ;
pwmSetClock = pwmSetClockSys ;
@ -1401,10 +1437,7 @@ int wiringPiSetupSys (void)
sysFds [ pin ] = open ( fName , O_RDWR ) ;
sysFds [ pin ] = open ( fName , O_RDWR ) ;
}
}
// Initialise the epoch for mills() ...
initialiseEpoch ( ) ;
gettimeofday ( & tv , NULL ) ;
epoch = ( tv . tv_sec * 1000000 + tv . tv_usec ) / 1000 ;
wiringPiMode = WPI_MODE_GPIO_SYS ;
wiringPiMode = WPI_MODE_GPIO_SYS ;