diff --git a/VERSION b/VERSION index e4fba21..6324d40 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.12 +3.14 diff --git a/gpio/readall.c b/gpio/readall.c index 8d2ffba..cf0caf4 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -303,35 +303,44 @@ void abReadall (int model, int rev) * Read all the pins on the model A+ or the B+ or actually, all 40-pin Pi's ********************************************************************************* */ +const char piModelNamesShort[PI_MODELS_MAX][11] = +{ + "---Pi A---", // 0 + "---Pi B---", // 1 + "---Pi A+--", // 2 + "---Pi B+--", // 3 + "---Pi 2---", // 4 + "---Alpha--", // 5 + "----CM----", // 6 + "", // 07 + "---Pi 3B--", // 8 + "-Pi Zero--", // 9 + "---CM3----", // 10 + "", // 11 + "-Pi ZeroW-", // 12 + "---Pi 3B+-", // 13 + "---Pi 3A+-", // 14 + "", // 15 + "---CM3+---", // 16 + "---Pi 4B--", // 17 + "Pi Zero 2W", // 18 + "--Pi 400--", // 19 + "---CM4----", // 20 + "---CM4S---", // 21 + "", // 22 + "---Pi 5---", // 23 + "---CM5----", // 24 + "--Pi 500--", // 25 + "---CM5L---", // 24 +} ; static void plus2header (int model) { - /**/ if (model == PI_MODEL_AP) - printf (" +-----+-----+---------+------+---+---Pi A+--+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_BP) - printf (" +-----+-----+---------+------+---+---Pi B+--+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_ZERO) - printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_ZERO_W) - printf (" +-----+-----+---------+------+---+-Pi ZeroW-+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_ZERO_2W) - printf (" +-----+-----+---------+------+---+Pi Zero 2W+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_2) - printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_3B) - printf (" +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_3BP) - printf (" +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_3AP) - printf (" +-----+-----+---------+------+---+---Pi 3A+-+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_4B) - printf (" +-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_400) - printf (" +-----+-----+---------+------+---+---Pi 400-+---+------+---------+-----+-----+\n") ; - else if (model == PI_MODEL_5) - printf (" +-----+-----+---------+------+---+---Pi 5---+---+------+---------+-----+-----+\n") ; - else - printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; + if (model BCM26, +PWM: BCM12 <-> BCM13, BCM18 <-> BCM17 connected (1kOhm) -tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test8_pwm wiringpi_test9_pwm +tests = wiringpi_test0_version wiringpi_test1_sysfs wiringpi_test2_sysfs wiringpi_test3_device_wpi wiringpi_test4_device_phys wiringpi_test5_default wiringpi_test6_isr wiringpi_test7_bench wiringpi_test8_pwm wiringpi_test9_pwm # Need XO hardware xotests = wiringpi_xotest_test1_spi wiringpi_i2c_test1_pcf8574 wiringpi_test8_pwm wiringpi_test9_pwm @@ -13,6 +13,9 @@ pifacetests = wiringpi_piface_test1 wiringpi_test8_pwm wiringpi_test9_pwm all: $(tests) $(xotests) $(pifacetests) +wiringpi_test0_version: + ${CC} ${CFLAGS} wiringpi_test0_version.c -o wiringpi_test0_version -lwiringPi + wiringpi_test1_sysfs: ${CC} ${CFLAGS} wiringpi_test1_sysfs.c -o wiringpi_test1_sysfs -lwiringPi @@ -31,8 +34,8 @@ wiringpi_test5_default: wiringpi_test6_isr: ${CC} ${CFLAGS} wiringpi_test6_isr.c -o wiringpi_test6_isr -lwiringPi -wiringpi_test0_version: - ${CC} ${CFLAGS} wiringpi_test0_version.c -o wiringpi_test0_version -lwiringPi +wiringpi_test7_bench: + ${CC} ${CFLAGS} wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi wiringpi_test8_pwm: ${CC} ${CFLAGS} wiringpi_test8_pwm.c -o wiringpi_test8_pwm -lwiringPi diff --git a/wiringPi/test/wiringpi_test5_default.c b/wiringPi/test/wiringpi_test5_default.c index ecf80bf..818a75f 100644 --- a/wiringPi/test/wiringpi_test5_default.c +++ b/wiringPi/test/wiringpi_test5_default.c @@ -30,7 +30,7 @@ void SetAndCheckMode(int pin, int mode) { case PM_OFF: pinMode(pin, PM_OFF); AltGpio = getPinModeAlt(pin); - CheckSame("Pin mode off(input)", AltGpio, (PI_MODEL_5 == RaspberryPiModel) ? WPI_NONE : WPI_ALT_INPUT); + CheckSame("Pin mode off(input)", AltGpio, (piRP1Model()) ? WPI_NONE : WPI_ALT_INPUT); break; default: pinMode(pin, mode); @@ -53,8 +53,8 @@ int main (void) { int rev, mem, maker, overVolted; piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted); CheckNotSame("Model: ", RaspberryPiModel, -1); - if (PI_MODEL_5 == RaspberryPiModel) { - printf("Raspberry Pi 5 with RP1 found\n"); + if (piRP1Model()) { + printf("Raspberry Pi with RP1 chip found\n"); } else { printf("Raspberry Pi with BCM GPIO found (not Pi 5)\n"); } @@ -66,7 +66,7 @@ int main (void) { enum WPIPinAlt AltGpio = WPI_ALT_UNKNOWN; AltGpio = getPinModeAlt(23); - CheckSame("Pin mode default", AltGpio, PI_MODEL_5 == RaspberryPiModel ? WPI_NONE : WPI_ALT_INPUT); + CheckSame("Pin mode default", AltGpio, piRP1Model() ? WPI_NONE : WPI_ALT_INPUT); SetAndCheckMode(GPIOIN, INPUT); SetAndCheckMode(GPIO, OUTPUT); diff --git a/wiringPi/test/wiringpi_test7_bench.c b/wiringPi/test/wiringpi_test7_bench.c new file mode 100644 index 0000000..f3eb6e2 --- /dev/null +++ b/wiringPi/test/wiringpi_test7_bench.c @@ -0,0 +1,189 @@ +// WiringPi test program: benchmark +// Compile: gcc -Wall wiringpi_test7_bench.c -o wiringpi_test7_bench -lwiringPi + +#include "wpi_test.h" +//#include +//#include +//#include +#include +#include +#include + + +int ToggleValue = 240000000; +float fExpectTimedigitalWrite = 0.1; +float fExpectTimedigitalRead = 0.1; +float fExpectTimepinMode = 0.1; +float fWriteReadDelayFactor = 1.0; +float fWriteReadFactor = 1.0; +float fPi4ExpectTimedigitalWrite = 0.020; +int GPIO = 19; +int GPIOIN = 26; +int RaspberryPiModel = -1; + + +double ReportElapedTime(const char* msg, int multiop, const float fExpectTime, struct timeval t1, struct timeval t2) { + double elapsedTime, fTimePerOperation, fFreq; + + elapsedTime = (t2.tv_sec-t1.tv_sec)+(t2.tv_usec-t1.tv_usec)/1000000.0; + fTimePerOperation = elapsedTime*1000000.0/ToggleValue/multiop; + fFreq = 1.0f/(fTimePerOperation*2); //ToggleValue/elapsedTime/1000000.0; + printf(" % 9d took %.3f s, Time per operation %.3f us (toggle Freq %.3f MHz) \n", + ToggleValue, elapsedTime, fTimePerOperation, fFreq); + CheckSameFloat(msg, fTimePerOperation, fExpectTime, fExpectTime*0.2f); + + return fTimePerOperation; +} + + +int main (void) { + struct timeval t1, t2; + + if (wiringPiSetupGpio() == -1) { + printf("wiringPiSetupGpio failed\n\n"); + exit(EXIT_FAILURE); + } + + int rev, mem, maker, overVolted; + piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted); + CheckNotSame("Model: ", RaspberryPiModel, -1); + if (!piBoard40Pin()) { + GPIO = 23; + GPIOIN = 24; + } + + switch(RaspberryPiModel) { + case PI_MODEL_A: + case PI_MODEL_B: //ARM=800MHz + case PI_MODEL_BP: + case PI_MODEL_AP: + case PI_MODEL_CM: + fExpectTimedigitalWrite = 0.132; //us; + fExpectTimedigitalRead = 0.171; //us + fExpectTimepinMode = 0.334; //us + break; + case PI_MODEL_ZERO: + case PI_MODEL_ZERO_W: //ARM=1000MHz + fExpectTimedigitalWrite = 0.104; //us; + fExpectTimedigitalRead = 0.135; //us + fExpectTimepinMode = 0.250; //us + break; + case PI_MODEL_2: + ToggleValue /= 4; + 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: + ToggleValue /= 2; + break; + case PI_MODEL_4B: //ARM=1500MHz + case PI_MODEL_400: + case PI_MODEL_CM4: + case PI_MODEL_CM4S: + fExpectTimedigitalWrite = 0.020; //us + fExpectTimedigitalRead = 0.038; //us + fExpectTimepinMode = 0.121; //us + fWriteReadDelayFactor = 1.86; + break; + default: + if (piRP1Model()) { + // So far expect all Pi5 / RP1 hardware has same performance + printf("Raspberry Pi with RP1 chip found\n"); + fExpectTimedigitalWrite = 0.025; //us + fExpectTimedigitalRead = 0.323; //us + fExpectTimepinMode = 0.200; //us + fWriteReadDelayFactor = 3.2; + } else { + printf("Unknown Raspberry Pi found, exit\n"); + return(EXIT_FAILURE); + } + break; + } + fWriteReadFactor = fExpectTimedigitalRead/fExpectTimedigitalWrite; + ToggleValue /= (fExpectTimedigitalWrite/fPi4ExpectTimedigitalWrite); + + printf("WiringPi GPIO operation time test program (using GPIO %d/%d)\n", GPIO, GPIOIN); + pinMode(GPIO, OUTPUT); + + printf("\n% 3d million times digitalWrite ...\n", ToggleValue/1000000); + gettimeofday(&t1, NULL); + for (int loop=1; loop GetMaxPin()) return ; uint32_t wrVal; @@ -1271,7 +1291,7 @@ void setPadDrive (int group, int value) if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { value = value & 7; // 0-7 supported - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (-1==group) { printf ("Pad register:\n"); for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { @@ -1342,7 +1362,7 @@ int getAlt (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return 0 ; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function /* @@ -1402,7 +1422,7 @@ void pwmSetMode (int mode) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if(mode != PWM_MODE_MS) { fprintf(stderr, "pwmSetMode: Raspberry Pi 5 missing feature PWM BAL mode\n"); } @@ -1441,7 +1461,7 @@ void pwmSetRange (unsigned int range) return; } int readback = 0x00; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { pwm[RP1_PWM0_CHAN0_RANGE] = range; pwm[RP1_PWM0_CHAN1_RANGE] = range; pwm[RP1_PWM0_CHAN2_RANGE] = range; @@ -1478,7 +1498,7 @@ void pwmSetClock (int divisor) if (divisor > PWMCLK_DIVI_MAX) { divisor = PWMCLK_DIVI_MAX; // even on Pi5 4095 is OK } - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (divisor < 1) { if (wiringPiDebug) { printf("Disable PWM0 clock"); } clk[CLK_PWM0_CTRL] = RP1_CLK_PWM0_CTRL_DISABLE_MAGIC; // 0 = disable on Pi5 @@ -1713,7 +1733,7 @@ int OpenAndCheckGpioChip(int GPIONo, const char* label, const unsigned int lines int wiringPiGpioDeviceGetFd() { if (chipFd<0) { piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { chipFd = OpenAndCheckGpioChip(0, "rp1", 54); // /dev/gpiochip0 @ Pi5 since Kernel 6.6.47 if (chipFd<0) { chipFd = OpenAndCheckGpioChip(4, "rp1", 54); // /dev/gpiochip4 @ Pi5 with older kernel @@ -1793,7 +1813,7 @@ void pinModeAlt (int pin, int mode) else if (wiringPiMode != WPI_MODE_GPIO) return ; - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { //confusion! diffrent to to BCM! this is taking directly the value for the register int modeRP1; switch(mode) { @@ -1932,7 +1952,7 @@ void pinMode (int pin, int mode) shift = gpioToShift [pin] ; if (INPUT==mode || PM_OFF==mode) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { if (INPUT==mode) { pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO @@ -1947,14 +1967,14 @@ void pinMode (int pin, int mode) 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) { + if (channel>=0 && channel<=3 && piRP1Model()) { unsigned int ctrl = pwm[RP1_PWM0_GLOBAL_CTRL]; pwm[RP1_PWM0_GLOBAL_CTRL] = (ctrl & ~(1<0x%08X)\n", channel, ctrl, pwm[RP1_PWM0_GLOBAL_CTRL]); } } } else if (mode == OUTPUT) { - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO rio[RP1_RIO_OE + RP1_SET_OFFSET] = 1<=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); @@ -2086,7 +2106,7 @@ void pullUpDnControl (int pin, int pud) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits switch (pud){ case PUD_OFF: pads[1+pin] = pullbits; break; @@ -2188,7 +2208,7 @@ int digitalRead (int pin) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (ISRP1MODEL) { switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) { default: // 11 or 00 not allowed, give LOW! case RP1_STATUS_LEVEL_LOW: return LOW ; @@ -2291,7 +2311,7 @@ void digitalWrite (int pin, int value) break; } - if (PI_MODEL_5 == RaspberryPiModel) { + if (ISRP1MODEL) { if (value == LOW) { //printf("Set pin %d >>0x%08x<< to low\n", pin, 1<=0 && channel<=3) { unsigned int addr = RP1_PWM0_CHAN_START+RP1_PWM0_CHAN_OFFSET*channel+RP1_PWM0_CHAN_DUTY; pwm[addr] = value; @@ -2991,7 +3011,7 @@ int wiringPiUserLevelAccess(void) const char* gpiomemModule = gpiomem_BCM; piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { gpiomemModule = gpiomem_RP1; } @@ -3058,7 +3078,7 @@ int wiringPiGlobalMemoryAccess(void) unsigned int BaseAddr, PWMAddr; piBoard(); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { GetRP1Memory(pciemem_RP1, sizeof(pciemem_RP1)); gpiomemGlobal = pciemem_RP1; MMAP_size = pciemem_RP1_Size; @@ -3081,7 +3101,7 @@ int wiringPiGlobalMemoryAccess(void) fprintf(stderr,"wiringPiGlobalMemoryAccess: mmap (GPIO 0x%X,0x%X) failed: %s\n", BaseAddr, MMAP_size, strerror (errno)) ; } else { munmap(lgpio, MMAP_size); - if (PI_MODEL_5 == RaspberryPiModel) { + if (piRP1Model()) { returnvalue = 2; // GPIO & PWM accessible (same area, nothing to mmap) } else { //check PWM area @@ -3167,7 +3187,7 @@ int wiringPiSetup (void) const char* gpiomemGlobal = gpiomem_global; const char* gpiomemModule = gpiomem_BCM; - if (PI_MODEL_5 == model) { + if (piRP1Model()) { GetRP1Memory(); gpiomemGlobal = pciemem_RP1; gpiomemModule = gpiomem_RP1; @@ -3205,7 +3225,7 @@ int wiringPiSetup (void) printf ("wiringPi: access to %s succeded %d\n", usingGpioMem ? gpiomemModule : gpiomemGlobal, fd) ; } // GPIO: - if (PI_MODEL_5 != model) { + if (!piRP1Model()) { //Set the offsets into the memory interface. GPIO_PADS = piGpioBase + 0x00100000 ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 79a895a..f2a4599 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -1,7 +1,7 @@ /* * wiringPi.h: * Arduino like Wiring library for the Raspberry Pi. - * Copyright (c) 2012-2017 Gordon Henderson + * Copyright (c) 2012-2025 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://github.com/WiringPi/WiringPi/ @@ -93,35 +93,44 @@ // Pi model types and version numbers // Intended for the GPIO program Use at your own risk. // https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#new-style-revision-codes +// https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/raspberry-pi/revision-codes.adoc -#define PI_MODEL_A 0 -#define PI_MODEL_B 1 -#define PI_MODEL_AP 2 -#define PI_MODEL_BP 3 -#define PI_MODEL_2 4 -#define PI_ALPHA 5 -#define PI_MODEL_CM 6 -#define PI_MODEL_07 7 -#define PI_MODEL_3B 8 -#define PI_MODEL_ZERO 9 -#define PI_MODEL_CM3 10 -#define PI_MODEL_ZERO_W 12 -#define PI_MODEL_3BP 13 -#define PI_MODEL_3AP 14 -#define PI_MODEL_CM3P 16 -#define PI_MODEL_4B 17 -#define PI_MODEL_ZERO_2W 18 -#define PI_MODEL_400 19 -#define PI_MODEL_CM4 20 -#define PI_MODEL_CM4S 21 -#define PI_MODEL_5 23 +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 -#define PI_VERSION_1 0 +#define PI_MODEL_3B 8 +#define PI_MODEL_ZERO 9 +#define PI_MODEL_CM3 10 + +#define PI_MODEL_ZERO_W 12 +#define PI_MODEL_3BP 13 +#define PI_MODEL_3AP 14 + +#define PI_MODEL_CM3P 16 +#define PI_MODEL_4B 17 +#define PI_MODEL_ZERO_2W 18 +#define PI_MODEL_400 19 +#define PI_MODEL_CM4 20 +#define PI_MODEL_CM4S 21 + +#define PI_MODEL_5 23 +#define PI_MODEL_CM5 24 +#define PI_MODEL_500 25 +#define PI_MODEL_CM5L 26 + +#define PI_MODELS_MAX 27 + +#define PI_VERSION_1 0 #define PI_VERSION_1_1 1 #define PI_VERSION_1_2 2 -#define PI_VERSION_2 3 +#define PI_VERSION_2 3 -#define PI_MAKER_SONY 0 +#define PI_MAKER_SONY 0 #define PI_MAKER_EGOMAN 1 #define PI_MAKER_EMBEST 2 #define PI_MAKER_UNKNOWN 3 @@ -129,13 +138,12 @@ #define GPIO_LAYOUT_PI1_REV1 1 //Pi 1 A/B Revision 1, 1.1, CM #define GPIO_LAYOUT_DEFAULT 2 -extern const char *piModelNames [24] ; +extern const char *piModelNames [PI_MODELS_MAX] ; extern const char *piProcessor [ 5] ; extern const char *piRevisionNames [16] ; extern const char *piMakerNames [16] ; extern const int piMemorySize [ 8] ; - // Intended for the GPIO program Use at your own risk. // Threads @@ -271,6 +279,7 @@ 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 piRP1Model (void) ; // Interface V3.14 extern int wpiPinToGpio (int wpiPin) ; extern int physPinToGpio (int physPin) ; extern void setPadDrive (int group, int value) ;