@@ -816,7 +816,7 @@ static void doPwmClock (int argc, char *argv [])
|
||||
|
||||
if ((clock < 1) || (clock > 4095))
|
||||
{
|
||||
fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
|
||||
fprintf (stderr, "%s: pwm clock must be between 1 and 4095\n", argv [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#define VERSION "3.6"
|
||||
#define VERSION "3.7"
|
||||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 6
|
||||
#define VERSION_MINOR 7
|
||||
|
||||
@@ -1,47 +1,64 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall
|
||||
LDFLAGS =
|
||||
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
|
||||
# Need BCM19 <-> BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm)
|
||||
tests = wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_version wiringpi_test8_pwm wiringpi_test9_pwm
|
||||
|
||||
xotests = wiringpi_xotest_test1_spi
|
||||
# Need XO hardware
|
||||
xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm
|
||||
|
||||
i2ctests = wiringpi_i2c_test1_pcf8574
|
||||
# Need PiFace hardware and BCM23 <-> BCM24 , BCM18 <-> BCM17 connected (1kOhm), and PiFace Out7<->In4, Out6<->In5, R0_NO<->In6, R0_NO<->In7, R_C<-100Ohm->GND
|
||||
pifacetests = wiringpi_piface_test1 wiringpi_test8_pwm wiringpi_test9_pwm
|
||||
|
||||
all: $(tests) $(xotests) $(i2ctests)
|
||||
all: $(tests) $(xotests) $(pifacetests)
|
||||
|
||||
wiringpi_test1_sysfs:
|
||||
wiringpi_test1_sysfs:
|
||||
${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi
|
||||
|
||||
wiringpi_test2_sysfs:
|
||||
wiringpi_test2_sysfs:
|
||||
${CC} ${CFLAGS} wiringpi_test2_sysfs.c -o wiringpi_test2_sysfs -lwiringPi
|
||||
|
||||
wiringpi_test3_device_wpi:
|
||||
wiringpi_test3_device_wpi:
|
||||
${CC} ${CFLAGS} wiringpi_test3_device_wpi.c -o wiringpi_test3_device_wpi -lwiringPi
|
||||
|
||||
wiringpi_test4_device_phys:
|
||||
wiringpi_test4_device_phys:
|
||||
${CC} ${CFLAGS} wiringpi_test4_device_phys.c -o wiringpi_test4_device_phys -lwiringPi
|
||||
|
||||
wiringpi_test5_default:
|
||||
wiringpi_test5_default:
|
||||
${CC} ${CFLAGS} wiringpi_test5_default.c -o wiringpi_test5_default -lwiringPi
|
||||
|
||||
wiringpi_test6_isr:
|
||||
wiringpi_test6_isr:
|
||||
${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi
|
||||
|
||||
wiringpi_test7_version:
|
||||
wiringpi_test7_version:
|
||||
${CC} ${CFLAGS} wiringpi_test7_version.c -o wiringpi_test7_version -lwiringPi
|
||||
|
||||
wiringpi_test8_pwm:
|
||||
${CC} ${CFLAGS} wiringpi_test8_pwm.c -o wiringpi_test8_pwm -lwiringPi
|
||||
|
||||
wiringpi_test9_pwm:
|
||||
${CC} ${CFLAGS} wiringpi_test9_pwm.c -o wiringpi_test9_pwm -lwiringPi
|
||||
|
||||
wiringpi_piface_test1:
|
||||
${CC} ${CFLAGS} wiringpi_piface_test1.c -o wiringpi_piface_test1 -lwiringPi -lwiringPiDev
|
||||
|
||||
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 [ $${t} = *"8_pwm" ] || [ $${t} = *"9_pwm" ]; then \
|
||||
time sudo ./$${t} ; \
|
||||
else \
|
||||
time ./$${t} ; \
|
||||
fi ; \
|
||||
if [ $$? -ne 0 ]; then \
|
||||
error_state=true ; \
|
||||
fi ; \
|
||||
@@ -57,7 +74,11 @@ xotest:
|
||||
@error_state=false ; \
|
||||
for t in $(tests) $(xotests) ; do \
|
||||
echo === XO unit test: $${t} === ; \
|
||||
time ./$${t} ; \
|
||||
if [ $${t} = *"8_pwm" ] || [ $${t} = *"9_pwm" ]; then \
|
||||
time sudo ./$${t} ; \
|
||||
else \
|
||||
time ./$${t} ; \
|
||||
fi ; \
|
||||
if [ $$? -ne 0 ]; then \
|
||||
error_state=true ; \
|
||||
fi ; \
|
||||
@@ -69,23 +90,27 @@ xotest:
|
||||
echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \
|
||||
fi
|
||||
|
||||
i2ctest:
|
||||
pifacetest:
|
||||
@error_state=false ; \
|
||||
for t in $(tests) $(i2ctests) ; do \
|
||||
echo === I2C unit test: $${t} === ; \
|
||||
time ./$${t} ; \
|
||||
for t in $(tests) $(pifacetests) ; do \
|
||||
echo === PiFace unit test: $${t} === ; \
|
||||
if [ $${t} = *"8_pwm" ] || [ $${t} = *"9_pwm" ]; then \
|
||||
time sudo ./$${t} ; \
|
||||
else \
|
||||
time ./$${t} ; \
|
||||
fi ; \
|
||||
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"; \
|
||||
echo "\n\e[5mPIFACE TEST FAILED\e[0m\n"; \
|
||||
else \
|
||||
echo "\n\e[5mSTD/I2C TEST SUCCESS\e[0m\n"; \
|
||||
echo "\n\e[5mPIFACE TEST SUCCESS\e[0m\n"; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
for t in $(tests) $(xotests) $(i2ctests) ; do \
|
||||
clean:
|
||||
for t in $(tests) $(xotests) $(pifacetests) ; do \
|
||||
rm -fv $${t} ; \
|
||||
done
|
||||
|
||||
133
wiringPi/test/wiringpi_piface_test1.c
Normal file
133
wiringPi/test/wiringpi_piface_test1.c
Normal file
@@ -0,0 +1,133 @@
|
||||
// WiringPi piface program IN, OUT, PULL
|
||||
// Compile: gcc -Wall wiringpi_piface_test1.c -o wiringpi_piface_test1 -lwiringPi -lwiringPiDev
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <piFace.h>
|
||||
|
||||
// Use 200 as the pin-base for the PiFace board, and change all pins
|
||||
// for the LED and relays
|
||||
|
||||
const int PIFACE = 200; //Mapped wiringpi IO address
|
||||
const int defaultsleep = 200000; // 200 ms
|
||||
|
||||
void ReadUntilTimeout(int GPIO, int expect, int timeoutSec) {
|
||||
const int intervaluS = 250000; //250ms
|
||||
int in;
|
||||
const char* strexpect = expect ? "HIGH" : "LOW";
|
||||
for(int loop=0, end=(timeoutSec*1000000/intervaluS); loop<end; ++loop) {
|
||||
in = digitalRead(GPIO);
|
||||
if (in==expect) {
|
||||
printf( "took %g sec to set %s\n", loop*intervaluS/1000000.0, strexpect);
|
||||
break;
|
||||
}
|
||||
delayMicroseconds(intervaluS);
|
||||
printf(".");fflush(stdout);
|
||||
}
|
||||
if (in!=expect) {
|
||||
printf( "timeout reached %d sec to set %s\n", timeoutSec, strexpect);
|
||||
}
|
||||
CheckGPIO(GPIO, -1, expect) ;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv []) {
|
||||
int major, minor;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
printf("Testing piface functions with WiringPi %d.%d\n",major, minor);
|
||||
printf("------------------------------------------\n\n");
|
||||
|
||||
// initialise wiringPi
|
||||
if (wiringPiSetupSys() == -1) {
|
||||
printf("wiringPiSetupSys failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
piFaceSetup (PIFACE); // Setup the PiFace board with default addr 0, 0
|
||||
|
||||
const int RELAY0 = PIFACE+0;
|
||||
const int RELAY0IN = PIFACE+6;
|
||||
const int RELAY1 = PIFACE+1;
|
||||
const int RELAY1IN = PIFACE+7;
|
||||
|
||||
|
||||
printf("\nRelays async:\n");
|
||||
pullUpDnControl(RELAY0IN, PUD_UP);
|
||||
pullUpDnControl(RELAY1IN, PUD_UP);
|
||||
for (int loop = 0, end=3 ; loop<end ; ++loop) {
|
||||
int sleep = defaultsleep*(end-loop);
|
||||
printf("sleep %d ms:\n", sleep/1000);
|
||||
digitalWrite (RELAY0, HIGH);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY0IN, -1, HIGH) ;
|
||||
digitalWrite (RELAY0, LOW);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY0IN, -1, LOW);
|
||||
|
||||
digitalWrite (RELAY1, HIGH);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY1IN, -1, HIGH);
|
||||
digitalWrite (RELAY1, LOW);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY1IN, -1, LOW);
|
||||
}
|
||||
|
||||
const int OUT7 = PIFACE+7;
|
||||
const int OUT7IN = PIFACE+4;
|
||||
const int OUT6 = PIFACE+6;
|
||||
const int OUT6IN = PIFACE+5;
|
||||
|
||||
printf("\nOUT6/7 sync:\n");
|
||||
delayMicroseconds(defaultsleep);
|
||||
for (int loop = 0, end=3 ; loop<end ; ++loop) {
|
||||
digitalWrite (OUT7, HIGH);
|
||||
delayMicroseconds(defaultsleep);
|
||||
CheckInversGPIO(OUT7IN, -1, HIGH);
|
||||
|
||||
digitalWrite (OUT7, LOW);
|
||||
delayMicroseconds(defaultsleep);
|
||||
CheckInversGPIO(OUT7IN, -1, LOW);
|
||||
|
||||
digitalWrite (OUT6, HIGH);
|
||||
delayMicroseconds(defaultsleep);
|
||||
CheckInversGPIO(OUT6IN, -1, HIGH);
|
||||
|
||||
digitalWrite (OUT6, LOW);
|
||||
delayMicroseconds(defaultsleep);
|
||||
CheckInversGPIO(OUT6IN, -1, LOW);
|
||||
}
|
||||
|
||||
printf("\nRelays sync:\n");
|
||||
for (int loop = 0, end=3 ; loop<end ; ++loop) {
|
||||
int sleep = defaultsleep*(end-loop);
|
||||
printf("sleep %d ms:\n", sleep/1000);
|
||||
digitalWrite (RELAY0, HIGH);
|
||||
digitalWrite (RELAY1, HIGH);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY0IN, -1, HIGH) ;
|
||||
CheckInversGPIO(RELAY1IN, -1, HIGH) ;
|
||||
|
||||
digitalWrite (RELAY0, LOW);
|
||||
digitalWrite (RELAY1, LOW);
|
||||
delayMicroseconds(sleep);
|
||||
CheckInversGPIO(RELAY0IN, -1, LOW) ;
|
||||
CheckInversGPIO(RELAY1IN, -1, LOW) ;
|
||||
}
|
||||
|
||||
printf("\nInput pull up/down resistor:\n");
|
||||
for (int IN = 0 ; IN <= 7 ; ++IN) {
|
||||
if (4==IN || 5==IN) {
|
||||
continue; //4 & 5 connected from out to in -> test not possible
|
||||
}
|
||||
//6 & 7 connected from relais NO (normaly open) to in -> test possible
|
||||
delayMicroseconds(defaultsleep);
|
||||
pullUpDnControl (PIFACE + IN, PUD_UP) ;
|
||||
ReadUntilTimeout(PIFACE + IN, HIGH, 2) ;
|
||||
pullUpDnControl (PIFACE + IN, PUD_DOWN) ;
|
||||
// cool down very slowly, connect 680 kOhm pull down resistor to make ist faster
|
||||
ReadUntilTimeout(PIFACE + IN, LOW, 60) ;
|
||||
pullUpDnControl (PIFACE + IN, PUD_UP) ; // finally up
|
||||
ReadUntilTimeout(PIFACE + IN, HIGH, 2) ;
|
||||
}
|
||||
|
||||
return UnitTestState();
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
int GPIO = 19;
|
||||
int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ int main (void) {
|
||||
printf("wiringPiSetupSys failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 23;
|
||||
GPIOIN = 24;
|
||||
}
|
||||
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
int GPIO = 19;
|
||||
int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ int main (void) {
|
||||
printf("wiringPiSetupSys failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 23;
|
||||
GPIOIN = 24;
|
||||
}
|
||||
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 24; //BCM 19
|
||||
const int GPIOIN = 25; //BCM 26;
|
||||
int GPIO = 24; //BCM 19
|
||||
int GPIOIN = 25; //BCM 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ int main (void) {
|
||||
printf("wiringPiSetupGpioDevice failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 4; //BCM 23
|
||||
GPIOIN = 5; //BCM 24
|
||||
}
|
||||
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 35; //BCM 19
|
||||
const int GPIOIN = 37; //BCM 26;
|
||||
int GPIO = 35; //BCM 19
|
||||
int GPIOIN = 37; //BCM 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ int main (void) {
|
||||
printf("wiringPiSetupGpioDevice failed\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 16; //BCM 23
|
||||
GPIOIN = 18; //BCM 24
|
||||
}
|
||||
|
||||
pinMode(GPIOIN, INPUT);
|
||||
pinMode(GPIO, OUTPUT);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
int GPIO = 19;
|
||||
int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
int RaspberryPiModel = -1;
|
||||
|
||||
@@ -58,6 +58,10 @@ int main (void) {
|
||||
} else {
|
||||
printf("Raspberry Pi with BCM GPIO found (not Pi 5)\n");
|
||||
}
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 23;
|
||||
GPIOIN = 24;
|
||||
}
|
||||
|
||||
|
||||
enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
const int GPIO = 19;
|
||||
const int GPIOIN = 26;
|
||||
int GPIO = 19;
|
||||
int GPIOIN = 26;
|
||||
const int ToggleValue = 4;
|
||||
|
||||
|
||||
@@ -115,55 +115,61 @@ double DurationTime(int Enge, int OUTpin, int IRQpin) {
|
||||
return fTime;
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
const int IRQpin = GPIOIN ;
|
||||
const int OUTpin = GPIO ;
|
||||
int major, minor;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
int main (void) {
|
||||
|
||||
int major, minor;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
|
||||
printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN);
|
||||
printf(" testing irq\n");
|
||||
|
||||
printf("\nISR test (WiringPi %d.%d)\n", major, minor);
|
||||
printf("\nISR test (WiringPi %d.%d)\n", major, minor);
|
||||
|
||||
wiringPiSetupGpio() ;
|
||||
|
||||
pinMode(IRQpin, INPUT);
|
||||
pinMode(OUTpin, OUTPUT);
|
||||
digitalWrite (OUTpin, LOW) ;
|
||||
wiringPiSetupGpio() ;
|
||||
if (!piBoard40Pin()) {
|
||||
GPIO = 23;
|
||||
GPIOIN = 24;
|
||||
}
|
||||
int IRQpin = GPIOIN ;
|
||||
int OUTpin = GPIO ;
|
||||
|
||||
pinMode(IRQpin, INPUT);
|
||||
pinMode(OUTpin, OUTPUT);
|
||||
digitalWrite (OUTpin, LOW) ;
|
||||
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_RISING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_RISING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_RISING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_FALLING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_BOTH, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_FALLING, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
for (int count=0; count<2; count++) {
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_RISING, OUTpin, IRQpin);
|
||||
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d both\n", IRQpin, OUTpin);
|
||||
wiringPiISR (IRQpin, INT_EDGE_BOTH, &wfi) ;
|
||||
sleep(1);
|
||||
StartSequence (INT_EDGE_BOTH, OUTpin);
|
||||
printf("Testing close\n");
|
||||
wiringPiISRStop (IRQpin) ;
|
||||
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin);
|
||||
}
|
||||
pinMode(OUTpin, INPUT);
|
||||
for (int count=0; count<2; count++) {
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d rising\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_RISING, OUTpin, IRQpin);
|
||||
|
||||
return UnitTestState();
|
||||
printf("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin);
|
||||
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin);
|
||||
}
|
||||
pinMode(OUTpin, INPUT);
|
||||
|
||||
return UnitTestState();
|
||||
}
|
||||
|
||||
186
wiringPi/test/wiringpi_test8_pwm.c
Normal file
186
wiringPi/test/wiringpi_test8_pwm.c
Normal file
@@ -0,0 +1,186 @@
|
||||
// WiringPi test program: PWM test
|
||||
// Compile: gcc -Wall wiringpi_test8_pwm.c -o wiringpi_test8_pwm -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int PWM_OUT[4] = { 18, 12, 13, 19 };
|
||||
int PWM_IN[4] = { 17, 13, 12, 26 };
|
||||
|
||||
volatile int gCounter = 0;
|
||||
|
||||
//Interrupt Service Routine for FREQIN
|
||||
void ISR_FREQIN(void) {
|
||||
gCounter++;
|
||||
}
|
||||
|
||||
double MeasureAndCheckFreqTolerance(const char* msg, double expect_freq, int tolerance) {
|
||||
double fFrequency;
|
||||
clock_t CPUClockBegin, CPUClockEnd;
|
||||
int CountBegin, CountEnd;
|
||||
double CPUClockInterval, CountInterval;
|
||||
double elapsed_time, CPULoad;
|
||||
uint64_t tbegin, tend;
|
||||
int SleepMs = 1200;
|
||||
|
||||
CPUClockBegin = clock();
|
||||
tbegin = piMicros64();
|
||||
CountBegin = gCounter;
|
||||
delay(SleepMs);
|
||||
CountEnd = gCounter;
|
||||
CPUClockEnd = clock();
|
||||
tend = piMicros64();
|
||||
|
||||
elapsed_time = (double)(tend-tbegin)/1.0e6;
|
||||
CountInterval = CountEnd - CountBegin;
|
||||
CPUClockInterval = CPUClockEnd - CPUClockBegin;
|
||||
CPULoad = CPUClockInterval*100.0 / CLOCKS_PER_SEC / elapsed_time;
|
||||
fFrequency = CountInterval / elapsed_time / 1000;
|
||||
|
||||
printf("\nInterval: time: %.6f sec (CPU: %3.1f %%), count: %g -> frequency: %.3f kHz\n",
|
||||
elapsed_time, CPULoad, CountInterval, fFrequency);
|
||||
|
||||
CheckSameDouble("Wait for freq. meas.", elapsed_time, SleepMs/1000.0, 0.1); //100ms tolerance. maybe problematic on high freq/cpu load
|
||||
CheckSameDouble(msg, fFrequency, expect_freq, (expect_freq!=0.0) ? expect_freq*tolerance/100 : 0.1); //x% tolerance
|
||||
return fFrequency;
|
||||
}
|
||||
|
||||
double MeasureAndCheckFreq(const char* msg, double expect_freq) {
|
||||
return MeasureAndCheckFreqTolerance(msg, expect_freq, 2);
|
||||
}
|
||||
|
||||
|
||||
int main (void) {
|
||||
|
||||
int major, minor;
|
||||
int PWM, FREQIN;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
|
||||
printf("WiringPi PWM GPIO test program 8\n");
|
||||
printf("PWM/ISR test (WiringPi %d.%d)\n", major, minor);
|
||||
|
||||
wiringPiSetupGpio() ;
|
||||
|
||||
int rev, mem, maker, overVolted, RaspberryPiModel;
|
||||
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
|
||||
CheckNotSame("Model: ", RaspberryPiModel, -1);
|
||||
|
||||
PWM = 18;
|
||||
FREQIN = 17;
|
||||
|
||||
printf("Register ISR@%d\n", PWM);
|
||||
// INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input
|
||||
int result = wiringPiISR(FREQIN, INT_EDGE_RISING, &ISR_FREQIN);
|
||||
CheckSame("Register ISR", result, 0);
|
||||
if (result < 0) {
|
||||
printf("Unable to setup ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
|
||||
return UnitTestState();
|
||||
}
|
||||
|
||||
printf("\n==> Set pwm 0%% and enable PWM output with PWM_OUTPUT (default mode)\n");
|
||||
pwmWrite(PWM, 0); // <-- Allways start with 0 Hz
|
||||
pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
|
||||
delay(250);
|
||||
double duty_fact = 0.0;
|
||||
double freq = 0.0;
|
||||
MeasureAndCheckFreq("PMW Pi0-4:BAL/Pi5:MS without change", freq);
|
||||
|
||||
printf("Keep pwm 0%% and set mode MS\n");
|
||||
pwmSetMode(PWM_MODE_MS);
|
||||
delay(250);
|
||||
MeasureAndCheckFreq("PWM MS without change", freq);
|
||||
|
||||
int pwmc;
|
||||
int pwmr;
|
||||
int pwm;
|
||||
|
||||
if (RaspberryPiModel!=PI_MODEL_5) {
|
||||
pwmSetMode(PWM_MODE_BAL);
|
||||
pwmc = 1000;
|
||||
pwmr = 1024;
|
||||
pwm = 512;
|
||||
duty_fact = (double)pwm/(double)pwmr;
|
||||
printf("\n==> set mode BAL, pwmc=%d, pwmr=%d, pwm=%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
|
||||
pwmSetClock(pwmc);
|
||||
pwmSetRange(pwmr);
|
||||
pwmWrite(PWM, pwm);
|
||||
delay(250);
|
||||
freq = 19200.0/pwmc*duty_fact;
|
||||
MeasureAndCheckFreq("PWM BAL with settings", freq);
|
||||
}
|
||||
|
||||
pwmSetMode(PWM_MODE_MS);
|
||||
pwmc = 10;
|
||||
pwmr = 256;
|
||||
pwm = 171;
|
||||
duty_fact = (double)pwm/(double)pwmr;
|
||||
printf("\n==> set mode MS, pwmc=%d, pwmr=%d, pwm%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
|
||||
pwmSetClock(pwmc);
|
||||
pwmSetRange(pwmr);
|
||||
pwmWrite(PWM, pwm);
|
||||
delay(250);
|
||||
freq = 19200.0/(double)pwmc/(double)pwmr;
|
||||
MeasureAndCheckFreq("PWM BAL with settings", freq);
|
||||
|
||||
printf("set PWM@GPIO%d (output) off\n", PWM);
|
||||
pinMode(PWM, PM_OFF);
|
||||
delay(1000);
|
||||
MeasureAndCheckFreq("PMW off", 0.0);
|
||||
|
||||
if (RaspberryPiModel!=PI_MODEL_5) {
|
||||
pwmc = 800;
|
||||
pwmr = 2048;
|
||||
pwm = 768;
|
||||
duty_fact = (double)pwm/(double)pwmr;
|
||||
printf("\n==> set mode PWM_BAL_OUTPUT, pwmc=%d, pwmr=%d, pwm%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
|
||||
pwmSetRange(pwmr);
|
||||
pwmSetClock(pwmc);
|
||||
pwmWrite(PWM, pwm);
|
||||
pinMode(PWM, PWM_BAL_OUTPUT);
|
||||
delay(250);
|
||||
freq = 19200.0/pwmc*duty_fact;
|
||||
MeasureAndCheckFreq("PMW BAL start values", freq);
|
||||
}
|
||||
|
||||
printf("set PWM@GPIO%d (output) off\n", PWM);
|
||||
pinMode(PWM, PM_OFF);
|
||||
delay(1000);
|
||||
MeasureAndCheckFreq("PMW off", 0.0);
|
||||
|
||||
printf("Set pwm settings and enable PWM\n");
|
||||
pwmc = 5;
|
||||
pwmr = 1024;
|
||||
pwm = 768;
|
||||
duty_fact = (double)pwm/(double)pwmr;
|
||||
printf("\n==> set mode PWM_MS_OUTPUT, pwmc=%d, pwmr=%d, pwm%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
|
||||
pwmSetRange(pwmr);
|
||||
pwmSetClock(pwmc);
|
||||
pwmWrite(PWM, pwm);
|
||||
pinMode(PWM, PWM_MS_OUTPUT);
|
||||
delay(250);
|
||||
freq = 19200.0/(double)pwmc/(double)pwmr;
|
||||
MeasureAndCheckFreq("PMW MS start values", freq);
|
||||
|
||||
printf("set PWM@GPIO%d (output) off\n", PWM);
|
||||
pinMode(PWM, PM_OFF);
|
||||
delay(1000);
|
||||
MeasureAndCheckFreq("PMW off", 0.0);
|
||||
|
||||
printf("set PWM0 CLK off @ Pi5\n");
|
||||
pwmSetClock(0);
|
||||
|
||||
result = wiringPiISRStop(FREQIN);
|
||||
CheckSame("\n\nRelease ISR", result, 0);
|
||||
if (result < 0) {
|
||||
printf("Unable to release ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
|
||||
return UnitTestState();
|
||||
}
|
||||
|
||||
return UnitTestState();
|
||||
}
|
||||
225
wiringPi/test/wiringpi_test9_pwm.c
Normal file
225
wiringPi/test/wiringpi_test9_pwm.c
Normal file
@@ -0,0 +1,225 @@
|
||||
// WiringPi test program: PWM test
|
||||
// Compile: gcc -Wall wiringpi_test9_pwm.c -o wiringpi_test9_pwm -lwiringPi
|
||||
|
||||
#include "wpi_test.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int PWM_OUT[4] = { 18, 12, 13, 19 };
|
||||
int PWM_IN[4] = { 17, 13, 12, 26 };
|
||||
|
||||
volatile int gCounter = 0;
|
||||
|
||||
//Interrupt Service Routine for FREQIN
|
||||
void ISR_FREQIN(void) {
|
||||
gCounter++;
|
||||
}
|
||||
|
||||
double MeasureAndCheckFreq(const char* msg, double expect_freq) {
|
||||
double fFrequency;
|
||||
clock_t CPUClockBegin, CPUClockEnd;
|
||||
int CountBegin, CountEnd;
|
||||
double CPUClockInterval, CountInterval;
|
||||
double elapsed_time, CPULoad;
|
||||
uint64_t tbegin, tend;
|
||||
int SleepMs = 1200;
|
||||
|
||||
CPUClockBegin = clock();
|
||||
tbegin = piMicros64();
|
||||
CountBegin = gCounter;
|
||||
delay(SleepMs);
|
||||
CountEnd = gCounter;
|
||||
CPUClockEnd = clock();
|
||||
tend = piMicros64();
|
||||
|
||||
elapsed_time = (double)(tend-tbegin)/1.0e6;
|
||||
CountInterval = CountEnd - CountBegin;
|
||||
CPUClockInterval = CPUClockEnd - CPUClockBegin;
|
||||
CPULoad = CPUClockInterval*100.0 / CLOCKS_PER_SEC / elapsed_time;
|
||||
fFrequency = CountInterval / elapsed_time / 1000;
|
||||
|
||||
printf("\nInterval: time: %.6f sec (CPU: %3.1f %%), count: %g -> frequency: %.3f kHz\n",
|
||||
elapsed_time, CPULoad, CountInterval, fFrequency);
|
||||
|
||||
CheckSameDouble("Wait for freq. meas.", elapsed_time, SleepMs/1000.0, 0.1); //100ms tolerance. maybe problematic on high freq/cpu load
|
||||
CheckSameDouble(msg, fFrequency, expect_freq, expect_freq*2/100); //2% toleranc
|
||||
return fFrequency;
|
||||
}
|
||||
|
||||
|
||||
int tests_pwmc[7] = {1456, 1000, 512, 100, 2000, 3000, 4000};
|
||||
int tests_duty[7] = { 512, 768, 682, 922, 256, 341, 102};
|
||||
int tests_pwmr[12]= { 50, 100, 200, 512, 1024, 1456, 2000, 3000, 5000, 10000, 15000, 20000};
|
||||
int tests_pwm[3] = { 50, 25, 75};
|
||||
|
||||
int main (void) {
|
||||
|
||||
int major, minor;
|
||||
char msg[255];
|
||||
int testruns = 4;
|
||||
int PWM, FREQIN;
|
||||
|
||||
wiringPiVersion(&major, &minor);
|
||||
|
||||
printf("WiringPi GPIO test program 9\n");
|
||||
printf("PWM/ISR test (WiringPi %d.%d)\n", major, minor);
|
||||
|
||||
wiringPiSetupGpio() ;
|
||||
|
||||
int rev, mem, maker, overVolted, RaspberryPiModel;
|
||||
piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
|
||||
CheckNotSame("Model: ", RaspberryPiModel, -1);
|
||||
int Pi4 = 0;
|
||||
int Pi5 = 0;
|
||||
double MaxFreq = 100.0;
|
||||
switch(RaspberryPiModel) {
|
||||
case PI_MODEL_A:
|
||||
case PI_MODEL_B:
|
||||
case PI_MODEL_BP:
|
||||
case PI_MODEL_AP:
|
||||
case PI_MODEL_ZERO:
|
||||
case PI_MODEL_ZERO_W:
|
||||
case PI_MODEL_CM:
|
||||
MaxFreq = 13.0; // 12.5 kHz -> ~40% CPU@800 MHz
|
||||
printf(" - Pi1/BCM2835 detected, will skip tests with frequency above %g kHz\n", MaxFreq);
|
||||
break;
|
||||
case PI_MODEL_2:
|
||||
MaxFreq = 20.0;
|
||||
printf(" - Pi2/BCM2836 detected, will skip tests with frequency above %g kHz\n", MaxFreq);
|
||||
break;
|
||||
case PI_MODEL_3B:
|
||||
case PI_MODEL_CM3:
|
||||
case PI_MODEL_3BP:
|
||||
case PI_MODEL_3AP:
|
||||
case PI_MODEL_CM3P:
|
||||
case PI_MODEL_ZERO_2W:
|
||||
MaxFreq = 50.0;
|
||||
printf(" - Pi3/BCM2837 detected, will skip tests with frequency above %g kHz\n", MaxFreq);
|
||||
break;
|
||||
case PI_MODEL_4B:
|
||||
case PI_MODEL_400:
|
||||
case PI_MODEL_CM4:
|
||||
case PI_MODEL_CM4S:
|
||||
Pi4 = 1;
|
||||
break;
|
||||
case PI_MODEL_5:
|
||||
Pi5 = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!piBoard40Pin()) {
|
||||
testruns = 1; // only fist PWM0, supported
|
||||
}
|
||||
|
||||
for (int testrun=0; testrun<testruns; testrun++) {
|
||||
PWM = PWM_OUT[testrun];
|
||||
FREQIN = PWM_IN[testrun];
|
||||
printf("using PWM@GPIO%d (output) and GPIO%d (input)\n", PWM, FREQIN);
|
||||
delay(1000);
|
||||
printf("\n");
|
||||
printf("*********************************\n");
|
||||
printf("* PWM BAL mode *\n");
|
||||
printf("*********************************\n");
|
||||
const int pmw = 512;
|
||||
int pmwr = 1024; //default!
|
||||
|
||||
printf("Set pwm 50%% and enable PWM output (600 kHz?) \n");
|
||||
pwmWrite(PWM, pmw); //50% Duty
|
||||
pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
|
||||
printf("pwmc 4.8kHz\n");
|
||||
pwmSetClock(2000);
|
||||
delay(250);
|
||||
|
||||
printf("Register ISR@%d\n", PWM);
|
||||
// INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input
|
||||
int result = wiringPiISR(FREQIN, INT_EDGE_RISING, &ISR_FREQIN);
|
||||
CheckSame("Register ISR", result, 0);
|
||||
if (result < 0) {
|
||||
printf("Unable to setup ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
|
||||
return UnitTestState();
|
||||
}
|
||||
printf("Wait for start ...\n");
|
||||
delay(500);
|
||||
printf("Start:\n");
|
||||
//MeasureAndCheckFreq("50\% Duty (default)", 300.000); //FAIL , freq (pwmc=32) to high for irq count
|
||||
if(!Pi5) {
|
||||
for (int c_duty=0, c_duty_end = sizeof(tests_duty)/sizeof(tests_duty[0]); c_duty<c_duty_end; c_duty++) {
|
||||
double tests_duty_corr;
|
||||
if (tests_duty[c_duty]>(pmwr/2)) {
|
||||
tests_duty_corr = pmwr-tests_duty[c_duty];
|
||||
} else {
|
||||
tests_duty_corr = tests_duty[c_duty];
|
||||
}
|
||||
|
||||
double duty_fact = tests_duty_corr/(double)pmwr;
|
||||
printf("\n%d/%d set duty %d/%d\n",c_duty+1, c_duty_end, tests_duty[c_duty], pmwr);
|
||||
pwmWrite(PWM, tests_duty[c_duty]);
|
||||
|
||||
for (int c_pwmc=0, end = sizeof(tests_pwmc)/sizeof(tests_pwmc[0]); c_pwmc<end; c_pwmc++) {
|
||||
int pwmc = tests_pwmc[c_pwmc];
|
||||
if (Pi4 && pwmc>1456) {
|
||||
printf("* Set clock (pwmc) %d not possible on BCM2711 system (OSC 54 MHz), ignore\n", pwmc);
|
||||
continue;
|
||||
}
|
||||
double freq = 19200.0/pwmc*duty_fact;
|
||||
if (freq>MaxFreq) {
|
||||
printf("* Set clock (pwmc) %d not possible on system (to slow to measure %g kHz with ISR), ignore\n", pwmc, freq);
|
||||
continue;
|
||||
}
|
||||
pwmSetClock(pwmc);
|
||||
delay(250);
|
||||
sprintf(msg, "Set Clock (pwmc) %d, %d%% duty", pwmc, tests_duty[c_duty]*100/pmwr);
|
||||
MeasureAndCheckFreq(msg, freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay(250);
|
||||
printf("\n");
|
||||
printf("*********************************\n");
|
||||
printf("* PWM MS mode *\n");
|
||||
printf("*********************************\n");
|
||||
int pwmc = 10;
|
||||
printf("SetClock pwmc=%d and enable MS mode\n", pwmc);
|
||||
pwmSetClock(pwmc);
|
||||
pwmSetMode(PWM_MODE_MS);
|
||||
printf("Wait for start ...\n");
|
||||
delay(250);
|
||||
printf("Start:\n");
|
||||
for (int c_pmwr=0, c_pmwr_end = sizeof(tests_pwmr)/sizeof(tests_pwmr[0]); c_pmwr<c_pmwr_end; c_pmwr++) {
|
||||
int pwmr = tests_pwmr[c_pmwr];
|
||||
double freq = 19200.0/(double)pwmc/(double)pwmr;
|
||||
if (freq>MaxFreq) {
|
||||
printf("* Set Clock (pwmc, pwmr) %d, %d not possible on system (to slow to measure %g kHz with ISR), ignore\n", pwmc, pwmr, freq);
|
||||
continue;
|
||||
}
|
||||
sprintf(msg, "Set range (pwmr) %d", pwmr);
|
||||
pwmSetRange(pwmr);
|
||||
|
||||
for (int c_pmw=0, c_pmw_end = sizeof(tests_pwm)/sizeof(tests_pwm[0]); c_pmw<c_pmw_end; c_pmw++) {
|
||||
int pwm = pwmr*tests_pwm[c_pmw]/100;
|
||||
sprintf(msg, "Set pwm %d/%d (%d %%)", pwm, pwmr, tests_pwm[c_pmw]);
|
||||
pwmWrite(PWM, pwm);
|
||||
delay(250);
|
||||
MeasureAndCheckFreq(msg, freq);
|
||||
}
|
||||
}
|
||||
|
||||
result = wiringPiISRStop(FREQIN);
|
||||
CheckSame("\n\nRelease ISR", result, 0);
|
||||
if (result < 0) {
|
||||
printf("Unable to release ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
|
||||
return UnitTestState();
|
||||
}
|
||||
printf("set PWM@GPIO%d (output) back to input\n", PWM);
|
||||
pinMode(PWM, INPUT);
|
||||
}
|
||||
|
||||
printf("\nDid %d PWM GPIO tests with model %d\n", testruns, RaspberryPiModel);
|
||||
|
||||
return UnitTestState();
|
||||
}
|
||||
@@ -47,7 +47,7 @@ void checkVoltage(float expect, const char* szexpect) {
|
||||
int CH1 = AnalogRead(spiChannel, 1, &returnvalue);
|
||||
//float value0 = CH0 * fRefVoltage / fResolution;
|
||||
float value1 = CH1 * fRefVoltage / fResolution;
|
||||
CheckSameFloat(szexpect, value1, expect);
|
||||
CheckSameFloat(szexpect, value1, expect, 0.1);
|
||||
delayMicroseconds(300);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@ void CheckGPIO(int GPIO, int GPIOIN, int out) {
|
||||
|
||||
int in = out;
|
||||
if (GPIOIN>=0) {
|
||||
in = digitalRead(GPIOIN);
|
||||
in = digitalRead(GPIOIN);
|
||||
}
|
||||
int readback = digitalRead(GPIO);
|
||||
|
||||
int pass = 0;
|
||||
if (out==readback && in==out) {
|
||||
pass = 1;
|
||||
}
|
||||
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);
|
||||
@@ -44,6 +44,11 @@ void CheckGPIO(int GPIO, int GPIOIN, int out) {
|
||||
}
|
||||
|
||||
|
||||
void CheckInversGPIO(int GPIO, int GPIOIN, int out) {
|
||||
CheckGPIO(GPIO, GPIOIN, out==HIGH ? LOW : HIGH);
|
||||
}
|
||||
|
||||
|
||||
void digitalWriteEx(int GPIO, int GPIOIN, int mode) {
|
||||
digitalWrite(GPIO, mode);
|
||||
delayMicroseconds(5000);
|
||||
@@ -90,8 +95,21 @@ void CheckNotSame(const char* msg, int value, int expect) {
|
||||
}
|
||||
|
||||
|
||||
void CheckSameFloat(const char* msg, float value, float expect) {
|
||||
if (fabs(value-expect)<0.08) {
|
||||
void CheckSameFloat(const char* msg, float value, float expect, float epsilon) {
|
||||
if (fabs(value-expect)<epsilon) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckSameFloatX(const char* msg, float value, float expect) {
|
||||
return CheckSameFloat(msg, value, expect, 0.08f);
|
||||
}
|
||||
|
||||
void CheckSameDouble(const char* msg, double value, double expect, double epsilon) {
|
||||
if (fabs(value-expect)<epsilon) {
|
||||
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);
|
||||
|
||||
@@ -118,14 +118,20 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
|
||||
|
||||
// Port function select bits
|
||||
|
||||
#define FSEL_INPT 0b000
|
||||
#define FSEL_OUTP 0b001
|
||||
#define FSEL_ALT0 0b100
|
||||
#define FSEL_ALT1 0b101
|
||||
#define FSEL_ALT2 0b110
|
||||
#define FSEL_ALT3 0b111
|
||||
#define FSEL_ALT4 0b011
|
||||
#define FSEL_ALT5 0b010
|
||||
#define FSEL_INPT 0b000 //0
|
||||
#define FSEL_OUTP 0b001 //1
|
||||
#define FSEL_ALT0 0b100 //4
|
||||
#define FSEL_ALT1 0b101 //5
|
||||
#define FSEL_ALT2 0b110 //6
|
||||
#define FSEL_ALT3 0b111 //7
|
||||
#define FSEL_ALT4 0b011 //3
|
||||
#define FSEL_ALT5 0b010 //2
|
||||
//RP1 defines
|
||||
#define FSEL_ALT6 8
|
||||
#define FSEL_ALT7 9
|
||||
#define FSEL_ALT8 10
|
||||
#define FSEL_ALT9 11
|
||||
|
||||
|
||||
//RP1 chip (@Pi5) - 3.1.1. Function select
|
||||
#define RP1_FSEL_ALT0 0x00
|
||||
@@ -166,10 +172,40 @@ 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);
|
||||
|
||||
const unsigned int RP1_PWM0_GLOBAL_CTRL = 0;
|
||||
const unsigned int RP1_PWM0_FIFO_CTRL = 1;
|
||||
const unsigned int RP1_PWM0_COMMON_RANGE= 2;
|
||||
const unsigned int RP1_PWM0_COMMON_DUTY = 3;
|
||||
const unsigned int RP1_PWM0_DUTY_FIFO = 4;
|
||||
const unsigned int RP1_PWM0_CHAN_START = 5;
|
||||
//offset channel
|
||||
const unsigned int RP1_PWM0_CHAN_CTRL = 0;
|
||||
const unsigned int RP1_PWM0_CHAN_RANGE = 1;
|
||||
const unsigned int RP1_PWM0_CHAN_PHASE = 2;
|
||||
const unsigned int RP1_PWM0_CHAN_DUTY = 3;
|
||||
const unsigned int RP1_PWM0_CHAN_OFFSET= 4;
|
||||
|
||||
const unsigned int RP1_PWM0_CHAN0_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*0+RP1_PWM0_CHAN_RANGE;
|
||||
const unsigned int RP1_PWM0_CHAN1_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*1+RP1_PWM0_CHAN_RANGE;
|
||||
const unsigned int RP1_PWM0_CHAN2_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*2+RP1_PWM0_CHAN_RANGE;
|
||||
const unsigned int RP1_PWM0_CHAN3_RANGE = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*3+RP1_PWM0_CHAN_RANGE;
|
||||
|
||||
const unsigned int RP1_PWM_CTRL_SETUPDATE = 0x80000000; // Bit 32
|
||||
const unsigned int RP1_PWM_TRAIL_EDGE_MS = 0x1;
|
||||
const unsigned int RP1_PWM_FIFO_POP_MASK = 0x100; // Bit 8
|
||||
const unsigned int RP1_CLK_PWM0_CTRL_DISABLE_MAGIC = 0x10000000; // Default after boot
|
||||
const unsigned int RP1_CLK_PWM0_CTRL_ENABLE_MAGIC = 0x11000840; // Reverse engineered, because of missing documentation, don't known meaning of of bits
|
||||
|
||||
const unsigned int CLK_PWM0_CTRL = (0x00074/4);
|
||||
const unsigned int CLK_PWM0_DIV_INT = (0x00078/4);
|
||||
const unsigned int CLK_PWM0_DIV_FRAC = (0x0007C/4);
|
||||
const unsigned int CLK_PWM0_SEL = (0x00080/4);
|
||||
|
||||
//RP1 chip (@Pi5) address
|
||||
const unsigned long long RP1_64_BASE_Addr = 0x1f000d0000;
|
||||
const unsigned int RP1_BASE_Addr = 0x40000000;
|
||||
const unsigned int RP1_PWM0_Addr = 0x40098000; // Adress is not mapped to gpiomem device!
|
||||
const unsigned int RP1_CLOCK_Addr = 0x40018000; // Adress is not mapped to gpiomem device, lower than RP1_IO0_Addr
|
||||
const unsigned int RP1_PWM0_Addr = 0x40098000; // Adress is not mapped to gpiomem device, lower than RP1_IO0_Addr
|
||||
const unsigned int RP1_IO0_Addr = 0x400d0000;
|
||||
const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000;
|
||||
const unsigned int RP1_PADS0_Addr = 0x400f0000;
|
||||
@@ -195,7 +231,7 @@ const unsigned short pciemem_RP1_Ventor= 0x1de4;
|
||||
const unsigned short pciemem_RP1_Device= 0x0001;
|
||||
|
||||
static volatile unsigned int GPIO_PADS ;
|
||||
static volatile unsigned int GPIO_CLOCK_BASE ;
|
||||
static volatile unsigned int GPIO_CLOCK_ADR ;
|
||||
static volatile unsigned int GPIO_BASE ;
|
||||
static volatile unsigned int GPIO_TIMER ;
|
||||
static volatile unsigned int GPIO_PWM ;
|
||||
@@ -238,6 +274,11 @@ static int wiringPiSetuped = FALSE ;
|
||||
#define PWM1_SERIAL 0x0200 // Run in serial mode
|
||||
#define PWM1_ENABLE 0x0100 // Channel Enable
|
||||
|
||||
const int PWMCLK_DIVI_MAX = 0xFFF; // 3 Byte max size for Clock devider
|
||||
const int OSC_FREQ_DEFAULT = 192; // x100kHz OSC
|
||||
const int OSC_FREQ_BCM2711 = 540; // x100kHz OSC
|
||||
const int OSC_FREQ_BCM2712 = 500; // x100kHz OSC - cat /sys/kernel/debug/clk/clk_summary | grep pwm0
|
||||
|
||||
// Timer
|
||||
// Word offsets
|
||||
|
||||
@@ -557,6 +598,27 @@ int piBoard() {
|
||||
return RaspberryPiModel<0 ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
int piBoard40Pin() {
|
||||
if (!piBoard()){
|
||||
// Board not detected
|
||||
return -1;
|
||||
}
|
||||
switch(RaspberryPiModel){
|
||||
case PI_MODEL_A:
|
||||
case PI_MODEL_B:
|
||||
return 0;
|
||||
// PI_MODEL_CM
|
||||
// PI_MODEL_CM3
|
||||
// PI_MODEL_CM4
|
||||
// PI_MODEL_CM4S
|
||||
// ? guess yes
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int GetMaxPin() {
|
||||
return PI_MODEL_5 == RaspberryPiModel ? 27 : 63;
|
||||
}
|
||||
@@ -564,10 +626,10 @@ int GetMaxPin() {
|
||||
|
||||
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
|
||||
|
||||
int FailOnModel5() {
|
||||
int FailOnModel5(const char *function) {
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n"
|
||||
" Unable to continue. Keep an eye of new versions at https://github.com/wiringpi/wiringpi\n") ;
|
||||
return wiringPiFailure (WPI_ALMOST, "Function '%s' not supported on Raspberry Pi 5.\n"
|
||||
" Unable to continue. Keep an eye of new versions at https://github.com/wiringpi/wiringpi\n", function) ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -690,8 +752,8 @@ static uint8_t gpioToPUDCLK [] =
|
||||
static uint8_t gpioToPwmALT [] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
|
||||
0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
|
||||
0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
|
||||
0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15
|
||||
0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
|
||||
FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47
|
||||
@@ -706,8 +768,8 @@ static uint8_t gpioToPwmALT [] =
|
||||
static uint8_t gpioToPwmPort [] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7
|
||||
0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
|
||||
0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
|
||||
0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15
|
||||
0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39
|
||||
PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47
|
||||
@@ -1131,6 +1193,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
|
||||
case PI_MODEL_4B:
|
||||
case PI_MODEL_400:
|
||||
case PI_MODEL_CM4:
|
||||
case PI_MODEL_CM4S:
|
||||
piGpioBase = GPIO_PERI_BASE_2711 ;
|
||||
piGpioPupOffset = GPPUPPDN0 ;
|
||||
break ;
|
||||
@@ -1261,7 +1324,7 @@ void setPadDrive (int group, int value)
|
||||
|
||||
int getAlt (int pin)
|
||||
{
|
||||
int fSel, shift, alt ;
|
||||
int alt;
|
||||
|
||||
pin &= 63 ;
|
||||
|
||||
@@ -1292,29 +1355,28 @@ int getAlt (int pin)
|
||||
11 = alternate function 9
|
||||
*/
|
||||
switch(alt) {
|
||||
case 0: return 4;
|
||||
case 1: return 5;
|
||||
case 2: return 6;
|
||||
case 3: return 7;
|
||||
case 4: return 3;
|
||||
case 0: return FSEL_ALT0;
|
||||
case 1: return FSEL_ALT1;
|
||||
case 2: return FSEL_ALT2;
|
||||
case 3: return FSEL_ALT3;
|
||||
case 4: return FSEL_ALT4;
|
||||
case RP1_FSEL_GPIO: {
|
||||
unsigned int outputmask = gpio[2*pin] & 0x3000; //Bit13-OETOPAD + Bit12-OEFROMPERI
|
||||
return (outputmask==0x3000) ? 1 : 0; //1=OUT 0=IN
|
||||
return (outputmask==0x3000) ? FSEL_OUTP : FSEL_INPT;
|
||||
}
|
||||
case 6: return 8;
|
||||
case 7: return 9;
|
||||
case 8: return 10;
|
||||
case 9: return 11;
|
||||
case 6: return FSEL_ALT6;
|
||||
case 7: return FSEL_ALT7;
|
||||
case 8: return FSEL_ALT8;
|
||||
case RP1_FSEL_NONE: return FSEL_ALT9;
|
||||
default:return alt;
|
||||
}
|
||||
|
||||
} else {
|
||||
fSel = gpioToGPFSEL [pin] ;
|
||||
shift = gpioToShift [pin] ;
|
||||
int fSel = gpioToGPFSEL [pin] ;
|
||||
int shift = gpioToShift [pin] ;
|
||||
|
||||
alt = (*(gpio + fSel) >> shift) & 7 ;
|
||||
}
|
||||
return alt ;
|
||||
return alt;
|
||||
}
|
||||
|
||||
|
||||
@@ -1333,11 +1395,20 @@ void pwmSetMode (int mode)
|
||||
{
|
||||
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
|
||||
{
|
||||
FailOnModel5();
|
||||
if (mode == PWM_MODE_MS)
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if(mode != PWM_MODE_MS) {
|
||||
fprintf(stderr, "pwmSetMode: Raspberry Pi 5 missing feature PWM BAL mode\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mode == PWM_MODE_MS) {
|
||||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
|
||||
else
|
||||
} else {
|
||||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("Enable PWM mode: %s. Current register: 0x%08X\n", mode == PWM_MODE_MS ? "mark:space (freq. stable)" : "balanced (freq. change)", *(pwm + PWM_CONTROL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1351,11 +1422,32 @@ void pwmSetMode (int mode)
|
||||
|
||||
void pwmSetRange (unsigned int range)
|
||||
{
|
||||
FailOnModel5();
|
||||
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
|
||||
{
|
||||
*(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
|
||||
*(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
|
||||
/* would be possible on ms mode but not on bal, deactivated, use pwmc modify instead
|
||||
if (piGpioBase == GPIO_PERI_BASE_2711) {
|
||||
range = (OSC_FREQ_BCM2711*range)/OSC_FREQ_DEFAULT;
|
||||
}
|
||||
*/
|
||||
if (!pwm) {
|
||||
fprintf(stderr, "wiringPi: pwmSetRange but no pwm memory available, ignoring\n");
|
||||
return;
|
||||
}
|
||||
int readback = 0x00;
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
pwm[RP1_PWM0_CHAN0_RANGE] = range;
|
||||
pwm[RP1_PWM0_CHAN1_RANGE] = range;
|
||||
pwm[RP1_PWM0_CHAN2_RANGE] = range;
|
||||
pwm[RP1_PWM0_CHAN3_RANGE] = range;
|
||||
readback = pwm[RP1_PWM0_CHAN0_RANGE];
|
||||
} else {
|
||||
*(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
|
||||
*(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
|
||||
readback = *(pwm + PWM0_RANGE);
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("PWM range: %u. Current register: 0x%08X\n", range, readback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1371,19 +1463,45 @@ void pwmSetRange (unsigned int range)
|
||||
void pwmSetClock (int divisor)
|
||||
{
|
||||
uint32_t pwm_control ;
|
||||
|
||||
FailOnModel5();
|
||||
if (piGpioBase == GPIO_PERI_BASE_2711)
|
||||
{
|
||||
divisor = 540*divisor/192;
|
||||
if (!clk) {
|
||||
fprintf(stderr, "wiringPi: pwmSetClock but no clk memory available, ignoring\n");
|
||||
return;
|
||||
}
|
||||
divisor &= 4095 ;
|
||||
|
||||
if (divisor > PWMCLK_DIVI_MAX) {
|
||||
divisor = PWMCLK_DIVI_MAX; // even on Pi5 4095 is OK
|
||||
}
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if (divisor < 1) {
|
||||
if (wiringPiDebug) { printf("Disable PWM0 clock"); }
|
||||
clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC; // 0 = disable on Pi5
|
||||
} else {
|
||||
divisor = (OSC_FREQ_BCM2712*divisor)/OSC_FREQ_DEFAULT;
|
||||
if (wiringPiDebug) {
|
||||
printf ("PWM clock divisor: %d\n", divisor) ;
|
||||
}
|
||||
//clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC;
|
||||
//delayMicroseconds(100);
|
||||
clk[CLK_PWM0_DIV_INT] = divisor;
|
||||
clk[CLK_PWM0_DIV_FRAC] = 0;
|
||||
clk[CLK_PWM0_SEL] = 1;
|
||||
clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_ENABLE_MAGIC;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (piGpioBase == GPIO_PERI_BASE_2711) {
|
||||
//calculate value for OSC 54MHz -> 19.2MHz
|
||||
// Pi 4 max divisor is 1456, Pi0-3 is 4095 (0xFFF)
|
||||
divisor = (OSC_FREQ_BCM2711*divisor)/OSC_FREQ_DEFAULT;
|
||||
}
|
||||
if (divisor < 1) {
|
||||
divisor = 1;
|
||||
}
|
||||
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
|
||||
{
|
||||
if (wiringPiDebug)
|
||||
printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
|
||||
|
||||
if (wiringPiDebug) {
|
||||
printf ("PWM clock divisor: Old register: 0x%08X\n", *(clk + PWMCLK_DIV)) ;
|
||||
}
|
||||
pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
|
||||
|
||||
// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
|
||||
@@ -1408,8 +1526,9 @@ void pwmSetClock (int divisor)
|
||||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
|
||||
*(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
|
||||
|
||||
if (wiringPiDebug)
|
||||
printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
|
||||
if (wiringPiDebug) {
|
||||
printf ("PWM clock divisor %d. Current register: 0x%08X\n", divisor, *(clk + PWMCLK_DIV));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1424,7 +1543,7 @@ void gpioClockSet (int pin, int freq)
|
||||
{
|
||||
int divi, divr, divf ;
|
||||
|
||||
FailOnModel5();
|
||||
FailOnModel5("gpioClockSet");
|
||||
pin &= 63 ;
|
||||
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
@@ -1438,9 +1557,9 @@ void gpioClockSet (int pin, int freq)
|
||||
divr = 19200000 % freq ;
|
||||
divf = (int)((double)divr * 4096.0 / 19200000.0) ;
|
||||
|
||||
if (divi > 4095)
|
||||
divi = 4095 ;
|
||||
|
||||
if (divi > PWMCLK_DIVI_MAX) {
|
||||
divi = PWMCLK_DIVI_MAX;
|
||||
}
|
||||
*(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock
|
||||
while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait
|
||||
;
|
||||
@@ -1613,9 +1732,6 @@ int requestLine(int pin, unsigned int lineRequestFlags) {
|
||||
|
||||
void pinModeAlt (int pin, int mode)
|
||||
{
|
||||
int fSel, shift ;
|
||||
|
||||
RETURN_ON_MODEL5
|
||||
setupCheck ("pinModeAlt") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin
|
||||
@@ -1628,20 +1744,49 @@ void pinModeAlt (int pin, int mode)
|
||||
return ;
|
||||
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
|
||||
//confusion! diffrent to to BCM! this is taking directly the value for the register
|
||||
/*
|
||||
"alt0" 0b100
|
||||
"alt1" 0b101
|
||||
"alt2" 0b110
|
||||
"alt3" 0b111
|
||||
"alt4" 0b011
|
||||
"alt5" 0b010
|
||||
*/
|
||||
gpio[2*pin+1] = (mode & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time
|
||||
int modeRP1;
|
||||
switch(mode) {
|
||||
case FSEL_ALT0:
|
||||
modeRP1 = 0;
|
||||
break;
|
||||
case FSEL_ALT1:
|
||||
modeRP1 = 1;
|
||||
break;
|
||||
case FSEL_ALT2:
|
||||
modeRP1 = 2;
|
||||
break;
|
||||
case FSEL_ALT3:
|
||||
modeRP1 = 3;
|
||||
break;
|
||||
case FSEL_ALT4:
|
||||
modeRP1 = 4;
|
||||
break;
|
||||
case FSEL_ALT5:
|
||||
modeRP1 = 5;
|
||||
break;
|
||||
case FSEL_ALT6:
|
||||
modeRP1 = 6;
|
||||
break;
|
||||
case FSEL_ALT7:
|
||||
modeRP1 = 7;
|
||||
break;
|
||||
case FSEL_ALT8:
|
||||
modeRP1 = 8;
|
||||
break;
|
||||
case FSEL_OUTP:
|
||||
case FSEL_INPT:
|
||||
modeRP1 = RP1_FSEL_GPIO;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "pinModeAlt: invalid mode %d\n", mode);
|
||||
return;
|
||||
}
|
||||
//printf("pinModeAlt: Pi5 alt pin %d to %d\n", pin, modeRP1);
|
||||
gpio[2*pin+1] = (modeRP1 & RP1_FSEL_NONE_HW) | RP1_DEBOUNCE_DEFAULT; //0-4 function, 5-11 debounce time
|
||||
} else {
|
||||
fSel = gpioToGPFSEL [pin] ;
|
||||
shift = gpioToShift [pin] ;
|
||||
int fSel = gpioToGPFSEL [pin] ;
|
||||
int shift = gpioToShift [pin] ;
|
||||
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
|
||||
}
|
||||
@@ -1749,6 +1894,15 @@ void pinMode (int pin, int mode)
|
||||
} else {
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
|
||||
}
|
||||
if (PM_OFF==mode && !usingGpioMem && pwm && gpioToPwmALT[pin]>0) { //PWM pin -> reset
|
||||
pwmWrite(origPin, 0);
|
||||
int channel = gpioToPwmPort[pin];
|
||||
if (channel>=0 && channel<=3 && PI_MODEL_5 == RaspberryPiModel) {
|
||||
unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL];
|
||||
pwm[RP1_PWM0_GLOBAL_CTRL] = (ctrl & ~(1<<channel)) | RP1_PWM_CTRL_SETUPDATE;
|
||||
//printf("Disable PWM0[%d] (0x%08X->0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]);
|
||||
}
|
||||
}
|
||||
} else if (mode == OUTPUT) {
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9;
|
||||
@@ -1766,22 +1920,41 @@ void pinMode (int pin, int mode)
|
||||
pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode
|
||||
pwmSetMode (PWM_MODE_MS) ;
|
||||
}
|
||||
else if (mode == PWM_OUTPUT)
|
||||
{
|
||||
RETURN_ON_MODEL5
|
||||
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
|
||||
return ;
|
||||
else if (PWM_OUTPUT==mode || PWM_MS_OUTPUT==mode || PWM_BAL_OUTPUT==mode) {
|
||||
|
||||
usingGpioMemCheck ("pinMode PWM") ;
|
||||
usingGpioMemCheck("pinMode PWM") ; // exit on error!
|
||||
alt = gpioToPwmALT[pin];
|
||||
if (0==alt) { // Not a hardware capable PWM pin
|
||||
return;
|
||||
}
|
||||
int channel = gpioToPwmPort[pin];
|
||||
if (PI_MODEL_5 == RaspberryPiModel) {
|
||||
if (channel>=0 && channel<=3) {
|
||||
// enable channel pwm m:s mode
|
||||
pwm[RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_CTRL] = (RP1_PWM_TRAIL_EDGE_MS | RP1_PWM_FIFO_POP_MASK);
|
||||
// enable pwm global
|
||||
unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL];
|
||||
pwm[RP1_PWM0_GLOBAL_CTRL] = ctrl | (1<<channel) | RP1_PWM_CTRL_SETUPDATE;
|
||||
//printf("Enable PWM0[%d] (0x%08X->0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]);
|
||||
//change GPIO mode
|
||||
pads[1+pin] = RP1_PAD_DEFAULT_FROM9; // enable output
|
||||
pinModeAlt(origPin, alt); //switch to PWM mode
|
||||
}
|
||||
} else {
|
||||
// Set pin to PWM mode
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
|
||||
// Set pin to PWM mode
|
||||
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
|
||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi
|
||||
|
||||
pwmSetMode (PWM_MODE_BAL) ; // Pi default mode
|
||||
pwmSetRange (1024) ; // Default range of 1024
|
||||
pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
|
||||
if (PWM_OUTPUT==mode || PWM_BAL_OUTPUT==mode) {
|
||||
pwmSetMode(PWM_MODE_BAL); // Pi default mode
|
||||
} else {
|
||||
pwmSetMode(PWM_MODE_MS);
|
||||
}
|
||||
}
|
||||
if (PWM_OUTPUT==mode) { // predefine
|
||||
pwmSetRange (1024) ; // Default range of 1024
|
||||
pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
|
||||
}
|
||||
}
|
||||
else if (mode == GPIO_CLOCK)
|
||||
{
|
||||
@@ -2121,7 +2294,6 @@ void pwmWrite (int pin, int value)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
|
||||
FailOnModel5();
|
||||
setupCheck ("pwmWrite") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
@@ -2133,8 +2305,29 @@ void pwmWrite (int pin, int value)
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return ;
|
||||
|
||||
/* would be possible on ms mode but not on bal, deactivated, use pwmc modify instead
|
||||
if (piGpioBase == GPIO_PERI_BASE_2711) {
|
||||
value = (OSC_FREQ_BCM2711*value)/OSC_FREQ_DEFAULT;
|
||||
}
|
||||
*/
|
||||
usingGpioMemCheck ("pwmWrite") ;
|
||||
*(pwm + gpioToPwmPort [pin]) = value ;
|
||||
int channel = gpioToPwmPort[pin];
|
||||
int readback = 0x00;
|
||||
if (PI_MODEL_5 == RaspberryPiModel ) {
|
||||
if (channel>=0 && channel<=3) {
|
||||
unsigned int addr = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_DUTY;
|
||||
pwm[addr] = value;
|
||||
readback = pwm[addr];
|
||||
} else {
|
||||
fprintf(stderr, "pwmWrite: invalid channel at GPIO pin %d \n", pin);
|
||||
}
|
||||
} else {
|
||||
*(pwm + channel) = value ;
|
||||
readback = *(pwm + channel);
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("PWM value(duty): %u. Current register: 0x%08X\n", value, readback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2191,8 +2384,6 @@ void analogWrite (int pin, int value)
|
||||
|
||||
void pwmToneWrite (int pin, int freq)
|
||||
{
|
||||
FailOnModel5();
|
||||
|
||||
setupCheck ("pwmToneWrite") ;
|
||||
|
||||
if (freq == 0)
|
||||
@@ -2230,7 +2421,7 @@ void digitalWriteByte (const int value)
|
||||
int mask = 1 ;
|
||||
int pin ;
|
||||
|
||||
FailOnModel5();
|
||||
FailOnModel5("digitalWriteByte");
|
||||
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||
{
|
||||
@@ -2259,7 +2450,7 @@ unsigned int digitalReadByte (void)
|
||||
uint32_t raw ;
|
||||
uint32_t data = 0 ;
|
||||
|
||||
FailOnModel5();
|
||||
FailOnModel5("digitalReadByte");
|
||||
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||
{
|
||||
@@ -2290,7 +2481,7 @@ unsigned int digitalReadByte (void)
|
||||
|
||||
void digitalWriteByte2 (const int value)
|
||||
{
|
||||
FailOnModel5();
|
||||
FailOnModel5("digitalWriteByte2");
|
||||
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||
{
|
||||
@@ -2306,7 +2497,7 @@ unsigned int digitalReadByte2 (void)
|
||||
{
|
||||
uint32_t data = 0 ;
|
||||
|
||||
FailOnModel5();
|
||||
FailOnModel5("digitalReadByte2");
|
||||
|
||||
if (wiringPiMode == WPI_MODE_GPIO_SYS)
|
||||
{
|
||||
@@ -2722,6 +2913,15 @@ unsigned int micros (void)
|
||||
return (uint32_t)(now - epochMicro) ;
|
||||
}
|
||||
|
||||
|
||||
unsigned long long piMicros64(void) {
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ;
|
||||
uint64_t now = (uint64_t)ts.tv_sec * (uint64_t)1000000 + (uint64_t)(ts.tv_nsec / 1000) ;
|
||||
return (now - epochMicro) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* wiringPiVersion:
|
||||
* Return our current version number
|
||||
@@ -2868,6 +3068,17 @@ int wiringPiSetup (void)
|
||||
if (PI_MODEL_5 == model) {
|
||||
gpiomemGlobal = pciemem_RP1;
|
||||
gpiomemModule = gpiomem_RP1;
|
||||
|
||||
// PWM alt pins @RP1 - need to be translated to RP1_FSEL with pinModeAlt
|
||||
gpioToPwmALT[12] = FSEL_ALT0;
|
||||
gpioToPwmALT[13] = FSEL_ALT0;
|
||||
gpioToPwmALT[18] = FSEL_ALT3;
|
||||
gpioToPwmALT[19] = FSEL_ALT3;
|
||||
//PWM0 channel @RP1
|
||||
gpioToPwmPort[12] = 0;
|
||||
gpioToPwmPort[13] = 1;
|
||||
gpioToPwmPort[18] = 2;
|
||||
gpioToPwmPort[19] = 3;
|
||||
}
|
||||
|
||||
usingGpioMem = FALSE;
|
||||
@@ -2894,10 +3105,10 @@ int wiringPiSetup (void)
|
||||
if (PI_MODEL_5 != model) {
|
||||
//Set the offsets into the memory interface.
|
||||
|
||||
GPIO_PADS = piGpioBase + 0x00100000 ;
|
||||
GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ;
|
||||
GPIO_PADS = piGpioBase + 0x00100000 ;
|
||||
GPIO_CLOCK_ADR = piGpioBase + 0x00101000 ;
|
||||
GPIO_BASE = piGpioBase + 0x00200000 ;
|
||||
GPIO_TIMER = piGpioBase + 0x0000B000 ;
|
||||
GPIO_TIMER = piGpioBase + 0x0000B000 ;
|
||||
GPIO_PWM = piGpioBase + 0x0020C000 ;
|
||||
GPIO_RIO = 0x00 ;
|
||||
|
||||
@@ -2917,7 +3128,7 @@ int wiringPiSetup (void)
|
||||
|
||||
// Clock control (needed for PWM)
|
||||
|
||||
clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ;
|
||||
clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_ADR) ;
|
||||
if (clk == MAP_FAILED)
|
||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
|
||||
|
||||
@@ -2953,7 +3164,7 @@ int wiringPiSetup (void)
|
||||
unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size;
|
||||
|
||||
GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ;
|
||||
GPIO_CLOCK_BASE = 0x00;
|
||||
GPIO_CLOCK_ADR = (RP1_CLOCK_Addr-RP1_BASE_Addr);
|
||||
GPIO_BASE = (RP1_IO0_Addr-RP1_BASE_Addr) ;
|
||||
GPIO_TIMER = 0x00;
|
||||
GPIO_PWM = RP1_PWM0_Addr-RP1_BASE_Addr;
|
||||
@@ -2965,8 +3176,12 @@ int wiringPiSetup (void)
|
||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
|
||||
if (usingGpioMem) {
|
||||
gpio = base; // RP1 start adress of map memory for gpio (same as module memory)
|
||||
pwm = NULL; // outside of mapped memory, PWM not available from none root
|
||||
clk = NULL; // outside of mapped memory, CLK main not available from none root
|
||||
} else {
|
||||
gpio = &base[GPIO_BASE/4];// RP1 start adress of map memory for gpio
|
||||
gpio = &base[GPIO_BASE/4]; // RP1 start adress of map memory for gpio
|
||||
pwm = &base[GPIO_PWM/4]; // RP1 start adress of map memory for pwm0
|
||||
clk = &base[GPIO_CLOCK_ADR/4]; // RP1 start adress of map memory for clocks_main
|
||||
}
|
||||
pads = &gpio[GPIO_PADS/4]; // RP1 start adress of map memory for pads
|
||||
rio = &gpio[GPIO_RIO/4]; // RP1 start adress of map memory for rio
|
||||
@@ -2976,19 +3191,19 @@ int wiringPiSetup (void)
|
||||
// Export the base addresses for any external software that might need them
|
||||
_wiringPiBase = base ;
|
||||
_wiringPiGpio = gpio ;
|
||||
_wiringPiPwm = NULL ;
|
||||
_wiringPiClk = NULL ;
|
||||
_wiringPiPwm = pwm ;
|
||||
_wiringPiClk = clk ;
|
||||
_wiringPiPads = pads ;
|
||||
_wiringPiTimer = NULL ;
|
||||
_wiringPiRio = rio ;
|
||||
}
|
||||
if (wiringPiDebug) {
|
||||
printf ("wiringPi: memory map gpio 0x%x %s\n", GPIO_BASE , _wiringPiGpio ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map pads 0x%x %s\n", GPIO_PADS , _wiringPiPads ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map rio 0x%x %s\n", GPIO_RIO , _wiringPiRio ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map pwm 0x%x %s\n", GPIO_PWM , _wiringPiPwm ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map clk 0x%x %s\n", GPIO_CLOCK_BASE, _wiringPiClk ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map timer 0x%x %s\n", GPIO_TIMER,_wiringPiTimer ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map gpio 0x%x %s\n", GPIO_BASE , _wiringPiGpio ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map pads 0x%x %s\n", GPIO_PADS , _wiringPiPads ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map rio 0x%x %s\n", GPIO_RIO , _wiringPiRio ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map pwm0 0x%x %s\n", GPIO_PWM , _wiringPiPwm ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map clocks 0x%x %s\n", GPIO_CLOCK_ADR, _wiringPiClk ? "valid" : "invalid");
|
||||
printf ("wiringPi: memory map timer 0x%x %s\n", GPIO_TIMER ,_wiringPiTimer ? "valid" : "invalid");
|
||||
}
|
||||
|
||||
initialiseEpoch () ;
|
||||
|
||||
@@ -58,10 +58,12 @@
|
||||
|
||||
// Pin modes
|
||||
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
#define PWM_OUTPUT 2
|
||||
#define GPIO_CLOCK 3
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
#define PWM_OUTPUT 2
|
||||
#define PWM_MS_OUTPUT 8
|
||||
#define PWM_BAL_OUTPUT 9
|
||||
#define GPIO_CLOCK 3
|
||||
#define SOFT_PWM_OUTPUT 4
|
||||
#define SOFT_TONE_OUTPUT 5
|
||||
#define PWM_TONE_OUTPUT 6
|
||||
@@ -268,6 +270,7 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio
|
||||
extern int piGpioLayout (void) ;
|
||||
extern int piBoardRev (void) ; // Deprecated, but does the same as piGpioLayout
|
||||
extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ;
|
||||
extern int piBoard40Pin (void) ; // Interface V3.7
|
||||
extern int wpiPinToGpio (int wpiPin) ;
|
||||
extern int physPinToGpio (int physPin) ;
|
||||
extern void setPadDrive (int group, int value) ;
|
||||
@@ -308,6 +311,8 @@ extern void delayMicroseconds (unsigned int howLong) ;
|
||||
extern unsigned int millis (void) ;
|
||||
extern unsigned int micros (void) ;
|
||||
|
||||
extern unsigned long long piMicros64(void); // Interface V3.7
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user