Przeglądaj źródła

Merge pull request #270 from WiringPi/pwm

PI5 PWM
pull/273/head
Manfred Wallner 2 miesięcy temu
committed by GitHub
rodzic
commit
86f1061acc
Nie znaleziono w bazie danych klucza dla tego podpisu ID klucza GPG: B5690EEEBB952194
17 zmienionych plików z 1035 dodań i 198 usunięć
  1. +1
    -1
      VERSION
  2. +1
    -1
      gpio/gpio.c
  3. +2
    -2
      version.h
  4. +47
    -22
      wiringPi/test/Makefile
  5. +133
    -0
      wiringPi/test/wiringpi_piface_test1.c
  6. +7
    -2
      wiringPi/test/wiringpi_test1_sysfs.c
  7. +7
    -2
      wiringPi/test/wiringpi_test2_sysfs.c
  8. +7
    -2
      wiringPi/test/wiringpi_test3_device_wpi.c
  9. +7
    -2
      wiringPi/test/wiringpi_test4_device_phys.c
  10. +6
    -2
      wiringPi/test/wiringpi_test5_default.c
  11. +53
    -47
      wiringPi/test/wiringpi_test6_isr.c
  12. +186
    -0
      wiringPi/test/wiringpi_test8_pwm.c
  13. +225
    -0
      wiringPi/test/wiringpi_test9_pwm.c
  14. +1
    -1
      wiringPi/test/wiringpi_xotest_test1_spi.c
  15. +24
    -6
      wiringPi/test/wpi_test.h
  16. +319
    -104
      wiringPi/wiringPi.c
  17. +9
    -4
      wiringPi/wiringPi.h

+ 1
- 1
VERSION Wyświetl plik

@@ -1 +1 @@
3.6
3.7

+ 1
- 1
gpio/gpio.c Wyświetl plik

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



+ 2
- 2
version.h Wyświetl plik

@@ -1,3 +1,3 @@
#define VERSION "3.6"
#define VERSION "3.7"
#define VERSION_MAJOR 3
#define VERSION_MINOR 6
#define VERSION_MINOR 7

+ 47
- 22
wiringPi/test/Makefile Wyświetl plik

@@ -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
- 0
wiringPi/test/wiringpi_piface_test1.c Wyświetl plik

@@ -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
- 2
wiringPi/test/wiringpi_test1_sysfs.c Wyświetl plik

@@ -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
- 2
wiringPi/test/wiringpi_test2_sysfs.c Wyświetl plik

@@ -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
- 2
wiringPi/test/wiringpi_test3_device_wpi.c Wyświetl plik

@@ -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
- 2
wiringPi/test/wiringpi_test4_device_phys.c Wyświetl plik

@@ -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);



+ 6
- 2
wiringPi/test/wiringpi_test5_default.c Wyświetl plik

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


+ 53
- 47
wiringPi/test/wiringpi_test6_isr.c Wyświetl plik

@@ -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 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);

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();
}

+ 186
- 0
wiringPi/test/wiringpi_test8_pwm.c Wyświetl plik

@@ -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
- 0
wiringPi/test/wiringpi_test9_pwm.c Wyświetl plik

@@ -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();
}

+ 1
- 1
wiringPi/test/wiringpi_xotest_test1_spi.c Wyświetl plik

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



+ 24
- 6
wiringPi/test/wpi_test.h Wyświetl plik

@@ -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);


+ 319
- 104
wiringPi/wiringPi.c Wyświetl plik

@@ -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") ;

// 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)
{
@@ -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 () ;


+ 9
- 4
wiringPi/wiringPi.h Wyświetl plik

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


Ładowanie…
Anuluj
Zapisz