@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* pcf8574.c: | * pcf8574.c: | ||||
* Extend wiringPi with the PCF8574 I2C GPIO expander chip | * 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: | * This file is part of wiringPi: | ||||
* https://github.com/WiringPi/WiringPi/ | * https://github.com/WiringPi/WiringPi/ | ||||
@@ -33,8 +33,9 @@ | |||||
/* | /* | ||||
* myPinMode: | * 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... | * So, we're effectively copying digitalWrite... | ||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -102,7 +103,7 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) | |||||
* pcf8574Setup: | * pcf8574Setup: | ||||
* Create a new instance of a PCF8574 I2C GPIO interface. We know it | * 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 | * 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. | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -6,7 +6,9 @@ tests = wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiri | |||||
xotests = wiringpi_xotest_test1_spi | xotests = wiringpi_xotest_test1_spi | ||||
all: $(tests) $(xotests) | |||||
i2ctests = wiringpi_i2c_test1_pcf8574 | |||||
all: $(tests) $(xotests) $(i2ctests) | |||||
wiringpi_test1_sysfs: | wiringpi_test1_sysfs: | ||||
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi | ${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi | ||||
@@ -32,6 +34,9 @@ wiringpi_test7_version: | |||||
wiringpi_xotest_test1_spi: | wiringpi_xotest_test1_spi: | ||||
${CC} ${CFLAGS} wiringpi_xotest_test1_spi.c -o wiringpi_xotest_test1_spi -lwiringPi | ${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: | test: | ||||
@error_state=false ; \ | @error_state=false ; \ | ||||
for t in $(tests) ; do \ | for t in $(tests) ; do \ | ||||
@@ -51,7 +56,7 @@ test: | |||||
xotest: | xotest: | ||||
@error_state=false ; \ | @error_state=false ; \ | ||||
for t in $(tests) $(xotests) ; do \ | for t in $(tests) $(xotests) ; do \ | ||||
echo === unit test: $${t} === ; \ | |||||
echo === XO unit test: $${t} === ; \ | |||||
time ./$${t} ; \ | time ./$${t} ; \ | ||||
if [ $$? -ne 0 ]; then \ | if [ $$? -ne 0 ]; then \ | ||||
error_state=true ; \ | error_state=true ; \ | ||||
@@ -64,7 +69,23 @@ xotest: | |||||
echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \ | echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \ | ||||
fi | 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: | clean: | ||||
for t in $(tests) $(xotests) ; do \ | |||||
for t in $(tests) $(xotests) $(i2ctests) ; do \ | |||||
rm -fv $${t} ; \ | rm -fv $${t} ; \ | ||||
done | done |
@@ -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(); | |||||
} | |||||