Browse Source

Merge pull request #247 from WiringPi/spi

Spi
pull/253/head
Manfred Wallner 5 months ago
committed by GitHub
parent
commit
f13424de41
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
21 changed files with 778 additions and 92 deletions
  1. +1
    -1
      VERSION
  2. +2
    -2
      version.h
  3. +5
    -4
      wiringPi/pcf8574.c
  4. +55
    -2
      wiringPi/test/Makefile
  5. +112
    -0
      wiringPi/test/wiringpi_i2c_test1_pcf8574.c
  6. +112
    -0
      wiringPi/test/wiringpi_spi_test1_mcp3202.c
  7. +1
    -3
      wiringPi/test/wiringpi_test1_sysfs.c
  8. +1
    -3
      wiringPi/test/wiringpi_test2_sysfs.c
  9. +1
    -3
      wiringPi/test/wiringpi_test3_device_wpi.c
  10. +1
    -3
      wiringPi/test/wiringpi_test4_device_phys.c
  11. +55
    -7
      wiringPi/test/wiringpi_test5_default.c
  12. +1
    -2
      wiringPi/test/wiringpi_test6_isr.c
  13. +2
    -0
      wiringPi/test/wiringpi_test7_version.c
  14. +178
    -0
      wiringPi/test/wiringpi_xotest_test1_spi.c
  15. +97
    -25
      wiringPi/test/wpi_test.h
  16. +18
    -4
      wiringPi/wiringPi.c
  17. +20
    -0
      wiringPi/wiringPi.h
  18. +1
    -1
      wiringPi/wiringPiI2C.c
  19. +1
    -1
      wiringPi/wiringPiI2C.h
  20. +103
    -30
      wiringPi/wiringPiSPI.c
  21. +11
    -1
      wiringPi/wiringPiSPI.h

+ 1
- 1
VERSION View File

@@ -1 +1 @@
3.5
3.6

+ 2
- 2
version.h View File

@@ -1,3 +1,3 @@
#define VERSION "3.5"
#define VERSION "3.6"
#define VERSION_MAJOR 3
#define VERSION_MINOR 5
#define VERSION_MINOR 6

+ 5
- 4
wiringPi/pcf8574.c View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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
}


Loading…
Cancel
Save