Просмотр исходного кода

Merge pull request #253 from WiringPi/develop

Release 3.6
tags/3.6
mstroh76 5 месяцев назад
committed by GitHub
Родитель
Сommit
813c3130be
Не найден GPG ключ соответствующий данной подписи Идентификатор GPG ключа: B5690EEEBB952194
23 измененных файлов: 802 добавлений и 403 удалений
  1. +1
    -1
      VERSION
  2. +6
    -3
      gpio/gpio.1
  3. +18
    -308
      gpio/gpio.c
  4. +2
    -2
      version.h
  5. +5
    -4
      wiringPi/pcf8574.c
  6. +55
    -2
      wiringPi/test/Makefile
  7. +112
    -0
      wiringPi/test/wiringpi_i2c_test1_pcf8574.c
  8. +112
    -0
      wiringPi/test/wiringpi_spi_test1_mcp3202.c
  9. +1
    -3
      wiringPi/test/wiringpi_test1_sysfs.c
  10. +1
    -3
      wiringPi/test/wiringpi_test2_sysfs.c
  11. +1
    -3
      wiringPi/test/wiringpi_test3_device_wpi.c
  12. +1
    -3
      wiringPi/test/wiringpi_test4_device_phys.c
  13. +55
    -7
      wiringPi/test/wiringpi_test5_default.c
  14. +1
    -2
      wiringPi/test/wiringpi_test6_isr.c
  15. +2
    -0
      wiringPi/test/wiringpi_test7_version.c
  16. +178
    -0
      wiringPi/test/wiringpi_xotest_test1_spi.c
  17. +97
    -25
      wiringPi/test/wpi_test.h
  18. +18
    -4
      wiringPi/wiringPi.c
  19. +20
    -0
      wiringPi/wiringPi.h
  20. +1
    -1
      wiringPi/wiringPiI2C.c
  21. +1
    -1
      wiringPi/wiringPiI2C.h
  22. +103
    -30
      wiringPi/wiringPiSPI.c
  23. +11
    -1
      wiringPi/wiringPiSPI.h

+ 1
- 1
VERSION Просмотреть файл

@@ -1 +1 @@
3.4
3.6

+ 6
- 3
gpio/gpio.1 Просмотреть файл

@@ -48,7 +48,7 @@ high | low
range
.PP
.B gpio
.B load \ i2c/spi ...
.B i2cd
.PP
.B gpio
.B gbr
@@ -67,8 +67,7 @@ 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.

It can also control the IO's on the PiFace IO board and load the SPI and I2C
kernel modules if required.
It can also control the IO's on the PiFace IO board.

.SH OPTIONS

@@ -208,6 +207,10 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional)
Change the PWM range register. The default is 1024.

.TP
.B i2cd
Executes i2c-detect for the default I2C port on the P1 connector.

.TP
.B gbr
channel



+ 18
- 308
gpio/gpio.c Просмотреть файл

@@ -72,15 +72,11 @@ char *usage = "Usage: gpio -v\n"
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
" gpio <toggle/blink> <pin>\n"
" gpio readall\n"
// " gpio unexportall/exports\n"
// " gpio export/edge/unexport ...\n"
" gpio wfi <pin> <mode>\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 unload spi/i2c\n"
" gpio i2cd/i2cdetect\n"
" gpio rbx/rbd\n"
" gpio wb <value>\n"
@@ -110,287 +106,6 @@ static int decodePin (const char *str)
#endif


/*
* findExecutable:
* Code to locate the path to the given executable. We have a fixed list
* of locations to try which completely overrides any $PATH environment.
* This may be detrimental, however it avoids the reliance on $PATH
* which may be a security issue when this program is run a set-uid-root.
*********************************************************************************
*/

static const char *searchPath [] =
{
"/sbin",
"/usr/sbin",
"/bin",
"/usr/bin",
NULL,
} ;

static char *findExecutable (const char *progName)
{
static char *path = NULL ;
int len = strlen (progName) ;
int i = 0 ;
struct stat statBuf ;

for (i = 0 ; searchPath [i] != NULL ; ++i)
{
path = malloc (strlen (searchPath [i]) + len + 2) ;
sprintf (path, "%s/%s", searchPath [i], progName) ;

if (stat (path, &statBuf) == 0)
return path ;
free (path) ;
}

return NULL ;
}


/*
* changeOwner:
* Change the ownership of the file to the real userId of the calling
* program so we can access it.
*********************************************************************************
*/

static void changeOwner (char *cmd, char *file)
{
uid_t uid = getuid () ;
uid_t gid = getgid () ;

if (chown (file, uid, gid) != 0)
{

// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that
// the warning message is an error.

if (errno != ENOENT)
fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
}
}


/*
* moduleLoaded:
* Return true/false if the supplied module is loaded
*********************************************************************************
*/

static int moduleLoaded (char *modName)
{
int len = strlen (modName) ;
int found = FALSE ;
FILE *fd = fopen ("/proc/modules", "r") ;
char line [80] ;

if (fd == NULL)
{
fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ;
exit (1) ;
}

while (fgets (line, 80, fd) != NULL)
{
if (strncmp (line, modName, len) != 0)
continue ;

found = TRUE ;
break ;
}

fclose (fd) ;

return found ;
}


/*
* doLoad:
* Load either the spi or i2c modules and change device ownerships, etc.
*********************************************************************************
*/

static void checkDevTree (char *argv [])
{
struct stat statBuf ;

if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
{
fprintf (stderr,
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
" You need to run the raspi-config program (as root) and select the\n"
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
exit (1) ;
}
}

static void _doLoadUsage (char *argv [])
{
fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
exit (1) ;
}

static void doLoad (int argc, char *argv [])
{
char *module1, *module2 ;
char cmd [80] ;
char *file1, *file2 ;
char args1 [32], args2 [32] ;

checkDevTree (argv) ;

if (argc < 3)
_doLoadUsage (argv) ;

args1 [0] = args2 [0] = 0 ;

/**/ if (strcasecmp (argv [2], "spi") == 0)
{
module1 = "spidev" ;
module2 = "spi_bcm2708" ;
file1 = "/dev/spidev0.0" ;
file2 = "/dev/spidev0.1" ;
if (argc == 4)
{
fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
exit (1) ;
}
else if (argc > 4)
_doLoadUsage (argv) ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
module1 = "i2c_dev" ;
module2 = "i2c_bcm2708" ;
file1 = "/dev/i2c-0" ;
file2 = "/dev/i2c-1" ;
if (argc == 4)
sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
else if (argc > 4)
_doLoadUsage (argv) ;
}
else
_doLoadUsage (argv) ;

if (findExecutable ("modprobe") == NULL)
printf ("No found\n") ;

if (!moduleLoaded (module1))
{
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (!moduleLoaded (module2))
{
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (!moduleLoaded (module2))
{
fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
exit (1) ;
}

sleep (1) ; // To let things get settled

changeOwner (argv [0], file1) ;
changeOwner (argv [0], file2) ;
}


/*
* doUnLoad:
* Un-Load either the spi or i2c modules and change device ownerships, etc.
*********************************************************************************
*/

static void _doUnLoadUsage (char *argv [])
{
fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
exit (1) ;
}

static void doUnLoad (int argc, char *argv [])
{
char *module1, *module2 ;
char cmd [80] ;

checkDevTree (argv) ;

if (argc != 3)
_doUnLoadUsage (argv) ;

/**/ if (strcasecmp (argv [2], "spi") == 0)
{
module1 = "spidev" ;
module2 = "spi_bcm2708" ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
module1 = "i2c_dev" ;
module2 = "i2c_bcm2708" ;
}
else
_doUnLoadUsage (argv) ;

if (moduleLoaded (module1))
{
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}

if (moduleLoaded (module2))
{
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
int ret = system(cmd);
if (ret == -1) {
perror("Error executing command");
} else if (WIFEXITED(ret)) {
int exit_status = WEXITSTATUS(ret);
if (exit_status != 0) {
fprintf(stderr, "Command failed with exit status %d\n", exit_status);
}
} else {
fprintf(stderr, "Command terminated by signal\n");
}
}
}


/*
* doI2Cdetect:
@@ -398,28 +113,19 @@ static void doUnLoad (int argc, char *argv [])
*********************************************************************************
*/

static void doI2Cdetect (UNU int argc, char *argv [])
static void doI2Cdetect (const char *progName)
{
int port = piGpioLayout () == GPIO_LAYOUT_PI1_REV1 ? 0 : 1 ;
char *c, *command ;
char command[64];

if ((c = findExecutable (I2CDETECT)) == NULL)
{
fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
return ;
snprintf(command, 64, "i2cdetect -y %d", port);
int ret = system(command);
if (ret < 0) {
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", progName, strerror(errno));
}

if (!moduleLoaded ("i2c_dev"))
{
fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
return ;
if (0x7F00 == (ret & 0xFF00)) {
fprintf (stderr, "%s: i2cdetect not found, please install i2c-tools\n", progName);
}

command = malloc (strlen (c) + 16) ;
sprintf (command, "%s -y %d", c, port) ;
if (system (command) < 0)
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;

}


@@ -427,6 +133,10 @@ void SYSFS_DEPRECATED(const char *progName) {
fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName);
}

void LOAD_DEPRECATED(const char *progName) {
fprintf(stderr, "%s: load/unload modules is deprecated. You need to run the raspi-config program (as root) and select the interface option (SPI or I2C) that you wish to de-/activate.\n\n", progName);
}

/*
* doExports: -> deprecated, removed
* List all GPIO exports
@@ -1269,7 +979,7 @@ int main (int argc, char *argv [])
exit (EXIT_FAILURE) ;
}

// Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there
// Initial test for /sys/class/gpio operations: --> deprecated, empty but still there

/**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
@@ -1277,10 +987,10 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; }

// Check for load command:
// Check for un-/load command: --> deprecated, empty but still there

if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "load" ) == 0) { LOAD_DEPRECATED(argv[0]) ; return 0 ; }
if (strcasecmp (argv [1], "unload" ) == 0) { LOAD_DEPRECATED(argv[0]) ; return 0 ; }

// Check for usb power command

@@ -1413,8 +1123,8 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ;
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argv [0]) ;
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argv [0]) ;
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;


+ 2
- 2
version.h Просмотреть файл

@@ -1,3 +1,3 @@
#define VERSION "3.4"
#define VERSION "3.6"
#define VERSION_MAJOR 3
#define VERSION_MINOR 4
#define VERSION_MINOR 6

+ 5
- 4
wiringPi/pcf8574.c Просмотреть файл

@@ -1,7 +1,7 @@
/*
* pcf8574.c:
* Extend wiringPi with the PCF8574 I2C GPIO expander chip
* Copyright (c) 2013 Gordon Henderson
* Copyright (c) 2013-2024 Gordon Henderson and contributors
***********************************************************************
* This file is part of wiringPi:
* https://github.com/WiringPi/WiringPi/
@@ -33,8 +33,9 @@

/*
* myPinMode:
* The PCF8574 is an odd chip - the pins are effectively bi-directional,
* however the pins should be drven high when used as an input pin...
* The PCF8574 is a 8-Bit I/O Expander with Open-drain output.
* The pins are effectively bi-directional,
* however the pins should be driven high when used as an input pin...
* So, we're effectively copying digitalWrite...
*********************************************************************************
*/
@@ -102,7 +103,7 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
* pcf8574Setup:
* Create a new instance of a PCF8574 I2C GPIO interface. We know it
* has 8 pins, so all we need to know here is the I2C address and the
* user-defined pin base.
* user-defined pin base. Default address (A0-A3 low) is 0x20.
*********************************************************************************
*/



+ 55
- 2
wiringPi/test/Makefile Просмотреть файл

@@ -4,7 +4,11 @@ LDFLAGS =

tests = wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_version

all: $(tests)
xotests = wiringpi_xotest_test1_spi

i2ctests = wiringpi_i2c_test1_pcf8574

all: $(tests) $(xotests) $(i2ctests)

wiringpi_test1_sysfs:
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi
@@ -27,12 +31,61 @@ wiringpi_test6_isr:
wiringpi_test7_version:
${CC} ${CFLAGS} wiringpi_test7_version.c -o wiringpi_test7_version -lwiringPi

wiringpi_xotest_test1_spi:
${CC} ${CFLAGS} wiringpi_xotest_test1_spi.c -o wiringpi_xotest_test1_spi -lwiringPi

wiringpi_i2c_test1_pcf8574:
${CC} ${CFLAGS} wiringpi_i2c_test1_pcf8574.c -o wiringpi_i2c_test1_pcf8574 -lwiringPi

test:
@error_state=false ; \
for t in $(tests) ; do \
echo === unit test: $${t} === ; \
time ./$${t}; \
if [ $$? -ne 0 ]; then \
error_state=true ; \
fi ; \
echo ; echo ; \
done ; \
if [ "$$error_state" = true ]; then \
echo "\n\e[5mSTD TEST FAILED\e[0m\n"; \
else \
echo "\n\e[5mSTD TEST SUCCESS\e[0m\n"; \
fi

xotest:
@error_state=false ; \
for t in $(tests) $(xotests) ; do \
echo === XO unit test: $${t} === ; \
time ./$${t} ; \
if [ $$? -ne 0 ]; then \
error_state=true ; \
fi ; \
echo ; echo ; \
done
if [ "$$error_state" = true ]; then \
echo "\n\e[5mSTD/XO TEST FAILED\e[0m\n"; \
else \
echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \
fi

i2ctest:
@error_state=false ; \
for t in $(tests) $(i2ctests) ; do \
echo === I2C unit test: $${t} === ; \
time ./$${t} ; \
if [ $$? -ne 0 ]; then \
error_state=true ; \
fi ; \
echo ; echo ; \
done
if [ "$$error_state" = true ]; then \
echo "\n\e[5mSTD/I2C TEST FAILED\e[0m\n"; \
else \
echo "\n\e[5mSTD/I2C TEST SUCCESS\e[0m\n"; \
fi

clean:
for t in $(tests) ; do rm -fv $${t} ; done
for t in $(tests) $(xotests) $(i2ctests) ; do \
rm -fv $${t} ; \
done

+ 112
- 0
wiringPi/test/wiringpi_i2c_test1_pcf8574.c Просмотреть файл

@@ -0,0 +1,112 @@
// WiringPi test program: I2C functions (need PCF8574)
// Compile: gcc -Wall wiringpi_i2c_test1.c -o wiringpi_i2c_test1 -lwiringPi

#include "wpi_test.h"
#include "pcf8574.h"
#include "wiringPiI2C.h"

const int pinBase = 1020;
const int i2cAdress = 0x20;

int ShowAll() {
int in;
int value = 0;

printf("pin: 0 1 2 3 4 5 6 7\nval: ");
for (int pin=0; pin<=7; ++pin) {
in = digitalRead(pinBase + pin);
printf("%d ", in);
if(in==HIGH) { value |= (0x01<<pin); }
}
printf(" = 0x%02X\n", value);
return value;
}


void testPin(const char* msg, int fd, int pin , int value) {
printf("%s:\n", msg);
int in = digitalRead(pinBase + pin);
CheckSame("digitalRead", in, value);

int expect = HIGH==value ? (0x1<<pin) : 0;
int pinmask = 0x01<<pin;
int i2cread = wiringPiI2CRead(fd);
CheckSame("wiringPiI2CRead", i2cread & pinmask, expect);
//printf("Value = 0x%X\n",i2cread);

uint8_t i2cvalue = HIGH==value ? 0x00 : 0xFF;
int result = wiringPiI2CRawRead(fd, &i2cvalue, 1);
CheckSame("wiringPiI2CRawRead result", result, 1);
CheckSame("wiringPiI2CRawRead", i2cvalue & pinmask, expect);
//printf("Value = 0x%X\n",i2cvalue);
}


int main (void) {
int major, minor;
wiringPiVersion(&major, &minor);
printf("Testing I2C functions with PCF8574 (WiringPi %d.%d)\n",major, minor);
printf("-------------------------------------------------\n\n");


int ret = pcf8574Setup (pinBase, i2cAdress);
if (ret!=1) {
FailAndExitWithErrno("pcf8574Setup", ret);
}
int fd = wiringPiI2CSetup (i2cAdress);
if (fd<=0) {
FailAndExitWithErrno("wiringPiI2CSetup", fd);
}
CheckSame("I2C fd", fd, 4);

ShowAll();

int pin = 3;
testPin("Test pin 3 high", fd, pin , HIGH);
testPin("Test pin 4 high", fd, pin+1, HIGH);

digitalWrite(pinBase + pin, LOW);
testPin("Test pin 3 low", fd, pin , LOW);
testPin("Test pin 4 high", fd, pin+1, HIGH);

ShowAll();

digitalWrite(pinBase + pin, HIGH);
testPin("Test pin 3 high", fd, pin , HIGH);
testPin("Test pin 4 high", fd, pin+1, HIGH);

ShowAll();

printf("\nwiringPiI2CReadReg8:\n");
int i2cin, expect;
i2cin = wiringPiI2CReadReg8(fd, 0x00);
expect = ShowAll();
CheckSame("all low wiringPiI2CReadReg8", i2cin, expect);

i2cin = wiringPiI2CReadReg8(fd, 0xFF);
expect =ShowAll();
CheckSame("all high wiringPiI2CReadReg8", i2cin, expect);

printf("\nwiringPiI2CReadBlockData:\n");
uint8_t value;
int result;
value = 0xFF;
result = wiringPiI2CReadBlockData(fd, 0x00, &value, 1);
CheckSame("wiringPiI2CReadBlockData result", result, 1);
expect = ShowAll();
CheckSame("all high wiringPiI2CReadBlockData", value, expect);

printf("\n");
value = 0x00;
result = wiringPiI2CReadBlockData(fd, 0xFF, &value, 1);
CheckSame("wiringPiI2CReadBlockData result", result, 1);
expect = ShowAll();
CheckSame("all low wiringPiI2CReadBlockData", value, expect);

return UnitTestState();
}





+ 112
- 0
wiringPi/test/wiringpi_spi_test1_mcp3202.c Просмотреть файл

@@ -0,0 +1,112 @@
// WiringPi test program: SPI functions (need MCP3202 hardware @ CE1, ch0=Vdd, ch1=Vdd/2)
// Compile: gcc -Wall wiringpi_spi_test1_mcp3202.c -o wiringpi_spi_test1_mcp3202 -lwiringPi

#include <unistd.h>
#include <stdint.h>
#include <signal.h>
#include <time.h>
#include "wpi_test.h"
#include <wiringPiSPI.h>

const float fRefVoltage = 3.3f;
const float fResolution = 4096; //12-Bit
const int spiChannel = 1;
const int spiSpeedInit = 250000; // Hz


int AnalogRead(int spiChannel, int analogChannel, int* returnvalue) {
if (analogChannel<0 || analogChannel>1) {
return -1;
}

unsigned char spiData[3];
unsigned char chanBits;

if (analogChannel == 0) {
chanBits = 0b11010000;
} else {
chanBits = 0b11110000;
}
spiData[0] = chanBits;
spiData[1] = 0;
spiData[2] = 0;
*returnvalue = wiringPiSPIxDataRW(0, spiChannel, spiData, 3);
return ((spiData [0] << 9) | (spiData [1] << 1) | (spiData[2] >> 7)) & 0xFFF;
}


int main(int argc, char *argv []){

int hSPI;
int CH0,CH1;
float value0, value1;
int returnvalue;
int spiSpeed;
int major, minor;

wiringPiVersion(&major, &minor);
printf("Testing SPI functions with WiringPi %d.%d\n",major, minor);
printf("------------------------------------------\n\n");

wiringPiSetup();
spiSpeed = spiSpeedInit;
for (int testno=0; testno<=2; testno++) {
printf("\nTest 5d with %g MHz SPI Speed\n", spiSpeed/1000000.0f);
if ((hSPI = wiringPiSPISetup (spiChannel, spiSpeed)) < 0) {
FailAndExitWithErrno("wiringPiSPISetup", hSPI);
}

int hSPIOld=hSPI;
//printf("\nSPI fd = %d\n call close now\n", hSPI);
int ret = wiringPiSPIClose(spiChannel);
if (ret!=0) {
FailAndExitWithErrno("wiringPiSPIClose", ret);
}

if ((hSPI = wiringPiSPIxSetupMode(0, spiChannel, spiSpeed, 0)) < 0) {
FailAndExitWithErrno("wiringPiSPIxSetup", hSPI);
}

CheckSame("SPISetup, Close and SPIxSetup handle", hSPI, hSPIOld);
delayMicroseconds(500000);
returnvalue = -1;
CH0 = AnalogRead(spiChannel, 0, &returnvalue);
CheckSame("CH0 wiringPiSPIxDataRW return", returnvalue, 3);
value0 = CH0 * fRefVoltage / fResolution;
CheckSameFloat("CH0 value (VDD)", value0, 3.3f);
printf("\n");
delayMicroseconds(500000);
returnvalue = -1;
CH1 = AnalogRead(spiChannel, 1, &returnvalue);
CheckSame("CH1 wiringPiSPIxDataRW return", returnvalue, 3);
value1 = CH1 * fRefVoltage / fResolution;
CheckSameFloat("CH1 value (1/2)", value1, 1.65f);
printf("\n");

ret = wiringPiSPIxClose(0, spiChannel);
CheckSame("wiringPiSPIxClose result", ret, 0);
if (ret!=0) {
FailAndExitWithErrno("wiringPiSPIxClose", ret);
}
ret = wiringPiSPIxGetFd(0, spiChannel);
CheckSame("Fd after wiringPiSPIxGetFd", ret, -1);

ret = wiringPiSPIGetFd(spiChannel);
CheckSame("Fd after wiringPiSPIGetFd", ret, -1);

spiSpeed += spiSpeed;
}

printf("\n");
hSPI = wiringPiSPISetup (3, spiSpeedInit);
CheckSame("\nwiringPiSPISetup with wrong channel", hSPI, -22);

// will result in exit! - not useful in test code
//hSPI = wiringPiSPIxSetupMode (3, 0, spiSpeedInit,0);
//CheckSame("\nwiringPiSPISetup with wrong channel", hSPI, -22);

return UnitTestState();
}


+ 1
- 3
wiringPi/test/wiringpi_test1_sysfs.c Просмотреть файл

@@ -2,9 +2,7 @@
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

@@ -52,6 +50,6 @@ int main (void) {
//Error wrong direction - only for fun
digitalWrite(GPIO, LOW);

return(EXIT_SUCCESS);
return UnitTestState();
}


+ 1
- 3
wiringPi/test/wiringpi_test2_sysfs.c Просмотреть файл

@@ -2,9 +2,7 @@
// Compile: gcc -Wall wiringpi_test2_device.c -o wiringpi_test2_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

@@ -50,5 +48,5 @@ int main (void) {
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
return UnitTestState();
}

+ 1
- 3
wiringPi/test/wiringpi_test3_device_wpi.c Просмотреть файл

@@ -2,9 +2,7 @@
// Compile: gcc -Wall wiringpi_test3_device.c -o wiringpi_test3_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

@@ -50,5 +48,5 @@ int main (void) {
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
return UnitTestState();
}

+ 1
- 3
wiringPi/test/wiringpi_test4_device_phys.c Просмотреть файл

@@ -2,9 +2,7 @@
// Compile: gcc -Wall wiringpi_test4_device.c -o wiringpi_test4_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

@@ -50,5 +48,5 @@ int main (void) {
CheckGPIO(GPIO, GPIOIN, LOW);
delayMicroseconds(600000);

return(EXIT_SUCCESS);
return UnitTestState();
}

+ 55
- 7
wiringPi/test/wiringpi_test5_default.c Просмотреть файл

@@ -2,9 +2,7 @@
// Compile: gcc -Wall wiringpi_test1_device.c -o wiringpi_test1_device -lwiringPi

#include "wpi_test.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

@@ -12,6 +10,34 @@
const int GPIO = 19;
const int GPIOIN = 26;
const int ToggleValue = 4;
int RaspberryPiModel = -1;


void SetAndCheckMode(int pin, int mode) {
enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN;

switch(mode) {
case INPUT:
pinMode(pin, INPUT);
AltGpio = getPinModeAlt(pin);
CheckSame("Pin mode input", AltGpio, WPI_ALT_INPUT);
break;
case OUTPUT:
pinMode(pin, OUTPUT);
AltGpio = getPinModeAlt(pin);
CheckSame("Pin mode output", AltGpio, WPI_ALT_OUTPUT);
break;
case PM_OFF:
pinMode(pin, PM_OFF);
AltGpio = getPinModeAlt(pin);
CheckSame("Pin mode off(input)", AltGpio, (PI_MODEL_5 == RaspberryPiModel) ? WPI_NONE : WPI_ALT_INPUT);
break;
default:
pinMode(pin, mode);
printf("pinmode %d of pin %d not checked", mode, pin);
break;
}
}


int main (void) {
@@ -23,8 +49,23 @@ int main (void) {
printf("wiringPiSetupGpio failed\n\n");
exit(EXIT_FAILURE);
}
pinMode(GPIOIN, INPUT);
pinMode(GPIO, OUTPUT);

int rev, mem, maker, overVolted;
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
CheckNotSame("Model: ", RaspberryPiModel, -1);
if (PI_MODEL_5 == RaspberryPiModel) {
printf("Raspberry Pi 5 with RP1 found\n");
} else {
printf("Raspberry Pi with BCM GPIO found (not Pi 5)\n");
}


enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN;
AltGpio = getPinModeAlt(23);
CheckSame("Pin mode default", AltGpio, PI_MODEL_5 == RaspberryPiModel ? WPI_NONE : WPI_ALT_INPUT);

SetAndCheckMode(GPIOIN, INPUT);
SetAndCheckMode(GPIO, OUTPUT);

printf("toggle %d times ...\n", ToggleValue);
for (int loop=1; loop<ToggleValue; loop++) {
@@ -38,7 +79,9 @@ int main (void) {

printf("\nWiringPi GPIO test program (using GPIO%d (input pull up/down) and GPIO%d (input))\n", GPIO, GPIOIN);
pullUpDnControl (GPIO, PUD_UP);
pinMode(GPIO, INPUT);
SetAndCheckMode(GPIO, INPUT);


delayMicroseconds(3000000);
pullUpDnControl (GPIOIN, PUD_OFF);

@@ -52,6 +95,11 @@ int main (void) {
//Error wrong direction - only for fun
digitalWrite(GPIO, LOW);

return(EXIT_SUCCESS);
}
SetAndCheckMode(GPIO, OUTPUT);
SetAndCheckMode(GPIO, PM_OFF);
//pinModeAlt (GPIO, 0x1F);
//AltGpio = getPinModeAlt(GPIO);
//CheckSame("Pin mode off(default)", AltGpio, 0x1F);

return UnitTestState();
}

+ 1
- 2
wiringPi/test/wiringpi_test6_isr.c Просмотреть файл

@@ -4,7 +4,6 @@
#include "wpi_test.h"
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

@@ -166,5 +165,5 @@ int main (void) {
}
pinMode(OUTpin, INPUT);

return 0 ;
return UnitTestState();
}

+ 2
- 0
wiringPi/test/wiringpi_test7_version.c Просмотреть файл

@@ -8,4 +8,6 @@ int main (void) {

CheckSame("version major", major, VERSION_MAJOR);
CheckSame("version minor", minor, VERSION_MINOR);

return UnitTestState();
}

+ 178
- 0
wiringPi/test/wiringpi_xotest_test1_spi.c Просмотреть файл

@@ -0,0 +1,178 @@
// WiringPi test program: SPI functions (need XO hardware)
// Compile: gcc -Wall wiringpi_xotest_test1_spi.c -o wiringpi_xotest_test1_spi -lwiringPi

#include <unistd.h>
#include <stdint.h>
#include <signal.h>
#include <time.h>
#include "wpi_test.h"
#include <wiringPiSPI.h>

#define TRUE (1==1)
#define FALSE (!TRUE)
#define CHAN_CONFIG_SINGLE 8
#define CHAN_CONFIG_DIFF 0

const float fRefVoltage = 3.3f;
const float fResolution = 4096; //12-Bit
const int spiChannel = 1;
const int spiSpeed = 1000000; // MHz



int AnalogRead(int spiChannel, int analogChannel, int* returnvalue) {
if (analogChannel<0 || analogChannel>1) {
return -1;
}

unsigned char spiData[3];
unsigned char chanBits;

if (analogChannel == 0) {
chanBits = 0b11010000;
} else {
chanBits = 0b11110000;
}
spiData[0] = chanBits;
spiData[1] = 0;
spiData[2] = 0;
*returnvalue = wiringPiSPIxDataRW(0, spiChannel, spiData, 3);
return ((spiData [0] << 9) | (spiData [1] << 1) | (spiData[2] >> 7)) & 0xFFF;
}

void checkVoltage(float expect, const char* szexpect) {
int returnvalue;

//int CH0 = AnalogRead(spiChannel, 0, &returnvalue);
int CH1 = AnalogRead(spiChannel, 1, &returnvalue);
//float value0 = CH0 * fRefVoltage / fResolution;
float value1 = CH1 * fRefVoltage / fResolution;
CheckSameFloat(szexpect, value1, expect);
delayMicroseconds(300);
}


int main(int argc, char *argv []){

const int GPIOIn = 29;
int hSPI;
//int CH0;
int CH1;
int major, minor;

wiringPiVersion(&major, &minor);
printf("Testing SPI functions with WiringPi %d.%d\n",major, minor);
printf("------------------------------------------\n\n");

wiringPiSetup();

if ((hSPI = wiringPiSPISetup (spiChannel, spiSpeed)) < 0) {
FailAndExitWithErrno("wiringPiSPISetup", hSPI);
}

int hSPIOld=hSPI;
//printf("\nSPI fd = %d\n call close now\n", hSPI);
int ret = wiringPiSPIClose(spiChannel);
if (ret!=0) {
FailAndExitWithErrno("wiringPiSPIClose", ret);
}

if ((hSPI = wiringPiSPIxSetupMode(0, spiChannel, spiSpeed, 0)) < 0) {
FailAndExitWithErrno("wiringPiSPIxSetup", hSPI);
}

CheckSame("SPISetup, Close and SPIxSetup handle", hSPI, hSPIOld);

int returnvalue;
//CH0 = AnalogRead(spiChannel, 0, &returnvalue);
CH1 = AnalogRead(spiChannel, 1, &returnvalue);
CheckSame("SPI reading ioctl result (byte count) ", returnvalue, 3);
//float value0 = CH0 * fRefVoltage / fResolution;
//float value1 = CH1 * fRefVoltage / fResolution;

pinMode(21, OUTPUT);
pinMode(22, INPUT);
pinMode(24, INPUT);
pinMode(25, INPUT);
pinMode(27, INPUT);
pinMode(28, INPUT);
pinMode(GPIOIn, INPUT);


digitalWriteEx(21, GPIOIn, LOW);
checkVoltage(0.1f, "Analog value 1xLow");
checkVoltage(0.1f, "Analog value 1xLow");

digitalWriteEx(21, GPIOIn, HIGH);
checkVoltage(3.1f, "Analog value 1xHigh");

pinMode(22, OUTPUT);
digitalWriteEx(22, -1, LOW);
checkVoltage(1.65f, "Analog value Half (1H/1L)");

digitalWriteEx(22, GPIOIn, HIGH);
checkVoltage(3.2f, "Analog value 2xHigh");

pinMode(24, OUTPUT);
digitalWriteEx(24, GPIOIn, HIGH);
checkVoltage(3.2f, "Analog value 3xHigh");

digitalWriteEx(24, -1, LOW);
checkVoltage(2.2f, "Analog value 2xHigh/1xLow");
checkVoltage(2.2f, "Analog value 2xHigh/1xLow");

pinMode(25, OUTPUT);
digitalWriteEx(25, GPIOIn, HIGH);
checkVoltage(2.475f, "Analog value 3xHigh/1xLow");

digitalWriteEx(25, -1, LOW);
checkVoltage(1.65f, "Analog value Half (2H/2L)");

pinMode(27, OUTPUT);
digitalWriteEx(27, GPIOIn, HIGH);
checkVoltage(1.98f, "Analog value 3xHigh/2xLow");

digitalWriteEx(27, -1, LOW);
checkVoltage(1.32f, "Analog value Half (2H/3L)");

pinMode(28, OUTPUT);
digitalWriteEx(28, GPIOIn, LOW);
checkVoltage(1.100f, "Analog value 2xHigh/4xLow");

digitalWriteEx(28, GPIOIn, HIGH);
checkVoltage(1.65f, "Analog value Half (3H/3L)");

digitalWriteEx(27, GPIOIn, HIGH);
checkVoltage(2.2f, "Analog value 4xHigh/2xLow");

digitalWriteEx(25, GPIOIn, HIGH);
checkVoltage(2.75f, "Analog value 5xHigh/1xLow");

digitalWriteEx(24, GPIOIn, HIGH);
checkVoltage(3.3f, "Analog value 6xHigh");

CH1 = AnalogRead(3, 1, &returnvalue);
CheckSame("\nReading Wrong channel 3 result ", CH1, 0);
CheckSame("\nReading Wrong channel 3 ioctl result ", returnvalue, -EINVAL);
CH1 = AnalogRead(2, 1, &returnvalue);
CheckSame("\nReading Wrong channel 2 result ", CH1, 0);
CheckSame("\nReading Wrong channel 3 ioctl result ", returnvalue, -EBADF);

pinMode(22, INPUT);
pinMode(21, INPUT);
pinMode(24, INPUT);
pinMode(25, INPUT);
pinMode(27, INPUT);
pinMode(28, INPUT);

ret = wiringPiSPIxClose(0, spiChannel);
CheckSame("wiringPiSPIxClose result", ret, 0);
if (ret!=0) {
FailAndExitWithErrno("wiringPiSPIxClose", ret);
}
ret = wiringPiSPIxGetFd(0, spiChannel);
CheckSame("Fd after close", ret, -1);

return UnitTestState();
}


+ 97
- 25
wiringPi/test/wpi_test.h Просмотреть файл

@@ -1,48 +1,120 @@

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
#include <string.h>

#define COLORDEF "\x1B[0m"
#define COLORRED "\x1B[31m"
#define COLORGRN "\x1B[32m"
#define BOLD "\x1B[1m"
#define FINALCOLRED "\x1B[7;49;91m"
#define FINALCOLGRN "\x1B[7;49;32m"


unsigned int globalError = 0;

void CheckGPIO(int GPIO, int GPIOIN, int out) {
int in = digitalRead(GPIOIN);
int read = digitalRead(GPIO);

int pass = 0;
if (out==in && in==read) {
pass = 1;
}
if (pass) {
printf("GPIO%d = %d (GPIO%d = %d) -> %spassed%s\n", GPIOIN, in, GPIO, read, COLORGRN, COLORDEF );
} else {
printf("GPIO%d = %d (GPIO%d = %d) -> %sfailed%s\n", GPIOIN, in, GPIO, read, COLORRED, COLORDEF );
}
int in = out;
if (GPIOIN>=0) {
in = digitalRead(GPIOIN);
}
int readback = digitalRead(GPIO);

int pass = 0;
if (out==readback && in==out) {
pass = 1;
}

if (GPIOIN>=0) {
printf("set GPIO%02d = %d (readback %d), in GPIO%02d = %d ", GPIO, out, readback, GPIOIN, in);
} else {
printf("set GPIO%02d = %d (readback %d) ", GPIO, out, readback);
}

if (pass) {
printf("-> %spassed%s\n", COLORGRN, COLORDEF );
} else {
globalError=1;
printf("-> %sfailed%s\n", COLORRED, COLORDEF );
}
}


void digitalWriteEx(int GPIO, int GPIOIN, int mode) {
digitalWrite(GPIO, mode);
printf("out = %d ", mode);
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, mode);
digitalWrite(GPIO, mode);
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, mode);
}


void pullUpDnControlEx (int GPIO, int GPIOIN, int mode) {
pullUpDnControl (GPIO, mode);
int out = mode==PUD_UP ? 1:0;
printf("in = %4s ", mode==PUD_UP ? "up":"down");
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, out);
pullUpDnControl (GPIO, mode);
int out = mode==PUD_UP ? 1:0;
printf("in = %4s ", mode==PUD_UP ? "up":"down");
delayMicroseconds(5000);
CheckGPIO(GPIO, GPIOIN, out);
}


void CheckSameText(const char* msg, const char* value, const char* expect) {
if (!strcmp(value, expect)) {
printf("%39s (%10s==%10s) -> %spassed%s\n", msg, value, expect, COLORGRN, COLORDEF);
} else {
printf("%39s (%10s<>%10s) -> %sfailed%s\n", msg, value, expect, COLORRED, COLORDEF);
globalError=1;
}
}


void CheckSame(const char* msg, int value, int expect) {
if (value==expect) {
printf("%s -> %spassed%s\n", msg, COLORGRN, COLORDEF );
} else {
printf("%s -> %sfailed%s\n", msg, COLORRED, COLORDEF );
}
if (value==expect) {
printf("%39s (% 3d==% 3d) -> %spassed%s\n", msg, value, expect, COLORGRN, COLORDEF);
} else {
printf("%39s (% 3d<>% 3d) -> %sfailed%s\n", msg, value, expect, COLORRED, COLORDEF);
globalError=1;
}
}


void CheckNotSame(const char* msg, int value, int expect) {
if (value!=expect) {
printf("%39s (% 3d<>% 3d) -> %spassed%s\n", msg, value, expect, COLORGRN, COLORDEF);
} else {
printf("%39s (% 3d==% 3d) -> %sfailed%s\n", msg, value, expect, COLORRED, COLORDEF);
globalError=1;
}
}


void CheckSameFloat(const char* msg, float value, float expect) {
if (fabs(value-expect)<0.08) {
printf("%35s (%.3f==%.3f) -> %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF);
} else {
printf("%35s (%.3f<>%.3f) -> %sfailed%s \n" , msg, value, expect, COLORRED, COLORDEF);
globalError=1;
}
}


int UnitTestState() {
printf("\n\nUNIT TEST STATE: ");
if (globalError) {
printf(" %sFAILED%s\n\n", FINALCOLRED, COLORDEF);
return EXIT_FAILURE;
} else {
printf(" %sPASSED%s\n\n", FINALCOLGRN, COLORDEF);
return EXIT_SUCCESS;
}
}


void FailAndExitWithErrno(const char* msg, int ret) {
printf("%s (Return=%d, Err: %s) -> %sfailed%s \n" , msg, ret, strerror(errno), COLORRED, COLORDEF);
globalError=1;
exit(UnitTestState());
}


+ 18
- 4
wiringPi/wiringPi.c Просмотреть файл

@@ -156,8 +156,12 @@ const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4;
const unsigned int RP1_DEBOUNCE_MASK = 0x7f;
const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5);

const unsigned int RP1_IRQRESET = 0x10000000; //CTRL Bit 28

const unsigned int RP1_PAD_DEFAULT_0TO8 = (0x0B | 0x70); //Slewfast, Schmitt, PullUp, | 12mA, Input enable
const unsigned int RP1_PAD_DEFAULT_FROM9 = (0x07 | 0x70); //Slewfast, Schmitt, PullDown, | 12mA, Input enable
const unsigned int RP1_PAD_IC_DEFAULT_0TO8 = 0x9A; //pull-up, Schmitt
const unsigned int RP1_PAD_IC_DEFAULT_FROM9 = 0x96; //pull-down, Schmitt

const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030;
const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK);
@@ -1314,6 +1318,11 @@ int getAlt (int pin)
}


enum WPIPinAlt getPinModeAlt(int pin) {
return (enum WPIPinAlt) getAlt(pin);
}


/*
* pwmSetMode:
* Select the native "balanced" mode, or standard mark:space mode
@@ -1727,11 +1736,16 @@ void pinMode (int pin, int mode)
fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;

if (mode == INPUT) {
if (INPUT==mode || PM_OFF==mode) {
if (PI_MODEL_5 == RaspberryPiModel) {
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9;
gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO
rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input
if (INPUT==mode) {
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9;
gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO
rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input
} else { //PM_OFF
pads[1+pin] = (pin<=8) ? RP1_PAD_IC_DEFAULT_0TO8 : RP1_PAD_IC_DEFAULT_FROM9;
gpio[2*pin+1] = RP1_IRQRESET | RP1_FSEL_NONE_HW | RP1_DEBOUNCE_DEFAULT; // default but with irq reset
}
} else {
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
}


+ 20
- 0
wiringPi/wiringPi.h Просмотреть файл

@@ -225,8 +225,28 @@ extern int wiringPiSetupPhys (void) ;
extern int wiringPiSetupPinType (enum WPIPinType pinType); //Interface V3.3
extern int wiringPiSetupGpioDevice(enum WPIPinType pinType); //Interface V3.3


enum WPIPinAlt {
WPI_ALT_UNKNOWN = -1,
WPI_ALT_INPUT = 0,
WPI_ALT_OUTPUT,
WPI_ALT5,
WPI_ALT4,
WPI_ALT0,
WPI_ALT1,
WPI_ALT2,
WPI_ALT3,
WPI_ALT6,
WPI_ALT7,
WPI_ALT8,
WPI_ALT9,
WPI_NONE = 0x1F, // Pi5 default
};


extern int wiringPiGpioDeviceGetFd(); //Interface V3.3
extern void pinModeAlt (int pin, int mode) ;
extern enum WPIPinAlt getPinModeAlt (int pin) ; // Interface V3.5, same as getAlt but wie enum
extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ;
extern int digitalRead (int pin) ;


+ 1
- 1
wiringPi/wiringPiI2C.c Просмотреть файл

@@ -1,7 +1,7 @@
/*
* wiringPiI2C.c:
* Simplified I2C access routines
* Copyright (c) 2013 Gordon Henderson
* Copyright (c) 2013-2024 Gordon Henderson and contributors
***********************************************************************
* This file is part of wiringPi:
* https://github.com/WiringPi/WiringPi/


+ 1
- 1
wiringPi/wiringPiI2C.h Просмотреть файл

@@ -1,7 +1,7 @@
/*
* wiringPiI2C.h:
* Simplified I2C access routines
* Copyright (c) 2013 Gordon Henderson
* Copyright (c) 2013-2024 Gordon Henderson and contributors
***********************************************************************
* This file is part of wiringPi:
* https://github.com/WiringPi/WiringPi/


+ 103
- 30
wiringPi/wiringPiSPI.c Просмотреть файл

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


#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
@@ -32,9 +33,7 @@
#include <sys/ioctl.h>
#include <asm/ioctl.h>
#include <linux/spi/spidev.h>

#include "wiringPi.h"

#include "wiringPiSPI.h"


@@ -45,10 +44,49 @@
//static const char *spiDev1 = "/dev/spidev0.1" ;
static const uint8_t spiBPW = 8 ;
static const uint16_t spiDelay = 0 ;
//https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf
const uint8_t WPI_MaxSPINumbers = 7 ;
const uint8_t WPI_MaxSPIChannels = 3 ;


static uint32_t spiSpeeds [7][3] =
{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
};

static int spiFds [7][3] =
{
{-1, -1, -1},
{-1, -1, -1},
{-1, -1, -1},
{-1, -1, -1},
{-1, -1, -1},
{-1, -1, -1},
{-1, -1, -1},
};


int SPICheckLimits(const int number, const int channel) {
if (channel<0 || channel>=WPI_MaxSPIChannels) {
fprintf (stderr, "wiringPiSPI: Invalid SPI channel (%d, valid range 0-%d)", channel, WPI_MaxSPIChannels-1);
return -EINVAL;
}
if (number<0 || number>=WPI_MaxSPINumbers) {
fprintf (stderr, "wiringPiSPI: Invalid SPI number (%d, valid range 0-%d)", number, WPI_MaxSPINumbers-1);
return -EINVAL;
}

return 0; //sucess
}

static uint32_t spiSpeeds [2] ;
static int spiFds [2] ;

#define RETURN_ON_LIMIT_FAIL int ret = SPICheckLimits(number, channel); if(ret!=0) { return ret; };

/*
* wiringPiSPIGetFd:
@@ -56,9 +94,16 @@ static int spiFds [2] ;
*********************************************************************************
*/

int wiringPiSPIGetFd (int channel)
int wiringPiSPIxGetFd(const int number, int channel)
{
return spiFds [channel & 1] ;
if (SPICheckLimits(number, channel)!=0) {
return -1;
}
return spiFds[number][channel];
}

int wiringPiSPIGetFd(int channel) {
return wiringPiSPIxGetFd(0, channel);
}


@@ -71,27 +116,33 @@ int wiringPiSPIGetFd (int channel)
*********************************************************************************
*/

int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
int wiringPiSPIxDataRW (const int number, const int channel, unsigned char *data, const int len)
{
struct spi_ioc_transfer spi ;

channel &= 1 ;
RETURN_ON_LIMIT_FAIL
if (-1==spiFds[number][channel]) {
fprintf (stderr, "wiringPiSPI: Invalid SPI number/channel (need wiringPiSPIxSetupMode before read/write)");
return -EBADF;
}

struct spi_ioc_transfer spi ;
// Mentioned in spidev.h but not used in the original kernel documentation
// test program )-:

memset (&spi, 0, sizeof (spi)) ;

spi.tx_buf = (unsigned long)data ;
spi.rx_buf = (unsigned long)data ;
spi.len = len ;
spi.delay_usecs = spiDelay ;
spi.speed_hz = spiSpeeds [channel] ;
spi.speed_hz = spiSpeeds [number][channel] ;
spi.bits_per_word = spiBPW ;

return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ;
return ioctl (spiFds[number][channel], SPI_IOC_MESSAGE(1), &spi) ;
}

int wiringPiSPIDataRW (int channel, unsigned char *data, int len) {
return wiringPiSPIxDataRW(0, channel, data, len);
}

/*
* wiringPiSPISetupMode:
@@ -99,46 +150,68 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
*********************************************************************************
*/

int wiringPiSPISetupMode (int channel, int speed, int mode)

int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode)
{
int fd ;
char spiDev [32] ;

mode &= 3 ; // Mode is 0, 1, 2 or 3
RETURN_ON_LIMIT_FAIL
if (mode<0 || mode>3) { // Mode is 0, 1, 2 or 3 original
fprintf (stderr, "wiringPiSPI: Invalid mode (%d, valid range 0-%d)", mode, 3);
return -EINVAL;
}

// Channel can be anything - lets hope for the best
// channel &= 1 ; // Channel is 0 or 1

snprintf (spiDev, 31, "/dev/spidev0.%d", channel) ;

if ((fd = open (spiDev, O_RDWR)) < 0)
return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ;

spiSpeeds [channel] = speed ;
spiFds [channel] = fd ;
snprintf (spiDev, 31, "/dev/spidev%d.%d", number, channel) ;
if ((fd = open (spiDev, O_RDWR)) < 0) {
return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device %s: %s\n", spiDev, strerror (errno)) ;
}
spiSpeeds [number][channel] = speed ;
spiFds [number][channel] = fd ;

// Set SPI parameters.

if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0)
return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ;
return wiringPiFailure (WPI_ALMOST, "SPI mode change failure: %s\n", strerror (errno)) ;
if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
return wiringPiFailure (WPI_ALMOST, "SPI BPW Change failure: %s\n", strerror (errno)) ;
return wiringPiFailure (WPI_ALMOST, "SPI BPW change failure: %s\n", strerror (errno)) ;

if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ;
return wiringPiFailure (WPI_ALMOST, "SPI speed change failure: %s\n", strerror (errno)) ;

return fd ;
}


int wiringPiSPISetupMode (int channel, int speed, int mode) {
return wiringPiSPIxSetupMode (0, channel, speed, mode);
}


/*
* wiringPiSPISetup:
* Open the SPI device, and set it up, etc. in the default MODE 0
*********************************************************************************
*/

int wiringPiSPISetup (int channel, int speed)
{
return wiringPiSPISetupMode (channel, speed, 0) ;
int wiringPiSPISetup (int channel, int speed) {
return wiringPiSPIxSetupMode(0, channel, speed, 0) ;
}


int wiringPiSPIxClose (const int number, const int channel) {

RETURN_ON_LIMIT_FAIL
if (spiFds[number][channel]>0) {
ret = close(spiFds[number][channel]);
}
spiSpeeds [number][channel] = 0 ;
spiFds [number][channel] = -1 ;
return ret;
}

int wiringPiSPIClose (const int channel) {
return wiringPiSPIxClose (0, channel);
}


+ 11
- 1
wiringPi/wiringPiSPI.h Просмотреть файл

@@ -1,7 +1,7 @@
/*
* wiringPiSPI.h:
* Simplified SPI access routines
* Copyright (c) 2012-2015 Gordon Henderson
* Copyright (c) 2012-2024 Gordon Henderson and contributors
***********************************************************************
* This file is part of wiringPi:
* https://github.com/WiringPi/WiringPi/
@@ -26,10 +26,20 @@
extern "C" {
#endif



int wiringPiSPIGetFd (int channel) ;
int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
int wiringPiSPISetupMode (int channel, int speed, int mode) ;
int wiringPiSPISetup (int channel, int speed) ;
int wiringPiSPIClose (const int channel); //Interface 3.5

//Interface 3.5
int wiringPiSPIxGetFd (const int number, const int channel) ;
int wiringPiSPIxDataRW (const int number, const int channel, unsigned char *data, const int len) ;
int wiringPiSPIxSetupMode (const int number, const int channel, const int speed, const int mode) ;
int wiringPiSPIxSetup (const int number, const int channel, const int speed) ;
int wiringPiSPIxClose (const int number, const int channel);

#ifdef __cplusplus
}


Загрузка…
Отмена
Сохранить