#include <sys/wait.h>
#include <sys/ioctl.h>
+#include "softPwm.h"
+
#include "wiringPi.h"
#ifndef TRUE
#define PI_GPIO_MASK (0xFFFFFFC0)
-static struct wiringPiNodeStruct *wiringPiNodes = NULL ;
+struct wiringPiNodeStruct *wiringPiNodes = NULL ;
// BCM Magic
#define FSEL_INPT 0b000
#define FSEL_OUTP 0b001
#define FSEL_ALT0 0b100
-#define FSEL_ALT0 0b100
#define FSEL_ALT1 0b101
#define FSEL_ALT2 0b110
#define FSEL_ALT3 0b111
// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value
-static int sysFds [64] ;
+static int sysFds [64] =
+{
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+} ;
// ISR Data
*********************************************************************************
*/
-static struct wiringPiNodeStruct *wiringPiFindNode (int pin)
+struct wiringPiNodeStruct *wiringPiFindNode (int pin)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;
*********************************************************************************
*/
+/*
+ * pinModeAlt:
+ * This is an un-documented special to let you set any pin to any mode
+ *********************************************************************************
+ */
+
+void pinModeAlt (int pin, int mode)
+{
+ int fSel, shift ;
+
+ if ((pin & PI_GPIO_MASK) == 0) // On-board pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
+
+ fSel = gpioToGPFSEL [pin] ;
+ shift = gpioToShift [pin] ;
+
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
+ }
+}
+
/*
* pinMode:
{
int fSel, shift, alt ;
struct wiringPiNodeStruct *node = wiringPiNodes ;
+ int origPin = pin ;
if ((pin & PI_GPIO_MASK) == 0) // On-board pin
{
else if (wiringPiMode != WPI_MODE_GPIO)
return ;
+ softPwmStop (origPin) ;
+
fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
else if (mode == OUTPUT)
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
+ else if (mode == SOFT_PWM_OUTPUT)
+ softPwmCreate (origPin, 0, 100) ;
else if (mode == PWM_OUTPUT)
{
- if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
+ if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
return ;
// Set pin to PWM mode
pwmSetMode (PWM_MODE_BAL) ; // Pi default mode
pwmSetRange (1024) ; // Default range of 1024
- pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
+ pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
}
else if (mode == GPIO_CLOCK)
{
char c ;
int bcmGpioPin ;
- pin &= 63 ;
+ if ((pin < 0) || (pin > 63))
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ;
/**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
sprintf (pinS, "%d", bcmGpioPin) ;
if ((pid = fork ()) < 0) // Fail
- return pid ;
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ;
if (pid == 0) // Child, exec
{
execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ;
- return -1 ; // Failure ...
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ;
}
else // Parent, wait
wait (NULL) ;
}
-// Now pre-open the /sys/class node - it may already be open if
-// we are in Sys mode or if we call here twice, if-so, we'll close it.
-
- if (sysFds [bcmGpioPin] != -1)
- close (sysFds [bcmGpioPin]) ;
+// Now pre-open the /sys/class node - but it may already be open if
+// we are in Sys mode...
- sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ;
- if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
- return -1 ;
+ if (sysFds [bcmGpioPin] == -1)
+ {
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ;
+ if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ;
+ }
// Clear any initial pending interrupt
void delayMicroseconds (unsigned int howLong)
{
struct timespec sleeper ;
+ unsigned int uSecs = howLong % 1000000 ;
+ unsigned int wSecs = howLong / 1000000 ;
/**/ if (howLong == 0)
return ;
delayMicrosecondsHard (howLong) ;
else
{
- sleeper.tv_sec = 0 ;
- sleeper.tv_nsec = (long)(howLong * 1000) ;
+ sleeper.tv_sec = wSecs ;
+ sleeper.tv_nsec = (long)(uSecs * 1000L) ;
nanosleep (&sleeper, NULL) ;
}
}
// Open the master /dev/memory device
- if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
+ if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
// GPIO: