Browse Source

Merge pull request #23 from GrazerComputerClub/Pi5

V3 preparation / Pi5 support
pull/188/head
Manfred Wallner 8 months ago
committed by GitHub
parent
commit
5a79e5bc29
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
9 changed files with 443 additions and 109 deletions
  1. +5
    -6
      README.md
  2. +1
    -1
      VERSION
  3. +1
    -1
      debian-template/wiringPi/DEBIAN/control
  4. +27
    -1
      gpio/gpio.c
  5. +23
    -8
      gpio/readall.c
  6. +0
    -0
      newVersion
  7. +2
    -2
      version.h
  8. +383
    -90
      wiringPi/wiringPi.c
  9. +1
    -0
      wiringPi/wiringPi.h

+ 5
- 6
README.md View File

@@ -1,6 +1,4 @@

:warning: This library was deprecated by its author in August 2019. Until 31st October 2023 it was maintaining at https://github.com/WiringPi/WiringPi/ but later set to read only because there was no interest in properly maintaining it.
In 2024 GC2 fork the project to maintaining it and to keep the best GPIO Library for Raspberry Pi running. We do our best, but we have limited resources and can not give support.
ℹ️ Since 2024, [GC2](https://github.com/GrazerComputerClub) has taken over maintenance of the project, supporting new OS versions as well as current hardware generations. We are dedicated to keeping the arguably best-performing GPIO Library for Raspberry Pi running smoothly. We strive to do our best, but please note that this is a community effort, and we cannot provide any guarantees or take responsibility for implementing specific features you may need.

WiringPi (Unofficial Mirror/Fork)
=================================
@@ -42,9 +40,10 @@ wiringPi has been wrapped for multiple languages:
Support
-------

Please do not email Gordon if you have issues, he will not be able to help.
Dont' email @Gadgetoid.
Don't email GC2, use issue system of github to report errors.
Please use the [issue system](https://github.com/WiringPi/WiringPi/issues) of GitHub.
Please do not email Gordon if you have issues.
Dont' email @Gadgetoid.
Please don't email GC2 for reporting issues, you might [contact us](wiringpi@gc2.at) for anything that's not for the public eye.

Debug
-------


+ 1
- 1
VERSION View File

@@ -1 +1 @@
2.72
2.73

+ 1
- 1
debian-template/wiringPi/DEBIAN/control View File

@@ -1,5 +1,5 @@
Package: wiringpi
Version: 2.72
Version: 2.73
Section: libraries
Priority: optional
Architecture: armhf


+ 27
- 1
gpio/gpio.c View File

@@ -794,6 +794,31 @@ void doMode (int argc, char *argv [])
*********************************************************************************
*/

static void doPadDrivePin (int argc, char *argv [])
{

if (argc != 4) {
fprintf (stderr, "Usage: %s drivepin pin value\n", argv [0]) ;
exit (1) ;
}

int pin = atoi (argv [2]) ;
int val = atoi (argv [3]) ;

if ((pin < 0) || (pin > 27)) {
fprintf (stderr, "%s: drive pin not 0-27: %d\n", argv [0], pin) ;
exit (1) ;
}

if ((val < 0) || (val > 3)) {
fprintf (stderr, "%s: drive value not 0-3: %d\n", argv [0], val) ;
exit (1) ;
}

setPadDrivePin (pin, val) ;
}


static void doPadDrive (int argc, char *argv [])
{
int group, val ;
@@ -807,7 +832,7 @@ static void doPadDrive (int argc, char *argv [])
group = atoi (argv [2]) ;
val = atoi (argv [3]) ;

if ((group < 0) || (group > 2))
if ((group < -1) || (group > 2)) //-1 hidden feature for read and print values
{
fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
exit (1) ;
@@ -1536,6 +1561,7 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "drivepin" ) == 0) doPadDrivePin(argc, argv) ;
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ;


+ 23
- 8
gpio/readall.c View File

@@ -75,11 +75,23 @@ static void doReadallExternal (void)
*********************************************************************************
*/

static char *alts [] =
static const char unknown_alt[] = " - ";
static const char *alts [] =
{
"IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
"IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3", "ALT6", "ALT7", "ALT8", "ALT9"
} ;


static const char* GetAltString(int alt) {

if (alt>=0 && alt<=11) {
return alts[alt];
}

return unknown_alt;
}


static int physToWpi [64] =
{
-1, // 0
@@ -177,7 +189,7 @@ static void readallPhys (int physPin)
else
pin = physToWpi [physPin] ;

printf (" | %4s", alts [getAlt (pin)]) ;
printf (" | %4s", GetAltString(getAlt (pin))) ;
printf (" | %d", digitalRead (pin)) ;
}

@@ -201,7 +213,7 @@ static void readallPhys (int physPin)
pin = physToWpi [physPin] ;

printf (" | %d", digitalRead (pin)) ;
printf (" | %-4s", alts [getAlt (pin)]) ;
printf (" | %-4s", GetAltString(getAlt (pin))) ;
}

printf (" | %-5s", physNames [physPin]) ;
@@ -233,11 +245,11 @@ static void allReadall (void)
for (pin = 0 ; pin < 27 ; ++pin)
{
printf ("| %3d ", pin) ;
printf ("| %-4s ", alts [getAlt (pin)]) ;
printf ("| %-4s ", GetAltString(getAlt (pin))) ;
printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ;
printf ("| ") ;
printf ("| %3d ", pin + 27) ;
printf ("| %-4s ", alts [getAlt (pin + 27)]) ;
printf ("| %-4s ", GetAltString(getAlt (pin + 27))) ;
printf ("| %s ", digitalRead (pin + 27) == HIGH ? "High" : "Low ") ;
printf ("|\n") ;
}
@@ -315,6 +327,8 @@ static void plus2header (int model)
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") ;
}
@@ -363,7 +377,8 @@ void doReadall (void)
(model == PI_MODEL_3AP) ||
(model == PI_MODEL_3B) || (model == PI_MODEL_3BP) ||
(model == PI_MODEL_4B) || (model == PI_MODEL_400) || (model == PI_MODEL_CM4) ||
(model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W) || (model == PI_MODEL_ZERO_2W))
(model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W) || (model == PI_MODEL_ZERO_2W) ||
(model == PI_MODEL_5) )
piPlusReadall (model) ;
else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || (model == PI_MODEL_CM3P) )
allReadall () ;
@@ -401,5 +416,5 @@ void doQmode (int argc, char *argv [])
}

pin = atoi (argv [2]) ;
printf ("%s\n", alts [getAlt (pin)]) ;
printf ("%s\n", GetAltString(getAlt (pin))) ;
}

+ 0
- 0
newVersion View File


+ 2
- 2
version.h View File

@@ -1,3 +1,3 @@
#define VERSION "2.72"
#define VERSION "2.73"
#define VERSION_MAJOR 2
#define VERSION_MINOR 72
#define VERSION_MINOR 73

+ 383
- 90
wiringPi/wiringPi.c View File

@@ -123,6 +123,50 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
#define FSEL_ALT4 0b011
#define FSEL_ALT5 0b010

//RP1 chip (@Pi5) - 3.1.1. Function select
#define RP1_FSEL_ALT0 0x00
#define RP1_FSEL_GPIO 0x05 //SYS_RIO
#define RP1_FSEL_NONE 0x09
#define RP1_FSEL_NONE_HW 0x1f //default, mask

//RP1 chip (@Pi5) RIO address
const unsigned int RP1_RIO_OUT = 0x0000;
const unsigned int RP1_RIO_OE = (0x0004/4);
const unsigned int RP1_RIO_IN = (0x0008/4);

//RP1 chip (@Pi5) RIO offset for set/clear value
const unsigned int RP1_SET_OFFSET = (0x2000/4);
const unsigned int RP1_CLR_OFFSET = (0x3000/4);

//RP1 chip (@Pi5) PDE/PDU pull-up/-down enable
const unsigned int RP1_PUD_UP = (1<<3);
const unsigned int RP1_PUD_DOWN = (1<<2);
const unsigned int RP1_INV_PUD_MASK = ~(RP1_PUD_UP | RP1_PUD_DOWN); //~0x0C

//RP1 chip (@Pi5) pin level, status register
const unsigned int RP1_STATUS_LEVEL_LOW = 0x00400000;
const unsigned int RP1_STATUS_LEVEL_HIGH = 0x00800000;
const unsigned int RP1_STATUS_LEVEL_MASK = 0x00C00000;

const unsigned int RP1_DEBOUNCE_DEFAULT_VALUE = 4;
const unsigned int RP1_DEBOUNCE_MASK = 0x7f;
const unsigned int RP1_DEBOUNCE_DEFAULT = (RP1_DEBOUNCE_DEFAULT_VALUE << 5);

const unsigned int RP1_PAD_DEFAULT_0TO8 = (0x0B | 0x70); //Slewfast, Schmitt, PullUp, | 12mA, Input enable
const unsigned int RP1_PAD_DEFAULT_FROM9 = (0x07 | 0x70); //Slewfast, Schmitt, PullDown, | 12mA, Input enable

const unsigned int RP1_PAD_DRIVE_MASK = 0x00000030;
const unsigned int RP1_INV_PAD_DRIVE_MASK = ~(RP1_PAD_DRIVE_MASK);

//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_IO0_Addr = 0x400d0000;
const unsigned int RP1_SYS_RIO0_Addr = 0x400e0000;
const unsigned int RP1_PADS0_Addr = 0x400f0000;


// Access from ARM Running Linux
// Taken from Gert/Doms code. Some of this is not in the manual
// that I can find )-:
@@ -130,11 +174,24 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
// Updates in September 2015 - all now static variables (and apologies for the caps)
// due to the Pi v2, v3, etc. and the new /dev/gpiomem interface

const char* gpiomem_global = "/dev/mem";
const char* gpiomem_BCM = "/dev/gpiomem";
const char* gpiomem_RP1 = "/dev/gpiomem0";
const int gpiomem_RP1_Size = 0x00030000;
// PCIe Memory access, static define - maybe needed to detect in future
//dmesg: rp1 0000:01:00.0: bar1 len 0x400000, start 0x1f00000000, end 0x1f003fffff, flags, 0x40200
const char* pciemem_RP1_path = "/sys/bus/pci/devices/0000:01:00.0";
const char* pciemem_RP1 = "/sys/bus/pci/devices/0000:01:00.0/resource1";
const int pciemem_RP1_Size = 0x00400000;
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_BASE ;
static volatile unsigned int GPIO_TIMER ;
static volatile unsigned int GPIO_PWM ;
static volatile unsigned int GPIO_RIO ;

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
@@ -188,22 +245,25 @@ static int wiringPiSetuped = FALSE ;

// Locals to hold pointers to the hardware

static volatile unsigned int *base ;
static volatile unsigned int *gpio ;
static volatile unsigned int *pwm ;
static volatile unsigned int *clk ;
static volatile unsigned int *pads ;
static volatile unsigned int *timer ;
static volatile unsigned int *timerIrqRaw ;
static volatile unsigned int *rio ;

// Export variables for the hardware pointers

volatile unsigned int *_wiringPiBase ;
volatile unsigned int *_wiringPiGpio ;
volatile unsigned int *_wiringPiPwm ;
volatile unsigned int *_wiringPiClk ;
volatile unsigned int *_wiringPiPads ;
volatile unsigned int *_wiringPiTimer ;
volatile unsigned int *_wiringPiTimerIrqRaw ;
volatile unsigned int *_wiringPiRio ;

// Data for use with the boardId functions.
// The order of entries here to correspond with the PI_MODEL_X
@@ -216,6 +276,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ;
#define GPIO_PERI_BASE_OLD 0x20000000
#define GPIO_PERI_BASE_2835 0x3F000000
#define GPIO_PERI_BASE_2711 0xFE000000
#define GPIO_PERI_BASE_2712 0x00 //unknown - 32-bit mapped global mem access not supported for now

static volatile unsigned int piGpioBase = 0 ;

@@ -512,6 +573,21 @@ int GPIOToSysFS(const int pin) {
return sysfspin;
}

int GetMaxPin() {
return PI_MODEL_5 == RaspberryPiModel ? 27 : 63;
}


#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; }
int FailOnModel5() {
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 0;
}

// gpioToGPFSEL:
// Map a BCM_GPIO pin to it's Function Selection
// control port. (GPFSEL 0-5)
@@ -768,6 +844,7 @@ static void usingGpioMemCheck (const char *what)
fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ;
exit (EXIT_FAILURE) ;
}

}


@@ -1186,23 +1263,73 @@ int physPinToGpio (int physPin)
* Set the PAD driver value
*********************************************************************************
*/
void setPadDrivePin (int pin, int value) {
if (PI_MODEL_5 != RaspberryPiModel) return;
if (pin < 0 || pin > GetMaxPin()) return ;

uint32_t wrVal;
value = value & 3; // 0-3 supported
wrVal = (value << 4); //Drive strength 0-3
pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal;
if (wiringPiDebug) {
printf ("setPadDrivePin: pin: %d, value: %d (%08X)\n", pin, value, pads[1+pin]) ;
}
}


void setPadDrive (int group, int value)
{
uint32_t wrVal ;
uint32_t wrVal, rdVal;

if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
{
if ((group < 0) || (group > 2))
return ;
value = value & 7; // 0-7 supported
if (PI_MODEL_5 == RaspberryPiModel) {
if (-1==group) {
printf ("Pad register:\n");
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
unsigned int drive = (pads[1+pin] & RP1_PAD_DRIVE_MASK)>>4;
printf (" Pin %2d: 0x%08X drive: 0x%d = %2dmA\n", pin, pads[1+pin], drive, 0==drive ? 2 : drive*4) ;
}
}
if (group !=0) { // only GPIO range @RP1
return ;
}
switch(value) {
default:
/* bcm*/ // RP1
case 0: /* 2mA*/ value=0; break; // 2mA
case 1: /* 4mA*/
case 2: /* 6mA*/ value=1; break; // 4mA
case 3: /* 8mA*/
case 4: /*10mA*/ value=2; break; // 8mA
case 5: /*12mA*/
case 6: /*14mA*/
case 7: /*16mA*/ value=3; break; //12mA
}
wrVal = (value << 4); //Drive strength 0-3
//set for all pins even when it's avaiable for each pin separately
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) {
pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal;
}
rdVal = pads[1+17]; // only pin 17 readback, for logging
} else {
if (-1==group) {
printf ("Pad register: Group 0: 0x%08X, Group 1: 0x%08X, Group 2: 0x%08X\n", *(pads + 0 + 11), *(pads + 1 + 11), *(pads + 2 + 11)) ;
}

if ((group < 0) || (group > 2))
return ;

wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
*(pads + group + 11) = wrVal ;
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7
*(pads + group + 11) = wrVal ;
rdVal = *(pads + group + 11);
}

if (wiringPiDebug)
{
printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
printf ("Read : %08X\n", *(pads + group + 11)) ;
printf ("Read : %08X\n", rdVal) ;
}
}
}
@@ -1228,11 +1355,48 @@ int getAlt (int pin)
else if (wiringPiMode != WPI_MODE_GPIO)
return 0 ;

fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;
if (PI_MODEL_5 == RaspberryPiModel) {
alt = (gpio[2*pin+1] & RP1_FSEL_NONE_HW); //0-4 function

/*
BCM:
000b = GPIO Pin 9 is an input
001b = GPIO Pin 9 is an output
100b = GPIO Pin 9 takes alternate function 0
101b = GPIO Pin 9 takes alternate function 1
110b = GPIO Pin 9 takes alternate function 2
111b = GPIO Pin 9 takes alternate function 3
011b = GPIO Pin 9 takes alternate function 4
010b = GPIO Pin 9 takes alternate function 5
RP1:
8 = alternate function 6
9 = alternate function 7
10 = alternate function 8
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 RP1_FSEL_GPIO: {
unsigned int outputmask = gpio[2*pin] & 0x3000; //Bit13-OETOPAD + Bit12-OEFROMPERI
return (outputmask==0x3000) ? 1 : 0; //1=OUT 0=IN
}
case 6: return 8;
case 7: return 9;
case 8: return 10;
case 9: return 11;
default:return alt;
}

alt = (*(gpio + fSel) >> shift) & 7 ;
} else {
fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;

alt = (*(gpio + fSel) >> shift) & 7 ;
}
return alt ;
}

@@ -1247,6 +1411,7 @@ void pwmSetMode (int mode)
{
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
{
FailOnModel5();
if (mode == PWM_MODE_MS)
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
else
@@ -1264,6 +1429,7 @@ 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) ;
@@ -1284,6 +1450,7 @@ void pwmSetClock (int divisor)
{
uint32_t pwm_control ;

FailOnModel5();
if (piGpioBase == GPIO_PERI_BASE_2711)
{
divisor = 540*divisor/192;
@@ -1335,6 +1502,7 @@ void gpioClockSet (int pin, int freq)
{
int divi, divr, divf ;

FailOnModel5();
pin &= 63 ;

/**/ if (wiringPiMode == WPI_MODE_PINS)
@@ -1466,6 +1634,7 @@ void pinModeAlt (int pin, int mode)
{
int fSel, shift ;

RETURN_ON_MODEL5
setupCheck ("pinModeAlt") ;

if ((pin & PI_GPIO_MASK) == 0) // On-board pin
@@ -1477,10 +1646,25 @@ void pinModeAlt (int pin, int mode)
else if (wiringPiMode != WPI_MODE_GPIO)
return ;

fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;
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
} else {
fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;

*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
}

*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ;
}
}

@@ -1491,12 +1675,21 @@ void pinModeAlt (int pin, int mode)
*********************************************************************************
*/

//Default: rp1_set_pad(pin, 0, 1, 0, 1, 1, 1, 0);
void rp1_set_pad(int pin, int slewfast, int schmitt, int pulldown, int pullup, int drive, int inputenable, int outputdisable) {

pads[1+pin] = (slewfast != 0) | ((schmitt != 0) << 1) | ((pulldown != 0) << 2) | ((pullup != 0) << 3) | ((drive & 0x3) << 4) | ((inputenable != 0) << 6) | ((outputdisable != 0) << 7);
}

void pinMode (int pin, int mode)
{
int fSel, shift, alt ;
struct wiringPiNodeStruct *node = wiringPiNodes ;
int origPin = pin ;

if (wiringPiDebug)
printf ("pinMode: pin:%d mode:%d\n", pin, mode) ;

setupCheck ("pinMode") ;

if ((pin & PI_GPIO_MASK) == 0) // On-board pin
@@ -1508,27 +1701,43 @@ void pinMode (int pin, int mode)
else if (wiringPiMode != WPI_MODE_GPIO)
return ;

if (wiringPiDebug)
printf ("pinMode: bcm pin:%d mode:%d\n", pin, mode) ;

softPwmStop (origPin) ;
softToneStop (origPin) ;

fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;

/**/ if (mode == INPUT)
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
else if (mode == OUTPUT)
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
else if (mode == SOFT_PWM_OUTPUT)
if (mode == INPUT) {
if (PI_MODEL_5 == RaspberryPiModel) {
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_CLR_OFFSET] = 1<<pin; // Input
} else {
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
}
} else if (mode == OUTPUT) {
if (PI_MODEL_5 == RaspberryPiModel) {
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<<pin; // Output
} else {
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
}
} else if (mode == SOFT_PWM_OUTPUT) {
softPwmCreate (origPin, 0, 100) ;
else if (mode == SOFT_TONE_OUTPUT)
} else if (mode == SOFT_TONE_OUTPUT) {
softToneCreate (origPin) ;
else if (mode == PWM_TONE_OUTPUT)
} else if (mode == PWM_TONE_OUTPUT)
{
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 ;

@@ -1545,6 +1754,7 @@ void pinMode (int pin, int mode)
}
else if (mode == GPIO_CLOCK)
{
RETURN_ON_MODEL5
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
return ;

@@ -1580,42 +1790,53 @@ void pullUpDnControl (int pin, int pud)

if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{
/**/ if (wiringPiMode == WPI_MODE_PINS)

/**/ if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;

if (piGpioPupOffset == GPPUPPDN0)
{
// Pi 4B pull up/down method
int pullreg = GPPUPPDN0 + (pin>>4);
int pullshift = (pin & 0xf) << 1;
unsigned int pullbits;
unsigned int pull;

switch (pud)
{
case PUD_OFF: pull = 0; break;
case PUD_UP: pull = 1; break;
case PUD_DOWN: pull = 2; break;
if (PI_MODEL_5 == RaspberryPiModel) {
unsigned int pullbits = pads[1+pin] & RP1_INV_PUD_MASK; // remove bits
switch (pud){
case PUD_OFF: pads[1+pin] = pullbits; break;
case PUD_UP: pads[1+pin] = pullbits | RP1_PUD_UP; break;
case PUD_DOWN: pads[1+pin] = pullbits | RP1_PUD_DOWN; break;
default: return ; /* An illegal value */
}
} else {
if (piGpioPupOffset == GPPUPPDN0)
{
// Pi 4B pull up/down method
int pullreg = GPPUPPDN0 + (pin>>4);
int pullshift = (pin & 0xf) << 1;
unsigned int pullbits;
unsigned int pull;

switch (pud)
{
case PUD_OFF: pull = 0; break;
case PUD_UP: pull = 1; break;
case PUD_DOWN: pull = 2; break;
default: return ; /* An illegal value */
}

pullbits = *(gpio + pullreg);
pullbits &= ~(3 << pullshift);
pullbits |= (pull << pullshift);
*(gpio + pullreg) = pullbits;
}
else
{
// legacy pull up/down method
*(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;

pullbits = *(gpio + pullreg);
pullbits &= ~(3 << pullshift);
pullbits |= (pull << pullshift);
*(gpio + pullreg) = pullbits;
}
else
{
// legacy pull up/down method
*(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;

*(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
*(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
*(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
}
}
}
else // Extension module
@@ -1655,10 +1876,18 @@ int digitalRead (int pin)
else if (wiringPiMode != WPI_MODE_GPIO)
return LOW ;

if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
if (PI_MODEL_5 == RaspberryPiModel) {
switch(gpio[2*pin] & RP1_STATUS_LEVEL_MASK) {
default: // 11 or 00 not allowed, give LOW!
case RP1_STATUS_LEVEL_LOW: return LOW ;
case RP1_STATUS_LEVEL_HIGH: return HIGH ;
}
} else {
if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
return HIGH ;
else
return LOW ;
}
}
else
{
@@ -1704,12 +1933,12 @@ void digitalWrite (int pin, int value)
{
/**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
{
if (sysFds [pin] != -1)
if (sysFds [pin] != -1)
{
if (value == LOW)
write (sysFds [pin], "0\n", 2) ;
else
write (sysFds [pin], "1\n", 2) ;
if (value == LOW)
write (sysFds [pin], "0\n", 2) ;
else
write (sysFds [pin], "1\n", 2) ;
}
return ;
}
@@ -1719,11 +1948,20 @@ void digitalWrite (int pin, int value)
pin = physToGpio [pin] ;
else if (wiringPiMode != WPI_MODE_GPIO)
return ;

if (value == LOW)
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
if (PI_MODEL_5 == RaspberryPiModel) {
if (value == LOW) {
//printf("Set pin %d >>0x%08x<< to low\n", pin, 1<<pin);
rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin;
} else {
//printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin);
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin;
}
} else {
if (value == LOW)
*(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
else
*(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
}
}
else
{
@@ -1763,6 +2001,7 @@ void pwmWrite (int pin, int value)
{
struct wiringPiNodeStruct *node = wiringPiNodes ;

FailOnModel5();
setupCheck ("pwmWrite") ;

if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
@@ -1832,7 +2071,7 @@ void analogWrite (int pin, int value)

void pwmToneWrite (int pin, int freq)
{
int range ;
FailOnModel5();

setupCheck ("pwmToneWrite") ;

@@ -1840,7 +2079,7 @@ void pwmToneWrite (int pin, int freq)
pwmWrite (pin, 0) ; // Off
else
{
range = 600000 / freq ;
int range = 600000 / freq ;
pwmSetRange (range) ;
pwmWrite (pin, freq / 2) ;
}
@@ -1871,6 +2110,8 @@ void digitalWriteByte (const int value)
int mask = 1 ;
int pin ;

FailOnModel5();

/**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
{
for (pin = 0 ; pin < 8 ; ++pin)
@@ -1903,6 +2144,8 @@ unsigned int digitalReadByte (void)
uint32_t raw ;
uint32_t data = 0 ;

FailOnModel5();

/**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
{
for (pin = 0 ; pin < 8 ; ++pin)
@@ -1939,6 +2182,8 @@ void digitalWriteByte2 (const int value)
register int mask = 1 ;
register int pin ;

FailOnModel5();

/**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
{
for (pin = 20 ; pin < 28 ; ++pin)
@@ -1960,6 +2205,8 @@ unsigned int digitalReadByte2 (void)
int pin, x ;
uint32_t data = 0 ;

FailOnModel5();

/**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
{
for (pin = 20 ; pin < 28 ; ++pin)
@@ -2064,9 +2311,10 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
int count, i ;
char c ;
int bcmGpioPin ;
const int maxpin = GetMaxPin();

if ((pin < 0) || (pin > 63))
return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ;
if (pin < 0 || pin > maxpin)
return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-%d (%d)\n", maxpin, pin) ;

/**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
@@ -2384,6 +2632,11 @@ int wiringPiSetup (void)
piGpioPupOffset = GPPUPPDN0 ;
break ;

case PI_MODEL_5:
piGpioBase = GPIO_PERI_BASE_2712 ;
piGpioPupOffset = 0 ;
break ;

default:
piGpioBase = GPIO_PERI_BASE_2835 ;
piGpioPupOffset = GPPUD ;
@@ -2395,37 +2648,46 @@ int wiringPiSetup (void)
// Try /dev/mem. If that fails, then
// try /dev/gpiomem. If that fails then game over.

const char* gpiomemGlobal = gpiomem_global;
const char* gpiomemModule = gpiomem_BCM;

if (PI_MODEL_5 == model) {
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Raspberry Pi 5 not supported.\n"
" Unable to continue. Keep an eye of new versions at https://github.com/GrazerComputerClub/WiringPi\n") ;
gpiomemGlobal = pciemem_RP1;
gpiomemModule = gpiomem_RP1;
}

if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
if (gpiomemGlobal==NULL || (fd = open (gpiomemGlobal, O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
{
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem

if (gpiomemModule && (fd = open (gpiomemModule, O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem
{
piGpioBase = 0 ;
usingGpioMem = TRUE ;
}
else
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n"
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open %s or %s: %s.\n"
" Aborting your program because if it can not access the GPIO\n"
" hardware then it most certianly won't work\n"
" Try running with sudo?\n", strerror (errno)) ;
" Try running with sudo?\n", gpiomemGlobal, gpiomemModule, strerror (errno)) ;
}
if (wiringPiDebug) {
printf ("wiringPi: access to %s succeded\n", usingGpioMem ? gpiomemModule : gpiomemGlobal) ;
}
// GPIO:
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_BASE = piGpioBase + 0x00200000 ;
GPIO_TIMER = piGpioBase + 0x0000B000 ;
GPIO_PWM = piGpioBase + 0x0020C000 ;
GPIO_PADS = piGpioBase + 0x00100000 ;
GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ;
GPIO_BASE = piGpioBase + 0x00200000 ;
GPIO_TIMER = piGpioBase + 0x0000B000 ;
GPIO_PWM = piGpioBase + 0x0020C000 ;
GPIO_RIO = 0x00 ;

// Map the individual hardware components

// GPIO:
if (PI_MODEL_5 != model) {
// GPIO:
base = NULL;
gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
if (gpio == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
@@ -2462,23 +2724,55 @@ int wiringPiSetup (void)
*(timer + TIMER_PRE_DIV) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;

// Export the base addresses for any external software that might need them
_wiringPiBase = base ;
_wiringPiGpio = gpio ;
_wiringPiPwm = pwm ;
_wiringPiClk = clk ;
_wiringPiPads = pads ;
_wiringPiTimer = timer ;
_wiringPiRio = NULL ;
} else {
_wiringPiGpio = NULL ;
unsigned int MMAP_size = (usingGpioMem) ? gpiomem_RP1_Size : pciemem_RP1_Size;

GPIO_PADS = (RP1_PADS0_Addr-RP1_IO0_Addr) ;
GPIO_CLOCK_BASE = 0x00;
GPIO_BASE = (RP1_IO0_Addr-RP1_BASE_Addr) ;
GPIO_TIMER = 0x00;
GPIO_PWM = RP1_PWM0_Addr-RP1_BASE_Addr;
GPIO_RIO = (RP1_SYS_RIO0_Addr-RP1_IO0_Addr) ;

//map hole RP1 memory block from beginning,
base = (unsigned int *)mmap(0, MMAP_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x00000000) ;
if (base == MAP_FAILED)
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)
} else {
gpio = &base[GPIO_BASE/4];// RP1 start adress of map memory for gpio
}
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
GPIO_PADS += GPIO_BASE;
GPIO_RIO += GPIO_BASE;

// Export the base addresses for any external software that might need them
_wiringPiBase = base ;
_wiringPiGpio = gpio ;
_wiringPiPwm = NULL ;
_wiringPiClk = NULL ;
_wiringPiPads = NULL ;
_wiringPiPads = pads ;
_wiringPiTimer = NULL ;
}

// Export the base addresses for any external software that might need them


_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");
}

initialiseEpoch () ;

@@ -2541,7 +2835,6 @@ int wiringPiSetupPhys (void)

int wiringPiSetupSys (void)
{
int pin ;
char fName [128] ;

if (wiringPiSetuped)
@@ -2575,7 +2868,7 @@ int wiringPiSetupSys (void)
// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later

for (pin = 0 ; pin < 64 ; ++pin)
for (int pin = 0, maxpin=GetMaxPin() ; pin <= maxpin ; ++pin)
{
int pinFS = GPIOToSysFS(pin);
if (pinFS>=0) {


+ 1
- 0
wiringPi/wiringPi.h View File

@@ -236,6 +236,7 @@ extern void piBoardId (int *model, int *rev, int *mem, int *m
extern int wpiPinToGpio (int wpiPin) ;
extern int physPinToGpio (int physPin) ;
extern void setPadDrive (int group, int value) ;
extern void setPadDrivePin (int pin, int value); // Interface V2
extern int getAlt (int pin) ;
extern void pwmToneWrite (int pin, int freq) ;
extern void pwmSetMode (int mode) ;


Loading…
Cancel
Save