|
|
|
|
@@ -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)) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
|
|
|
|
|
*(pads + group + 11) = wrVal ;
|
|
|
|
|
if ((group < 0) || (group > 2))
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
alt = (*(gpio + fSel) >> shift) & 7 ;
|
|
|
|
|
/*
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} 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;
|
|
|
|
|
|
|
|
|
|
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) ;
|
|
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
|
|
|
|
|
*(gpio + gpioToPUDCLK [pin]) = 0 ; 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) ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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) {
|
|
|
|
|
|