@@ -1,11 +1,16 @@ | |||||
# WiringPi | |||||
# WiringPi Library | |||||
Welcome to the WiringPi Library, the highly performant GPIO access library for Raspberry Pi boards. This library is written in C and is designed to provide fast and efficient control of the GPIO pins by directly accessing the hardware registers using DMA. | |||||
WiringPi is a _performant_ GPIO access library written in C for Raspberry Pi boards. | |||||
**Key Features:** | |||||
- **Support:** WiringPi supports all Raspberry Pi Boards including Pi 5 ( :construction: On the Pi 5, only the GCLK functionality is currently not supported due to missing documentation of the RP1 chip). | |||||
- **High Performance:** By directly accessing the hardware registers, WiringPi ensures minimal latency and maximum performance for your GPIO operations. | |||||
- **Wide Adoption:** WiringPi is widely used in numerous projects, making it a reliable choice for your Raspberry Pi GPIO needs. | |||||
:warning:️ :construction: on Pi5, PWM support is currently under development and _will not work at this point_. If you're interested in the progress, please check the [corresponding issue](https://github.com/GrazerComputerClub/WiringPi/issues/21). | |||||
Whether you’re working on a simple LED blink project or a complex automation system, WiringPi provides the tools you need to get the job done efficiently. | |||||
## How to use | |||||
To compile programs with wiringPi, you need to include `wiringPi.h` as well as link against `wiringPi`: | |||||
To compile programs with wiringPi Library, you need to include `wiringPi.h` as well as link against `wiringPi`: | |||||
```c | ```c | ||||
#include <wiringPi.h> // Include WiringPi library! | #include <wiringPi.h> // Include WiringPi library! | ||||
@@ -143,7 +148,7 @@ Please don't email GC2 for reporting issues, you might [contact us](mailto:wirin | |||||
## History | ## History | ||||
This repository is the continuation of 'Gordon's wiringPi' which has been [deprecated](https://web.archive.org/web/20220405225008/http://wiringpi.com/wiringpi-deprecated/), a while ago. | |||||
This repository is the continuation of 'Gordon's wiringPi 2.5' which has been [deprecated](https://web.archive.org/web/20220405225008/http://wiringpi.com/wiringpi-deprecated/), a while ago. | |||||
* The last "old wiringPi" source of Gordon's release can be found at the | * The last "old wiringPi" source of Gordon's release can be found at the | ||||
[`final_source_2.50`](https://github.com/WiringPi/WiringPi/tree/final_official_2.50) tag. | [`final_source_2.50`](https://github.com/WiringPi/WiringPi/tree/final_official_2.50) tag. | ||||
@@ -1 +1 @@ | |||||
3.6 | |||||
3.8 |
@@ -816,7 +816,7 @@ static void doPwmClock (int argc, char *argv []) | |||||
if ((clock < 1) || (clock > 4095)) | 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) ; | exit (1) ; | ||||
} | } | ||||
@@ -1,3 +1,3 @@ | |||||
#define VERSION "3.6" | |||||
#define VERSION "3.8" | |||||
#define VERSION_MAJOR 3 | #define VERSION_MAJOR 3 | ||||
#define VERSION_MINOR 6 | |||||
#define VERSION_MINOR 8 |
@@ -1,47 +1,64 @@ | |||||
CC = gcc | CC = gcc | ||||
CFLAGS = -Wall | 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 | ${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 | ${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 | ${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 | ${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 | ${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 | ${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 | ${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: | 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: | wiringpi_i2c_test1_pcf8574: | ||||
${CC} ${CFLAGS} wiringpi_i2c_test1_pcf8574.c -o wiringpi_i2c_test1_pcf8574 -lwiringPi | ${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 \ | ||||
echo === unit test: $${t} === ; \ | 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 \ | if [ $$? -ne 0 ]; then \ | ||||
error_state=true ; \ | error_state=true ; \ | ||||
fi ; \ | fi ; \ | ||||
@@ -57,7 +74,11 @@ xotest: | |||||
@error_state=false ; \ | @error_state=false ; \ | ||||
for t in $(tests) $(xotests) ; do \ | for t in $(tests) $(xotests) ; do \ | ||||
echo === XO unit test: $${t} === ; \ | 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 \ | if [ $$? -ne 0 ]; then \ | ||||
error_state=true ; \ | error_state=true ; \ | ||||
fi ; \ | fi ; \ | ||||
@@ -69,23 +90,27 @@ xotest: | |||||
echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \ | echo "\n\e[5mSTD/XO TEST SUCCESS\e[0m\n"; \ | ||||
fi | fi | ||||
i2ctest: | |||||
pifacetest: | |||||
@error_state=false ; \ | @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 \ | if [ $$? -ne 0 ]; then \ | ||||
error_state=true ; \ | error_state=true ; \ | ||||
fi ; \ | fi ; \ | ||||
echo ; echo ; \ | echo ; echo ; \ | ||||
done | done | ||||
if [ "$$error_state" = true ]; then \ | 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 \ | else \ | ||||
echo "\n\e[5mSTD/I2C TEST SUCCESS\e[0m\n"; \ | |||||
echo "\n\e[5mPIFACE TEST SUCCESS\e[0m\n"; \ | |||||
fi | fi | ||||
clean: | |||||
for t in $(tests) $(xotests) $(i2ctests) ; do \ | |||||
clean: | |||||
for t in $(tests) $(xotests) $(pifacetests) ; do \ | |||||
rm -fv $${t} ; \ | rm -fv $${t} ; \ | ||||
done | done |
@@ -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> | #include <sys/time.h> | ||||
const int GPIO = 19; | |||||
const int GPIOIN = 26; | |||||
int GPIO = 19; | |||||
int GPIOIN = 26; | |||||
const int ToggleValue = 4; | const int ToggleValue = 4; | ||||
@@ -21,6 +21,11 @@ int main (void) { | |||||
printf("wiringPiSetupSys failed\n\n"); | printf("wiringPiSetupSys failed\n\n"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} | } | ||||
if (!piBoard40Pin()) { | |||||
GPIO = 23; | |||||
GPIOIN = 24; | |||||
} | |||||
pinMode(GPIOIN, INPUT); | pinMode(GPIOIN, INPUT); | ||||
pinMode(GPIO, OUTPUT); | pinMode(GPIO, OUTPUT); | ||||
@@ -7,8 +7,8 @@ | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
const int GPIO = 19; | |||||
const int GPIOIN = 26; | |||||
int GPIO = 19; | |||||
int GPIOIN = 26; | |||||
const int ToggleValue = 4; | const int ToggleValue = 4; | ||||
@@ -21,6 +21,11 @@ int main (void) { | |||||
printf("wiringPiSetupSys failed\n\n"); | printf("wiringPiSetupSys failed\n\n"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} | } | ||||
if (!piBoard40Pin()) { | |||||
GPIO = 23; | |||||
GPIOIN = 24; | |||||
} | |||||
pinMode(GPIOIN, INPUT); | pinMode(GPIOIN, INPUT); | ||||
pinMode(GPIO, OUTPUT); | pinMode(GPIO, OUTPUT); | ||||
@@ -7,8 +7,8 @@ | |||||
#include <sys/time.h> | #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; | const int ToggleValue = 4; | ||||
@@ -21,6 +21,11 @@ int main (void) { | |||||
printf("wiringPiSetupGpioDevice failed\n\n"); | printf("wiringPiSetupGpioDevice failed\n\n"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} | } | ||||
if (!piBoard40Pin()) { | |||||
GPIO = 4; //BCM 23 | |||||
GPIOIN = 5; //BCM 24 | |||||
} | |||||
pinMode(GPIOIN, INPUT); | pinMode(GPIOIN, INPUT); | ||||
pinMode(GPIO, OUTPUT); | pinMode(GPIO, OUTPUT); | ||||
@@ -7,8 +7,8 @@ | |||||
#include <sys/time.h> | #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; | const int ToggleValue = 4; | ||||
@@ -21,6 +21,11 @@ int main (void) { | |||||
printf("wiringPiSetupGpioDevice failed\n\n"); | printf("wiringPiSetupGpioDevice failed\n\n"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | ||||
} | } | ||||
if (!piBoard40Pin()) { | |||||
GPIO = 16; //BCM 23 | |||||
GPIOIN = 18; //BCM 24 | |||||
} | |||||
pinMode(GPIOIN, INPUT); | pinMode(GPIOIN, INPUT); | ||||
pinMode(GPIO, OUTPUT); | pinMode(GPIO, OUTPUT); | ||||
@@ -7,8 +7,8 @@ | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
const int GPIO = 19; | |||||
const int GPIOIN = 26; | |||||
int GPIO = 19; | |||||
int GPIOIN = 26; | |||||
const int ToggleValue = 4; | const int ToggleValue = 4; | ||||
int RaspberryPiModel = -1; | int RaspberryPiModel = -1; | ||||
@@ -58,6 +58,10 @@ int main (void) { | |||||
} else { | } else { | ||||
printf("Raspberry Pi with BCM GPIO found (not Pi 5)\n"); | printf("Raspberry Pi with BCM GPIO found (not Pi 5)\n"); | ||||
} | } | ||||
if (!piBoard40Pin()) { | |||||
GPIO = 23; | |||||
GPIOIN = 24; | |||||
} | |||||
enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN; | enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN; | ||||
@@ -8,8 +8,8 @@ | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
const int GPIO = 19; | |||||
const int GPIOIN = 26; | |||||
int GPIO = 19; | |||||
int GPIOIN = 26; | |||||
const int ToggleValue = 4; | const int ToggleValue = 4; | ||||
@@ -115,55 +115,61 @@ double DurationTime(int Enge, int OUTpin, int IRQpin) { | |||||
return fTime; | return fTime; | ||||
} | } | ||||
int main (void) { | int main (void) { | ||||
const int IRQpin = GPIOIN ; | |||||
const int OUTpin = GPIO ; | |||||
int major, minor; | |||||
wiringPiVersion(&major, &minor); | |||||
int major, minor; | |||||
wiringPiVersion(&major, &minor); | |||||
printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); | printf("WiringPi GPIO test program 1 (using GPIO%d (output) and GPIO%d (input))\n", GPIO, GPIOIN); | ||||
printf(" testing irq\n"); | printf(" testing irq\n"); | ||||
printf("\nISR test (WiringPi %d.%d)\n", major, minor); | |||||
wiringPiSetupGpio() ; | |||||
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 falling\n", IRQpin, OUTpin); | |||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ; | |||||
sleep(1); | |||||
StartSequence (INT_EDGE_FALLING, OUTpin); | |||||
printf("Testing close\n"); | |||||
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) ; | |||||
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("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); | |||||
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin); | |||||
} | |||||
pinMode(OUTpin, INPUT); | |||||
return UnitTestState(); | |||||
printf("\nISR test (WiringPi %d.%d)\n", major, minor); | |||||
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 falling\n", IRQpin, OUTpin); | |||||
wiringPiISR (IRQpin, INT_EDGE_FALLING, &wfi) ; | |||||
sleep(1); | |||||
StartSequence (INT_EDGE_FALLING, OUTpin); | |||||
printf("Testing close\n"); | |||||
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) ; | |||||
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("Measuring duration IRQ @ GPIO%d with trigger @ GPIO%d falling\n", IRQpin, OUTpin); | |||||
DurationTime(INT_EDGE_FALLING, OUTpin, IRQpin); | |||||
} | |||||
pinMode(OUTpin, INPUT); | |||||
return UnitTestState(); | |||||
} | } |
@@ -0,0 +1,187 @@ | |||||
// 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; //Problem with Pi0/1 after setting, PWM stops working, maybe IRQ problem or PWM BAL with that high freq (>2 MHz) | |||||
pwmc = 35; //PWM BAL would be >400 kHz | |||||
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(); | |||||
} |
@@ -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, 200, 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); | int CH1 = AnalogRead(spiChannel, 1, &returnvalue); | ||||
//float value0 = CH0 * fRefVoltage / fResolution; | //float value0 = CH0 * fRefVoltage / fResolution; | ||||
float value1 = CH1 * fRefVoltage / fResolution; | float value1 = CH1 * fRefVoltage / fResolution; | ||||
CheckSameFloat(szexpect, value1, expect); | |||||
CheckSameFloat(szexpect, value1, expect, 0.1); | |||||
delayMicroseconds(300); | delayMicroseconds(300); | ||||
} | } | ||||
@@ -20,14 +20,14 @@ void CheckGPIO(int GPIO, int GPIOIN, int out) { | |||||
int in = out; | int in = out; | ||||
if (GPIOIN>=0) { | if (GPIOIN>=0) { | ||||
in = digitalRead(GPIOIN); | |||||
in = digitalRead(GPIOIN); | |||||
} | } | ||||
int readback = digitalRead(GPIO); | int readback = digitalRead(GPIO); | ||||
int pass = 0; | int pass = 0; | ||||
if (out==readback && in==out) { | |||||
pass = 1; | |||||
} | |||||
if (out==readback && in==out) { | |||||
pass = 1; | |||||
} | |||||
if (GPIOIN>=0) { | if (GPIOIN>=0) { | ||||
printf("set GPIO%02d = %d (readback %d), in GPIO%02d = %d ", GPIO, out, readback, GPIOIN, in); | 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) { | void digitalWriteEx(int GPIO, int GPIOIN, int mode) { | ||||
digitalWrite(GPIO, mode); | digitalWrite(GPIO, mode); | ||||
delayMicroseconds(5000); | 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); | printf("%35s (%.3f==%.3f) -> %spassed%s \n", msg, value, expect, COLORGRN, COLORDEF); | ||||
} else { | } else { | ||||
printf("%35s (%.3f<>%.3f) -> %sfailed%s \n" , msg, value, expect, COLORRED, COLORDEF); | printf("%35s (%.3f<>%.3f) -> %sfailed%s \n" , msg, value, expect, COLORRED, COLORDEF); | ||||
@@ -118,14 +118,20 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; | |||||
// Port function select bits | // 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 | //RP1 chip (@Pi5) - 3.1.1. Function select | ||||
#define RP1_FSEL_ALT0 0x00 | #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_PAD_DRIVE_MASK = 0x00000030; | ||||
const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK); | 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 | //RP1 chip (@Pi5) address | ||||
const unsigned long long RP1_64_BASE_Addr = 0x1f000d0000; | const unsigned long long RP1_64_BASE_Addr = 0x1f000d0000; | ||||
const unsigned int RP1_BASE_Addr = 0x40000000; | 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_IO0_Addr = 0x400d0000; | ||||
const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000; | const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000; | ||||
const unsigned int RP1_PADS0_Addr = 0x400f0000; | 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; | const unsigned short pciemem_RP1_Device= 0x0001; | ||||
static volatile unsigned int GPIO_PADS ; | 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_BASE ; | ||||
static volatile unsigned int GPIO_TIMER ; | static volatile unsigned int GPIO_TIMER ; | ||||
static volatile unsigned int GPIO_PWM ; | static volatile unsigned int GPIO_PWM ; | ||||
@@ -238,6 +274,11 @@ static int wiringPiSetuped = FALSE ; | |||||
#define PWM1_SERIAL 0x0200 // Run in serial mode | #define PWM1_SERIAL 0x0200 // Run in serial mode | ||||
#define PWM1_ENABLE 0x0100 // Channel Enable | #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 | // Timer | ||||
// Word offsets | // Word offsets | ||||
@@ -557,6 +598,27 @@ int piBoard() { | |||||
return RaspberryPiModel<0 ? 0 : 1; | 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() { | int GetMaxPin() { | ||||
return PI_MODEL_5 == RaspberryPiModel ? 27 : 63; | 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; } | #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) { | 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; | return 0; | ||||
} | } | ||||
@@ -690,8 +752,8 @@ static uint8_t gpioToPUDCLK [] = | |||||
static uint8_t gpioToPwmALT [] = | static uint8_t gpioToPwmALT [] = | ||||
{ | { | ||||
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 | 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, // 24 -> 31 | ||||
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 | 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 | ||||
FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47 | 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 [] = | static uint8_t gpioToPwmPort [] = | ||||
{ | { | ||||
0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 | 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, // 24 -> 31 | ||||
0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 | 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 | ||||
PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47 | 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_4B: | ||||
case PI_MODEL_400: | case PI_MODEL_400: | ||||
case PI_MODEL_CM4: | case PI_MODEL_CM4: | ||||
case PI_MODEL_CM4S: | |||||
piGpioBase = GPIO_PERI_BASE_2711 ; | piGpioBase = GPIO_PERI_BASE_2711 ; | ||||
piGpioPupOffset = GPPUPPDN0 ; | piGpioPupOffset = GPPUPPDN0 ; | ||||
break ; | break ; | ||||
@@ -1261,7 +1324,7 @@ void setPadDrive (int group, int value) | |||||
int getAlt (int pin) | int getAlt (int pin) | ||||
{ | { | ||||
int fSel, shift, alt ; | |||||
int alt; | |||||
pin &= 63 ; | pin &= 63 ; | ||||
@@ -1292,29 +1355,28 @@ int getAlt (int pin) | |||||
11 = alternate function 9 | 11 = alternate function 9 | ||||
*/ | */ | ||||
switch(alt) { | 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: { | case RP1_FSEL_GPIO: { | ||||
unsigned int outputmask = gpio[2*pin] & 0x3000; //Bit13-OETOPAD + Bit12-OEFROMPERI | 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; | default:return alt; | ||||
} | } | ||||
} else { | } else { | ||||
fSel = gpioToGPFSEL [pin] ; | |||||
shift = gpioToShift [pin] ; | |||||
int fSel = gpioToGPFSEL [pin] ; | |||||
int shift = gpioToShift [pin] ; | |||||
alt = (*(gpio + fSel) >> shift) & 7 ; | 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)) | 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 ; | *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; | ||||
else | |||||
} else { | |||||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; | *(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) | void pwmSetRange (unsigned int range) | ||||
{ | { | ||||
FailOnModel5(); | |||||
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) | 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) | void pwmSetClock (int divisor) | ||||
{ | { | ||||
uint32_t pwm_control ; | 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 ((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 | pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL | ||||
// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY | // 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 | *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock | ||||
*(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL | *(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 ; | int divi, divr, divf ; | ||||
FailOnModel5(); | |||||
FailOnModel5("gpioClockSet"); | |||||
pin &= 63 ; | pin &= 63 ; | ||||
/**/ if (wiringPiMode == WPI_MODE_PINS) | /**/ if (wiringPiMode == WPI_MODE_PINS) | ||||
@@ -1438,9 +1557,9 @@ void gpioClockSet (int pin, int freq) | |||||
divr = 19200000 % freq ; | divr = 19200000 % freq ; | ||||
divf = (int)((double)divr * 4096.0 / 19200000.0) ; | 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 | *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock | ||||
while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait | 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) | void pinModeAlt (int pin, int mode) | ||||
{ | { | ||||
int fSel, shift ; | |||||
RETURN_ON_MODEL5 | |||||
setupCheck ("pinModeAlt") ; | setupCheck ("pinModeAlt") ; | ||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin | if ((pin & PI_GPIO_MASK) == 0) // On-board pin | ||||
@@ -1628,20 +1744,49 @@ void pinModeAlt (int pin, int mode) | |||||
return ; | return ; | ||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
//confusion! diffrent to to BCM! this is taking directly the value for the register | //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 { | } else { | ||||
fSel = gpioToGPFSEL [pin] ; | |||||
shift = gpioToShift [pin] ; | |||||
int fSel = gpioToGPFSEL [pin] ; | |||||
int shift = gpioToShift [pin] ; | |||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; | *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; | ||||
} | } | ||||
@@ -1749,6 +1894,15 @@ void pinMode (int pin, int mode) | |||||
} else { | } else { | ||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input | *(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) { | } else if (mode == OUTPUT) { | ||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; | 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 | pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode | ||||
pwmSetMode (PWM_MODE_MS) ; | 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") ; | |||||
// Set pin to PWM mode | |||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | |||||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi | |||||
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 | |||||
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) | else if (mode == GPIO_CLOCK) | ||||
{ | { | ||||
@@ -2121,7 +2294,6 @@ void pwmWrite (int pin, int value) | |||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
FailOnModel5(); | |||||
setupCheck ("pwmWrite") ; | setupCheck ("pwmWrite") ; | ||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | 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) | else if (wiringPiMode != WPI_MODE_GPIO) | ||||
return ; | 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") ; | 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 | else | ||||
{ | { | ||||
@@ -2191,8 +2384,6 @@ void analogWrite (int pin, int value) | |||||
void pwmToneWrite (int pin, int freq) | void pwmToneWrite (int pin, int freq) | ||||
{ | { | ||||
FailOnModel5(); | |||||
setupCheck ("pwmToneWrite") ; | setupCheck ("pwmToneWrite") ; | ||||
if (freq == 0) | if (freq == 0) | ||||
@@ -2230,7 +2421,7 @@ void digitalWriteByte (const int value) | |||||
int mask = 1 ; | int mask = 1 ; | ||||
int pin ; | int pin ; | ||||
FailOnModel5(); | |||||
FailOnModel5("digitalWriteByte"); | |||||
if (wiringPiMode == WPI_MODE_GPIO_SYS) | if (wiringPiMode == WPI_MODE_GPIO_SYS) | ||||
{ | { | ||||
@@ -2259,7 +2450,7 @@ unsigned int digitalReadByte (void) | |||||
uint32_t raw ; | uint32_t raw ; | ||||
uint32_t data = 0 ; | uint32_t data = 0 ; | ||||
FailOnModel5(); | |||||
FailOnModel5("digitalReadByte"); | |||||
if (wiringPiMode == WPI_MODE_GPIO_SYS) | if (wiringPiMode == WPI_MODE_GPIO_SYS) | ||||
{ | { | ||||
@@ -2290,7 +2481,7 @@ unsigned int digitalReadByte (void) | |||||
void digitalWriteByte2 (const int value) | void digitalWriteByte2 (const int value) | ||||
{ | { | ||||
FailOnModel5(); | |||||
FailOnModel5("digitalWriteByte2"); | |||||
if (wiringPiMode == WPI_MODE_GPIO_SYS) | if (wiringPiMode == WPI_MODE_GPIO_SYS) | ||||
{ | { | ||||
@@ -2306,7 +2497,7 @@ unsigned int digitalReadByte2 (void) | |||||
{ | { | ||||
uint32_t data = 0 ; | uint32_t data = 0 ; | ||||
FailOnModel5(); | |||||
FailOnModel5("digitalReadByte2"); | |||||
if (wiringPiMode == WPI_MODE_GPIO_SYS) | if (wiringPiMode == WPI_MODE_GPIO_SYS) | ||||
{ | { | ||||
@@ -2722,6 +2913,15 @@ unsigned int micros (void) | |||||
return (uint32_t)(now - epochMicro) ; | 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: | * wiringPiVersion: | ||||
* Return our current version number | * Return our current version number | ||||
@@ -2868,6 +3068,17 @@ int wiringPiSetup (void) | |||||
if (PI_MODEL_5 == model) { | if (PI_MODEL_5 == model) { | ||||
gpiomemGlobal = pciemem_RP1; | gpiomemGlobal = pciemem_RP1; | ||||
gpiomemModule = gpiomem_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; | usingGpioMem = FALSE; | ||||
@@ -2894,10 +3105,10 @@ int wiringPiSetup (void) | |||||
if (PI_MODEL_5 != model) { | if (PI_MODEL_5 != model) { | ||||
//Set the offsets into the memory interface. | //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_BASE = piGpioBase + 0x00200000 ; | ||||
GPIO_TIMER = piGpioBase + 0x0000B000 ; | |||||
GPIO_TIMER = piGpioBase + 0x0000B000 ; | |||||
GPIO_PWM = piGpioBase + 0x0020C000 ; | GPIO_PWM = piGpioBase + 0x0020C000 ; | ||||
GPIO_RIO = 0x00 ; | GPIO_RIO = 0x00 ; | ||||
@@ -2917,7 +3128,7 @@ int wiringPiSetup (void) | |||||
// Clock control (needed for PWM) | // 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) | if (clk == MAP_FAILED) | ||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; | 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; | unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size; | ||||
GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ; | 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_BASE = (RP1_IO0_Addr-RP1_BASE_Addr) ; | ||||
GPIO_TIMER = 0x00; | GPIO_TIMER = 0x00; | ||||
GPIO_PWM = RP1_PWM0_Addr-RP1_BASE_Addr; | 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)) ; | return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; | ||||
if (usingGpioMem) { | if (usingGpioMem) { | ||||
gpio = base; // RP1 start adress of map memory for gpio (same as module memory) | 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 { | } 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 | 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 | 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 | // Export the base addresses for any external software that might need them | ||||
_wiringPiBase = base ; | _wiringPiBase = base ; | ||||
_wiringPiGpio = gpio ; | _wiringPiGpio = gpio ; | ||||
_wiringPiPwm = NULL ; | |||||
_wiringPiClk = NULL ; | |||||
_wiringPiPwm = pwm ; | |||||
_wiringPiClk = clk ; | |||||
_wiringPiPads = pads ; | _wiringPiPads = pads ; | ||||
_wiringPiTimer = NULL ; | _wiringPiTimer = NULL ; | ||||
_wiringPiRio = rio ; | _wiringPiRio = rio ; | ||||
} | } | ||||
if (wiringPiDebug) { | 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 () ; | initialiseEpoch () ; | ||||
@@ -58,10 +58,12 @@ | |||||
// Pin modes | // 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_PWM_OUTPUT 4 | ||||
#define SOFT_TONE_OUTPUT 5 | #define SOFT_TONE_OUTPUT 5 | ||||
#define PWM_TONE_OUTPUT 6 | #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 piGpioLayout (void) ; | ||||
extern int piBoardRev (void) ; // Deprecated, but does the same as piGpioLayout | 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 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 wpiPinToGpio (int wpiPin) ; | ||||
extern int physPinToGpio (int physPin) ; | extern int physPinToGpio (int physPin) ; | ||||
extern void setPadDrive (int group, int value) ; | 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 millis (void) ; | ||||
extern unsigned int micros (void) ; | extern unsigned int micros (void) ; | ||||
extern unsigned long long piMicros64(void); // Interface V3.7 | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||