Browse Source

#219 boost speed and improve compatibility with sysfs

pull/228/head
mstroh76 7 months ago
parent
commit
ad6d821329
2 changed files with 97 additions and 66 deletions
  1. +96
    -66
      wiringPi/wiringPi.c
  2. +1
    -0
      wiringPi/wiringPi.h

+ 96
- 66
wiringPi/wiringPi.c View File

@@ -398,7 +398,7 @@ int wiringPiTryGpioMem = FALSE ;
// sysFds: // sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value // Map a file descriptor from the /sys/class/gpio/gpioX/value


static unsigned int cdflags [64] =
static unsigned int lineFlags [64] =
{ {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -406,6 +406,14 @@ static unsigned int cdflags [64] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
} ; } ;


static int lineFds [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,
} ;

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,
@@ -1557,6 +1565,48 @@ int GetChipFd() {
return chipFd; return chipFd;
} }


void releaseLine(int pin) {

if (wiringPiDebug)
printf ("releaseLine: pin:%d\n", pin) ;
lineFlags[pin] = 0;
close(lineFds[pin]);
lineFds[pin] = -1;
}

int requestLine(int pin, unsigned int lineRequestFlags) {
struct gpiohandle_request rq;

if (lineFds[pin]>=0) {
if (lineRequestFlags == lineFlags[pin]) {
//already requested
return lineFds[pin];
} else {
//different request -> rerequest
releaseLine(pin);
}
}

//requested line
if (GetChipFd()<0) {
return -1; // error
}
rq.lineoffsets[0] = pin;
rq.lines = 1;
rq.flags = lineRequestFlags;
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
if (ret || rq.fd<0) {
ReportDeviceError("get line handle", pin, "RequestLine", ret);
return -1; // error
}

lineFlags[pin] = lineRequestFlags;
lineFds[pin] = rq.fd;
if (wiringPiDebug)
printf ("requestLine succeeded: pin:%d, flags: %u, fd :%d\n", pin, lineRequestFlags, lineFds[pin]) ;
return lineFds[pin];
}

/* /*
********************************************************************************* *********************************************************************************
* Core Functions * Core Functions
@@ -1636,28 +1686,17 @@ void pinModeFlagsDevice (int pin, int mode, unsigned int flags) {
case OUTPUT: case OUTPUT:
lflag |= GPIOHANDLE_REQUEST_OUTPUT; lflag |= GPIOHANDLE_REQUEST_OUTPUT;
break; break;
}
if (GetChipFd()<0) {
return; // error
case PM_OFF:
pinModeFlagsDevice(pin, INPUT, 0);
releaseLine(pin);
return;
} }


struct gpiohandle_request rq;
rq.lineoffsets[0] = pin;
rq.lines = 1;
rq.flags = lflag;
if (wiringPiDebug)
printf ("pinModeFlagsDevice: ioctl pin:%d cmd: GPIO_GET_LINEHANDLE_IOCTL, flags: %u\n", pin, lflag) ;
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
if (ret) {
ReportDeviceError("get line handle", pin, "pinMode", ret);
return; // error
}
cdflags[pin] = lflag;
close(rq.fd);
requestLine(pin, lflag);
} }


void pinModeDevice (int pin, int mode) { void pinModeDevice (int pin, int mode) {
pinModeFlagsDevice (pin, mode, cdflags[pin]);
pinModeFlagsDevice(pin, mode, lineFlags[pin]);
} }


void pinMode (int pin, int mode) void pinMode (int pin, int mode)
@@ -1684,7 +1723,8 @@ void pinMode (int pin, int mode)
pin = physToGpio [pin]; pin = physToGpio [pin];
break; break;
case WPI_MODE_GPIO_DEVICE: case WPI_MODE_GPIO_DEVICE:
return pinModeDevice(pin, mode);
pinModeDevice(pin, mode);
return;
case WPI_MODE_GPIO: case WPI_MODE_GPIO:
break; break;
} }
@@ -1727,7 +1767,7 @@ void pinMode (int pin, int mode)
{ {
RETURN_ON_MODEL5 RETURN_ON_MODEL5
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
return ;
return ;


usingGpioMemCheck ("pinMode PWM") ; usingGpioMemCheck ("pinMode PWM") ;


@@ -1744,7 +1784,7 @@ void pinMode (int pin, int mode)
{ {
RETURN_ON_MODEL5 RETURN_ON_MODEL5
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
return ;
return ;


usingGpioMemCheck ("pinMode CLOCK") ; usingGpioMemCheck ("pinMode CLOCK") ;


@@ -1770,7 +1810,7 @@ void pinMode (int pin, int mode)
********************************************************************************* *********************************************************************************
*/ */
void pullUpDnControlDevice (int pin, int pud) { void pullUpDnControlDevice (int pin, int pud) {
unsigned int flag = cdflags[pin];
unsigned int flag = lineFlags[pin];
unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN; unsigned int biasflags = GPIOHANDLE_REQUEST_BIAS_DISABLE | GPIOHANDLE_REQUEST_BIAS_PULL_UP | GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;


flag &= ~biasflags; flag &= ~biasflags;
@@ -1782,12 +1822,12 @@ void pullUpDnControlDevice (int pin, int pud) {
} }


// reset input/output // reset input/output
if (cdflags[pin] & GPIOHANDLE_REQUEST_OUTPUT) {
if (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT) {
pinModeFlagsDevice (pin, OUTPUT, flag); pinModeFlagsDevice (pin, OUTPUT, flag);
} else if(cdflags[pin] & GPIOHANDLE_REQUEST_INPUT) {
} else if(lineFlags[pin] & GPIOHANDLE_REQUEST_INPUT) {
pinModeFlagsDevice (pin, INPUT, flag); pinModeFlagsDevice (pin, INPUT, flag);
} else { } else {
cdflags[pin] = flag; // only store for later
lineFlags[pin] = flag; // only store for later
} }
} }


@@ -1865,34 +1905,30 @@ void pullUpDnControl (int pin, int pud)
} }






/* /*
* digitalRead: * digitalRead:
* Read the value of a given Pin, returning HIGH or LOW * Read the value of a given Pin, returning HIGH or LOW
********************************************************************************* *********************************************************************************
*/ */


int digitalReadDevice (int pin) {
struct gpiohandle_data data;
struct gpiohandle_request rq;
int digitalReadDevice (int pin) { // INPUT and OUTPUT should work


if (GetChipFd()<0) {
return LOW; // error
}
rq.lineoffsets[0] = pin;
rq.lines = 1;
rq.flags = GPIOHANDLE_REQUEST_INPUT;
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
if (ret) {
ReportDeviceError("get line handle", pin, "digitalRead", ret);
return LOW; // error
if (lineFds[pin]<0) {
// line not requested - auto request on first read as input
pinModeDevice(pin, INPUT);
} }
ret = ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("get line values", pin, "digitalRead", ret);
return LOW; // error
if (lineFds[pin]>=0) {
struct gpiohandle_data data;
int ret = ioctl(lineFds[pin], GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("get line values", pin, "digitalRead", ret);
return LOW; // error
}
return data.values[0];
} }
close(rq.fd);
return data.values[0];
return LOW; // error , need to request line before
} }




@@ -1969,33 +2005,27 @@ unsigned int digitalRead8 (int pin)


void digitalWriteDevice (int pin, int value) { void digitalWriteDevice (int pin, int value) {


struct gpiohandle_data data;
struct gpiohandle_request rq;

if (wiringPiDebug) if (wiringPiDebug)
printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ; printf ("digitalWriteDevice: ioctl pin:%d value: %d\n", pin, value) ;


if (GetChipFd()<0) {
return; // error
if (lineFds[pin]<0) {
// line not requested - auto request on first write as output
pinModeDevice(pin, OUTPUT);
} }
rq.lineoffsets[0] = pin;
rq.lines = 1;
rq.flags = GPIOHANDLE_REQUEST_OUTPUT;
int ret = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &rq);
if (ret && rq.fd>0) {
ReportDeviceError("get line handle", pin, "digitalWrite", ret);
return; // error
}
data.values[0] = value;
if (wiringPiDebug)
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
ret = ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("set line values", pin, "digitalWrite", ret);
return; // error
if (lineFds[pin]>=0 && (lineFlags[pin] & GPIOHANDLE_REQUEST_OUTPUT)>0) {
struct gpiohandle_data data;
data.values[0] = value;
if (wiringPiDebug)
printf ("digitalWriteDevice: ioctl pin:%d cmd: GPIOHANDLE_SET_LINE_VALUES_IOCTL, value: %d\n", pin, value) ;
int ret = ioctl(lineFds[pin], GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret) {
ReportDeviceError("set line values", pin, "digitalWrite", ret);
return; // error
}
} else {
fprintf(stderr, "digitalWrite: no output (%d)\n", lineFlags[pin]);
} }
close(rq.fd);
return;
return; // error
} }


void digitalWrite (int pin, int value) void digitalWrite (int pin, int value)


+ 1
- 0
wiringPi/wiringPi.h View File

@@ -63,6 +63,7 @@
#define SOFT_PWM_OUTPUT 4 #define SOFT_PWM_OUTPUT 4
#define SOFT_TONE_OUTPUT 5 #define SOFT_TONE_OUTPUT 5
#define PWM_TONE_OUTPUT 6 #define PWM_TONE_OUTPUT 6
#define PM_OFF 7 // to input / release line


#define LOW 0 #define LOW 0
#define HIGH 1 #define HIGH 1


Loading…
Cancel
Save