/* * wiringPi: * Arduino look-a-like Wiring library for the Raspberry Pi * Copyright (c) 2012-2017 Gordon Henderson * Additional code for pwmSetClock by Chris Hall * * Thanks to code samples from Gert Jan van Loo and the * BCM2835 ARM Peripherals manual, however it's missing * the clock section /grr/mutter/ *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with wiringPi. * If not, see . *********************************************************************** */ // Revisions: // 19 Jul 2012: // Moved to the LGPL // Added an abstraction layer to the main routines to save a tiny // bit of run-time and make the clode a little cleaner (if a little // larger) // Added waitForInterrupt code // Added piHiPri code // // 9 Jul 2012: // Added in support to use the /sys/class/gpio interface. // 2 Jul 2012: // Fixed a few more bugs to do with range-checking when in GPIO mode. // 11 Jun 2012: // Fixed some typos. // Added c++ support for the .h file // Added a new function to allow for using my "pin" numbers, or native // GPIO pin numbers. // Removed my busy-loop delay and replaced it with a call to delayMicroseconds // // 02 May 2012: // Added in the 2 UART pins // Change maxPins to numPins to more accurately reflect purpose #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "softPwm.h" #include "softTone.h" #include "wiringPi.h" #include "../version.h" // Environment Variables #define ENV_DEBUG "WIRINGPI_DEBUG" #define ENV_CODES "WIRINGPI_CODES" #define ENV_GPIOMEM "WIRINGPI_GPIOMEM" int pwmmode = 1; static int ORANGEPI_PIN_MASK_3[12][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,16,-1,18,-1,-1,21,22,23,24,25,26,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1, 3, 4, 5, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1, 2, 3,-1,-1,-1,-1, 8,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL }; static int ORANGEPI_PIN_MASK_LITE_2[12][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB { 0,-1, 2, 3,-1, 5,-1, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,23,24,25,26,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1, 3, 4, 5, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH }; static int ORANGEPI_PIN_MASK_ZERO[12][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6, 7,-1,-1,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL }; static int ORANGEPI_PIN_MASK_ZERO_PLUS_2[12][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6,-1,-1,-1,-1,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL }; static int ORANGEPI_PIN_MASK_WIN[12][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,20,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC { 0, 1, 2, 3, 4, 5, 6,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1, 2, 3,-1,-1,-1,-1,-1, 9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL }; static int ORANGEPI_PIN_MASK_PRIME[9][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1, 4, 5, 6, 7, 8, 9,10,11,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI }; static int ORANGEPI_PIN_MASK_PC_2[9][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,-1,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI }; static int ORANGEPI_PIN_MASK_ZERO_PLUS[12][32] = //[BANK] [INDEX] { { 0, 1, 2, 3,-1,-1, 6, 7,-1,-1,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL }; static int ORANGEPI_PIN_MASK_ZERO_2[12][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1, 1,-1,-1,-1, 5, 6, 7, 8, 9,10,11,-1,-1,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1, 2, 3, 4, 5, 6, 7, 8, 9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE }; static int ORANGEPI_PIN_MASK_ZERO_2_W[12][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PJ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PK {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE }; static int ORANGEPI_PIN_MASK_800[5][32] = //[BANK] [INDEX] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}, }; static int ORANGEPI_PIN_MASK_4[5][32] = //[BANK] [INDEX] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PA { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PB { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PC { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD }; static int ORANGEPI_PIN_MASK_4_LTS[5][32] = //[BANK] [INDEX] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PA { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PB { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PC { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD }; static int ORANGEPI_PIN_MASK_RK3399[5][32] = //[BANK] [INDEX] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PA { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PB { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PC { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD }; static int ORANGEPI_PIN_MASK_5[5][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1, 4, 5,-1,-1,},//GPIO0 {-1,-1,-1, 3,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 7, 0, 1, 2,-1, 4,-1, 6,-1, -1,-1, 2, 3,-1,-1,-1,-1,},//GPIO1 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1, 4,-1,-1,-1,},//GPIO2 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO3 {-1,-1,-1, 3, 4,-1,-1,-1, -1,-1, 2, 3, 4,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO4 }; static int ORANGEPI_PIN_MASK_5B[5][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1, 4, 5,-1,-1,},//GPIO0 {-1,-1,-1, 3,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 7, 0, 1, 2,-1, 4,-1, 6,-1, -1,-1, 2, 3,-1,-1,-1,-1,},//GPIO1 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO2 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO3 {-1,-1,-1, 3, 4,-1,-1,-1, -1,-1, 2, 3, 4,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO4 }; static int ORANGEPI_PIN_MASK_5PLUS[5][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1, 7, 0,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO0 { 0, 1, 2, 3, 4,-1,-1, 7, 0, 1, 2, 3, 4, 5, 6, 7, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 7,},//GPIO1 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO2 { 0, 1, 2, 3, 4, 5,-1,-1, -1,-1,-1,-1,-1, 5, 6,-1, -1, 1, 2,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO3 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO4 }; static int ORANGEPI_PIN_MASK_900[5][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO0 { 0, 1, 2, 3, 4,-1,-1, 7, 0, 1, 2, 3, 4, 5, 6, 7, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 7,},//GPIO1 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO2 { 0, 1, 2, 3, 4, 5,-1,-1, -1,-1, 2, 3,-1, 5, 6,-1, -1, 1, 2,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO3 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO4 }; static int ORANGEPI_PIN_MASK_CM4[5][32] = //[BANK] [INDEX] { {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, 0, 1,-1,-1,-1,-1,-1,-1,},//GPIO0 { 0, 1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO1 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO2 {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 7, 0, 1, 2, 3, 4, 5,-1, 7,},//GPIO3 { 0, 1, 2, 3, 4, 5, 6, 7, 0,-1, 2, 3, 4, 5,-1,-1, 0,-1,-1, 3,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,},//GPIO4 }; static int ORANGEPI_PIN_MASK_R1_PLUS[5][32] = //[BANK] [INDEX] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PA { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PB { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PC { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},//PD }; static int ORANGEPI_PIN_MASK_H3[9][32] = //[BANK] [INDEX] { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,-1,-1,-1,18,19,20,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB { 0, 1, 2, 3, 4,-1,-1, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PF {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI }; int (*ORANGEPI_PIN_MASK)[32]; // Extend wiringPi with other pin-based devices and keep track of // them in this structure struct wiringPiNodeStruct *wiringPiNodes = NULL ; // BCM Magic #define BCM_PASSWORD 0x5A000000 // The BCM2835 has 54 GPIO pins. // BCM2835 data sheet, Page 90 onwards. // There are 6 control registers, each control the functions of a block // of 10 pins. // Each control register has 10 sets of 3 bits per GPIO pin - the ALT values // // 000 = GPIO Pin X is an input // 001 = GPIO Pin X is an output // 100 = GPIO Pin X takes alternate function 0 // 101 = GPIO Pin X takes alternate function 1 // 110 = GPIO Pin X takes alternate function 2 // 111 = GPIO Pin X takes alternate function 3 // 011 = GPIO Pin X takes alternate function 4 // 010 = GPIO Pin X takes alternate function 5 // // So the 3 bits for port X are: // X / 10 + ((X % 10) * 3) // 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 // Access from ARM Running Linux // Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: // // 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 static volatile unsigned int GPIO_PADS ; static volatile unsigned int GPIO_CLOCK_BASE ; #ifndef CONFIG_ORANGEPI static volatile unsigned int GPIO_BASE ; #endif static volatile unsigned int GPIO_TIMER ; //static volatile unsigned int GPIO_PWM; #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) static unsigned int usingGpioMem = FALSE ; static int wiringPiSetuped = FALSE ; static int wiringPiSysSetuped = FALSE ; // PWM // Word offsets into the PWM control region #define PWM_CONTROL 0 #define PWM_STATUS 1 #define PWM0_RANGE 4 #define PWM0_DATA 5 #define PWM1_RANGE 8 #define PWM1_DATA 9 // Clock regsiter offsets #define PWMCLK_CNTL 40 #define PWMCLK_DIV 41 #define PWM0_MS_MODE 0x0080 // Run in MS mode #define PWM0_USEFIFO 0x0020 // Data from FIFO #define PWM0_REVPOLAR 0x0010 // Reverse polarity #define PWM0_OFFSTATE 0x0008 // Ouput Off state #define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty #define PWM0_SERIAL 0x0002 // Run in serial mode #define PWM0_ENABLE 0x0001 // Channel Enable #define PWM1_MS_MODE 0x8000 // Run in MS mode #define PWM1_USEFIFO 0x2000 // Data from FIFO #define PWM1_REVPOLAR 0x1000 // Reverse polarity #define PWM1_OFFSTATE 0x0800 // Ouput Off state #define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty #define PWM1_SERIAL 0x0200 // Run in serial mode #define PWM1_ENABLE 0x0100 // Channel Enable // Timer // Word offsets #define TIMER_LOAD (0x400 >> 2) #define TIMER_VALUE (0x404 >> 2) #define TIMER_CONTROL (0x408 >> 2) #define TIMER_IRQ_CLR (0x40C >> 2) #define TIMER_IRQ_RAW (0x410 >> 2) #define TIMER_IRQ_MASK (0x414 >> 2) #define TIMER_RELOAD (0x418 >> 2) #define TIMER_PRE_DIV (0x41C >> 2) #define TIMER_COUNTER (0x420 >> 2) // Locals to hold pointers to the hardware 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 ; // Export variables for the hardware pointers volatile unsigned int *_wiringPiGpio ; volatile unsigned int *_wiringPiPwm ; volatile unsigned int *_wiringPiClk ; volatile unsigned int *_wiringPiPads ; volatile unsigned int *_wiringPiTimer ; volatile unsigned int *_wiringPiTimerIrqRaw ; // Data for use with the boardId functions. // The order of entries here to correspond with the PI_MODEL_X // and PI_VERSION_X defines in wiringPi.h // Only intended for the gpio command - use at your own risk! // piGpioBase: // The base address of the GPIO memory mapped hardware IO #define GPIO_PERI_BASE_OLD 0x20000000 #define GPIO_PERI_BASE_NEW 0x3F000000 static volatile unsigned int piGpioBase = 0 ; // Time for easy calculations static uint64_t epochMilli, epochMicro ; // Misc static int wiringPiMode = WPI_MODE_UNINITIALISED ; static volatile int pinPass = -1 ; static pthread_mutex_t pinMutex ; // Debugging & Return codes int wiringPiDebug = FALSE ; int wiringPiReturnCodes = FALSE ; // Use /dev/gpiomem ? int wiringPiTryGpioMem = FALSE ; sunxi_gpio_info sunxi_gpio_info_t; rk3328_soc_info rk3328_soc_info_t; rk3399_soc_info rk3399_soc_info_t; rk3588_soc_info rk3588_soc_info_t; rk3566_soc_info rk3566_soc_info_t; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value static int sysFds[384] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1-1,-1,-1,-1 }; // ISR Data static void (*isrFunctions [64])(void) ; // Doing it the Arduino way with lookup tables... // Yes, it's probably more innefficient than all the bit-twidling, but it // does tend to make it all a bit clearer. At least to me! // pinToGpio: // Take a Wiring pin (0 through X) and re-map it to the GPIO pin // Cope for 3 different board revisions here. static int OrangePiModel; static int *pinToGpio ; int pinToGpio_3[64] = { 122, 121, 118, 354, 355, 120, 114, 119, 362, 111, 112, 229, 230, 117, 228, 227, 360, // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_LITE_2[64] = { 230, 229, 228, 117, 118, 120, 73, 119, 122, 72, 71, 66, 67, 121, 64, 69, 227, // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_ZERO[64] = { 12, 11, 6, 198, 199, 1, 7, 0, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 3, 19, // I2C - SDA0, SCL0 wpi 8 - 9 18, 15, // SPI - CE1, CE0 wpi 10 - 11 16, 2, 14, // SPI - MOSI, MISO, SCLK wpi 12 - 14 13, 10, // UART - Tx, Rx wpi 15 - 16 -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 -1, -1, -1, -1, // B+ wpi 26, 27, 28, 29 -1, 1, // B+ wpi 30, 31 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_H3[64] = { 12, 11, 6, 13, 14, 1, 110, 0, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 3, 68, // I2C - SDA0, SCL0 wpi 8 - 9 71, 64, // SPI - CE1, CE0 wpi 10 - 11 65, 2, 66, // SPI - MOSI, MISO, SCLK wpi 12 - 14 67, 21, // UART - Tx, Rx wpi 15 - 16 19, 18, 7, 8, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 200, 9, 10, 201, 20, // B+ wpi 21, 22, 23, 24, 25 198, 199, // wpi 26, 27 -1, -1, //PA4, PA5(PWM0) wpi 28, 29 -1, -1, // B+ wpi 30, 31 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_ZERO_PLUS_2[64] = { 12, 11, 6, 0, 1, 352, 107, 353, 3, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 19, 18, // I2C - SDA0, SCL0 wpi 8 - 9 15, 16, // SPI - CE1, CE0 wpi 10 - 11 2, 14, 13, // SPI - MOSI, MISO, SCLK wpi 12 - 14 110, -1, // UART - Tx, Rx wpi 15 - 16 -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 -1, -1, // wpi 26, 27 -1, -1, //PA4, PA5(PWM0) wpi 28, 29 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_WIN[64] = { 227, 226, // 0, 1 362, 354, // 2, 3 355, 229, // 4 5 100, 228, // 6, 7 231, 361, // 8, 9 68, 98, //10,11 99, 230, //12,13 97, 96, //14,15 102, 143, //16,17 142, 36, //18,19 37, 34, //20,21 38, 39, //22,23 35, 101, //24,25 32, 33, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_PRIME[64] = { 12, 11, // 0, 1 6, 69, // 2, 3 70, 1, // 4 5 110, 0, // 6, 7 3, 68, // 8, 9 71, 15, // 10,11 16, 2, // 12,13 14, 13, // 14,15 72, 19, // 16,17 18, 7, // 18,19 8, 73, // 20,21 9, 10, // 22,23 74,107, // 24,25 75, 76, // 26,27 -1, -1, // 28,29 -1, -1, // 30,31 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_PC_2[64] = { 12, 11, // 0, 1 6, 69, // 2, 3 70, 1, // 4 5 110,0, // 6, 7 3, 68, // 8, 9 71, 15, //10,11 16, 2, //12,13 14, 13, //14,15 21, 19, //16,17 18, 7, //18,19 8, 200, //20,21 9, 10, //22,23 201,107, //24,25 198, 199, //26,27 -1, -1, //28, 29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_ZERO_PLUS[64] = { 12, 11, 6, 198, 199, 1, 7, 0, 3, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 19, 18, // I2C - SDA0, SCL0 wpi 8 - 9 15, 16, // SPI - CE1, CE0 wpi 10 - 11 2, 14, 13, // SPI - MOSI, MISO, SCLK wpi 12 - 14 10, -1, // UART - Tx, Rx wpi 15 - 16 -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 -1, -1, // wpi 26, 27 -1, -1, //PA4, PA5(PWM0) wpi 28, 29 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_ZERO_2[64] = { 229, 228, 73, 226, 227, 70, 75, 69, 72, 79, 78, 231, 232, 71, 230, 233, 74, 65, 272, 262, 234, // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_ZERO_2_W[64] = { 264, 263, // 0, 1 269, 224, // 2, 3 225, 226, // 4 5 257, 227, // 6, 7 261, 270, // 8, 9 228, 231, //10,11 232, 262, //12,13 230, 229, //14,15 233, 266, //16,17 265, 256, //18,19 271, 267, //20,21 268, 258, //22,23 76, 272, //24,25 260, 259, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int pinToGpio_RK3399[64] = { 43, 44, // 0, 1 64, 148, // 2, 3 147, 80, // 4 5 65, 81, // 6, 7 82, 66, // 8, 9 67, 39, //10,11 40, 83, //12,13 41, 42, //14,15 133, 154, //16,17 50, 68, //18,19 69, 76, //20,21 70, 71, //22,23 73, 72, //24,25 74, 75, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_800[64] = { 43, 44, //0,1 150, 39, //2,3 40, 148, //4,5 152, 147, //6,7 149, 64, //8,9 65, 74, //10,11 73, 153, //12,13 75, 76, //14,15 154, -1, //16,17 -1, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_4[64] = { 64, 65, // 0, 1 150, 145, // 2, 3 144, 33, // 4 5 50, 35, // 6, 7 92, 54, // 8, 9 55, 40, //10,11 39, 56, //12,13 41, 42, //14,15 149, 64, //16,17 65, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_4_LTS[64] = { 52, 53, // 0, 1 150, 145, // 2, 3 144, 33, // 4 5 50, 35, // 6, 7 92, 54, // 8, 9 55, 40, //10,11 39, 56, //12,13 41, 42, //14,15 149, 64, //16,17 65, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_5[64] = { 47, 46, // 0, 1 54, 131, // 2, 3 132,138, // 4 5 29, 139, // 6, 7 28, 59, // 8, 9 58, 49, //10,11 48, 92, //12,13 50, 52, //14,15 35, -1, //16,17 -1, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_5B[64] = { 47, 46, // 0, 1 54, 131, // 2, 3 132,138, // 4 5 29, 139, // 6, 7 28, 59, // 8, 9 58, 49, //10,11 48, 50, //12,13 52, 35, //14,15 -1, -1, //16,17 -1, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_5PLUS[64] = { 16, 15, // 0, 1 62, 33, // 2, 3 32, 36, // 4 5 97, 39, // 6, 7 40, 109, // 8, 9 110, 42, //10,11 41, 34, //12,13 43, 44, //14,15 45, 47, //16,17 46, 63, //18,19 96, 35, //20,21 114, 98, //22,23 101,113, //24,25 100, 99, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_900[64] = { 34, 35, // 0, 1 39, 46, // 2, 3 47, 101, // 4 5 97, 96, // 6, 7 113,107, // 8, 9 62, 42, //10,11 41, 63, //12,13 43, 44, //14,15 45, 32, //16,17 33, 36, //18,19 40, 114, //20,21 106, 98, //22,23 110,109, //24,25 100, 99, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_CM4[64] = { 140,141, // 0, 1 147, 25, // 2, 3 24, 118, // 4 5 119,128, // 6, 7 130,131, // 8, 9 129,138, //10,11 136,132, //12,13 139,134, //14,15 135, 32, //16,17 33, 133, //18,19 124,144, //20,21 127,120, //22,23 125,123, //24,25 122,121, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; int pinToGpio_R1_PLUS[64] = { 89, 88, // 0, 1 100, 102, // 2, 3 112, 103, // 4 5 101, 66, // 6, 7 -1, -1, // 8, 9 -1, -1, //10,11 -1, -1, //12,13 -1, -1, //14,15 -1, -1, //16,17 -1, -1, //18,19 -1, -1, //20,21 -1, -1, //22,23 -1, -1, //24,25 -1, -1, //26,27 -1, -1, //28,29 -1, -1, //30,31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,// ... 63 }; // physToGpio: // Take a physical pin (1 through 26) and re-map it to the GPIO pin // Cope for 2 different board revisions here. // Also add in the P5 connector, so the P5 pins are 3,4,5,6, so 53,54,55,56 static int *physToGpio ; int physToGpio_3[64] = { -1, // 0 -1, -1, // 1, 2 122, -1, 121, -1, 118, 354, -1, 355, 120, 114, 119, -1, 362, 111, -1, 112, 229, -1, 230, 117, 228, 227, -1, 360, // 25, 26 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 58 -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_LITE_2[64] = { -1, // 0 -1, -1, // 1, 2 230, -1, 229, -1, 228, 117, -1, 118, 120, 73, 119, -1, 122, 72, -1, 71, 66, -1, 67, 121, 64, 69, -1, 227, // 25, 26 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_ZERO[64] = { -1, // 0 -1, -1, // 1, 2 12, -1, 11, -1, 6,198, -1,199, 1, 7, 0, -1, 3, 19, -1, 18, 15, -1, 16, 2, 14, 13, -1, 10, // 25, 26 -1, -1, //27, 28 -1, -1, //29, 30 -1, -1, //31, 32 -1, -1, //33, 34 -1, -1, //35, 36 -1, -1, //37, 38 -1, -1, //39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_H3[64] = { -1, // 0 -1, -1, // 1, 2 12, -1, 11, -1, 6, 13, -1, 14, 1, 110, 0, -1, 3, 68, -1, 71, 64, -1, 65, 2, 66, 67, -1, 21, // 25, 26 19, 18, //27, 28 7, -1, //29, 30 8, 200, //31, 32 9, -1, //33, 34 10, 201, //35, 36 20, 198, //37, 38 -1, 199, //39, 40 4, 5, //41, 42 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_ZERO_PLUS_2[64] = { -1, // 0 -1, -1, // 1, 2 12, -1, 11, -1, 6, 0, -1, 1, 352, 107, 353, -1, 3, 19, -1, 18, 15, -1, 16, 2, 14, 13, -1, 110, // 25, 26 -1, -1, //27, 28 -1, -1, //29, 30 -1, -1, //31, 32 -1, -1, //33, 34 -1, -1, //35, 36 -1, -1, //37, 38 -1, -1, //39, 40 -1, -1, //41, 42 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_WIN[64] = { -1, // 0 -1, -1, // 1, 2 227, -1, // 3, 4 226, -1, // 5, 6 362, 354, // 7, 8 -1, 355, // 9, 10 229, 100, //11, 12 228, -1, //13, 14 231, 361, //15, 16 -1, 68, //17, 18 98, -1, //19, 20 99, 230, //21, 22 97, 96, //23, 24 -1, 102, //25, 26 143, 142, //27, 28 36, -1, //29, 30 37, 34, //31, 32 38, -1, //33, 34 39, 35, //35, 36 101, 32, //37, 38 -1, 33, //39, 40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 }; int physToGpio_PRIME[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 12, -1, // 3, 4 11, -1, // 5, 6 6, 69, // 7, 8 -1, 70, // 9, 10 1, 110, //11, 12 0, -1, //13, 14 3, 68, //15, 16 -1, 71, //17, 18 15, -1, //19, 20 16, 2, //21, 22 14, 13, //23, 24 -1, 72, //25, 26 19, 18, //27, 28 7, -1, //29, 30 8, 73, //31, 32 9, -1, //33, 34 10, 74, //35, 36 107, 75, //37, 38 -1, 76, //39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 }; int physToGpio_PC_2[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 12, -1, // 3, 4 11, -1, // 5, 6 6, 69, // 7, 8 -1, 70, // 9, 10 1, 110, //11, 12 0, -1, //13, 14 3, 68, //15, 16 -1, 71, //17, 18 15, -1, //19, 20 16, 2, //21, 22 14, 13, //23, 24 -1, 21, //25, 26 19, 18, //27, 28 7, -1, //29, 30 8, 200, //31, 32 9, -1, //33, 34 10, 201, //35, 36 107, 198, //37, 38 -1, 199, //39, 40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 }; int physToGpio_ZERO_PLUS[64] = { -1, // 0 -1, -1, // 1, 2 12, -1, 11, -1, 6, 198, -1, 199, 1, 7, 0, -1, 3, 19, -1, 18, 15, -1, 16, 2, 14, 13, -1, 10, // 25, 26 -1, -1, //27, 28 -1, -1, //29, 30 -1, -1, //31, 32 -1, -1, //33, 34 -1, -1, //35, 36 -1, -1, //37, 38 -1, -1, //39, 40 -1, -1, //41, 42 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_ZERO_2[64] = { -1, // 0 -1, -1, // 1, 2 229, -1, 228, -1, 73, 226, -1, 227, 70, 75, 69, -1, 72, 79, -1, 78, 231, -1, 232, 71, 230, 233, -1, 74, // 25, 26 65, -1, // 27 272, -1, // 29 262, -1, // 31 234, -1, // 33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_ZERO_2_W[64] = { -1, -1, -1, 264, -1, 263, -1, 269, 224, -1, 225, 226, 257, 227, -1, 261, 270, -1, 228, 231, -1, 232, 262, 230, 229, -1, 233, 266, 265, 256, -1, 271, 267, 268, -1, 258, 76, 272, 260, -1, 259, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_RK3399[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 43, -1, // 3, 4 44, -1, // 5, 6 64, 148, // 7, 8 -1, 147, // 9, 10 80, 65, // 11, 12 81, -1, // 13, 14 82, 66, // 15, 16 -1, 67, // 17, 18 39, -1, // 19, 20 40, 83, // 21, 22 41, 42, // 23, 24 -1, 133, // 25, 26 154, 50, // 27, 28 68, -1, // 29, 30 69, 76, // 31, 32 70, -1, // 33, 34 71, 73, // 35, 36 72, 74, // 37, 38 -1, 75, // 39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_800[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 43, -1, // 3, 4 44, -1, // 5, 6 150, 39, // 7, 8 -1, 40, // 9, 10 148, 152, // 11, 12 147, -1, // 13, 14 149, 64, // 15, 16 -1, 65, // 17, 18 74, -1, // 19, 20 73, 153, // 21, 22 75, 76, // 23, 24 -1, 154, // 25, 26 -1, -1, // 27, 28 -1, -1, // 29, 30 -1, -1, // 31, 32 -1, -1, // 33, 34 -1, -1, // 35, 36 -1, -1, // 37, 38 -1, 75, // 39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_4[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 64, -1, // 3, 4 65, -1, // 5, 6 150, 145, // 7, 8 -1, 144, // 9, 10 33, 50, // 11, 12 35, -1, // 13, 14 92, 54, // 15, 16 -1, 55, // 17, 18 40, -1, // 19, 20 39, 56, // 21, 22 41, 42, // 23, 24 -1, 149, // 25, 26 64, 65, // 27, 28 -1, -1, // 29, 30 -1, 76, // 31, 32 -1, -1, // 33, 34 -1, 73, // 35, 36 -1, 74, // 37, 38 -1, 75, // 39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_4_LTS[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 64, -1, // 3, 4 65, -1, // 5, 6 150, 145, // 7, 8 -1, 144, // 9, 10 33, 50, // 11, 12 35, -1, // 13, 14 92, 54, // 15, 16 -1, 55, // 17, 18 40, -1, // 19, 20 39, 56, // 21, 22 41, 42, // 23, 24 -1, 149, // 25, 26 -1, -1, // 27, 28 -1, -1, // 29, 30 -1, -1, // 31, 32 -1, -1, // 33, 34 -1, -1, // 35, 36 -1, -1, // 37, 38 -1, -1, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_5[64] = { -1, // 0 -1, -1, // 1, 2 47, -1, // 3, 4 46, -1, // 5, 6 54, 131, // 7, 8 -1, 132, // 9, 10 138, 29, // 11, 12 139, -1, // 13, 14 28, 59, // 15, 16 -1, 58, // 17, 18 49, -1, // 19, 20 48, 92, // 21, 22 50, 52, // 23, 24 -1, 35, // 25, 26 -1, -1, // 27, 28 -1, -1, // 29, 30 -1, -1, // 31, 32 -1, -1, // 33, 34 -1, -1, // 35, 36 -1, -1, // 37, 38 -1, -1, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_5B[64] = { -1, // 0 -1, -1, // 1, 2 47, -1, // 3, 4 46, -1, // 5, 6 54, 131, // 7, 8 -1, 132, // 9, 10 138, 29, // 11, 12 139, -1, // 13, 14 28, 59, // 15, 16 -1, 58, // 17, 18 49, -1, // 19, 20 48, -1, // 21, 22 50, 52, // 23, 24 -1, 35, // 25, 26 -1, -1, // 27, 28 -1, -1, // 29, 30 -1, -1, // 31, 32 -1, -1, // 33, 34 -1, -1, // 35, 36 -1, -1, // 37, 38 -1, -1, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_5PLUS[64] = { -1, // 0 -1, -1, // 1, 2 16, -1, // 3, 4 15, -1, // 5, 6 62, 33, // 7, 8 -1, 32, // 9, 10 36, 97, // 11, 12 39, -1, // 13, 14 40, 109, // 15, 16 -1, 110, // 17, 18 42, -1, // 19, 20 41, 34, // 21, 22 43, 44, // 23, 24 -1, 45, // 25, 26 47, 46, // 27, 28 63, -1, // 29, 30 96, 35, // 31, 32 114, -1, // 33, 34 98, 101, // 35, 36 113,100, // 37, 38 -1, 99, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_900[64] = { -1, // 0 -1, -1, // 1, 2 34, -1, // 3, 4 35, -1, // 5, 6 39, 46, // 7, 8 -1, 47, // 9, 10 101, 97, // 11, 12 96, -1, // 13, 14 113, 107, // 15, 16 -1, 62, // 17, 18 42, -1, // 19, 20 41, 63, // 21, 22 43, 44, // 23, 24 -1, 45, // 25, 26 32, 33, // 27, 28 36, -1, // 29, 30 40, 114, // 31, 32 106, -1, // 33, 34 98, 110, // 35, 36 109,100, // 37, 38 -1, 99, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_CM4[64] = { -1, // 0 -1, -1, // 1, 2 140, -1, // 3, 4 141, -1, // 5, 6 147, 25, // 7, 8 -1, 24, // 9, 10 118,119, // 11, 12 128, -1, // 13, 14 130,131, // 15, 16 -1, 129, // 17, 18 138, -1, // 19, 20 136,132, // 21, 22 139,134, // 23, 24 -1, 135, // 25, 26 32, 33, // 27, 28 133, -1, // 29, 30 124,144, // 31, 32 127, -1, // 33, 34 120,125, // 35, 36 123,122, // 37, 38 -1, 121, // 39, 40 //Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; int physToGpio_R1_PLUS[64] =//head num map to OrangePi { -1, // 0 -1, -1, // 1, 2 89, 88, // 3, 4 100, 102, // 5, 6 -1, -1, // 7, 8 -1, 112, // 9, 10 103,101, // 11, 12 66, -1, // 13, 14 -1, -1, // 15, 16 -1, -1, // 17, 18 -1, -1, // 19, 20 -1, -1, // 21, 22 -1, -1, // 23, 24 -1, -1, // 25, 26 -1, -1, // 27, 28 -1, -1, // 29, 30 -1, -1, // 31, 32 -1, -1, // 33, 34 -1, -1, // 35, 36 -1, -1, // 37, 38 -1, -1, // 39, 40 // Padding: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 -1, -1, -1, -1, -1, -1, -1, // ... 63 }; // gpioToGPFSEL: // Map a BCM_GPIO pin to it's Function Selection // control port. (GPFSEL 0-5) // Groups of 10 - 3 bits per Function - 30 bits per port static uint8_t gpioToGPFSEL [] = { 0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5, } ; // gpioToShift // Define the shift up for the 3 bits per pin in each GPFSEL port static uint8_t gpioToShift [] = { 0,3,6,9,12,15,18,21,24,27, 0,3,6,9,12,15,18,21,24,27, 0,3,6,9,12,15,18,21,24,27, 0,3,6,9,12,15,18,21,24,27, 0,3,6,9,12,15,18,21,24,27, 0,3,6,9,12,15,18,21,24,27, } ; // gpioToGPSET: // (Word) offset to the GPIO Set registers for each GPIO pin static uint8_t gpioToGPSET [] = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, } ; // gpioToGPCLR: // (Word) offset to the GPIO Clear registers for each GPIO pin static uint8_t gpioToGPCLR [] = { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, } ; // gpioToGPLEV: // (Word) offset to the GPIO Input level registers for each GPIO pin static uint8_t gpioToGPLEV [] = { 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, } ; #ifdef notYetReady // gpioToEDS // (Word) offset to the Event Detect Status static uint8_t gpioToEDS [] = { 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, } ; // gpioToREN // (Word) offset to the Rising edge ENable register static uint8_t gpioToREN [] = { 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, } ; // gpioToFEN // (Word) offset to the Falling edgde ENable register static uint8_t gpioToFEN [] = { 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, } ; #endif // GPPUD: // GPIO Pin pull up/down register #define GPPUD 37 // gpioToPUDCLK // (Word) offset to the Pull Up Down Clock regsiter static uint8_t gpioToPUDCLK [] = { 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, } ; // gpioToPwmALT // the ALT value to put a GPIO pin into PWM mode 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, 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 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ; // gpioToPwmPort // The port value to put a GPIO pin into PWM mode /*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, 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 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ;*/ // gpioToGpClkALT: // ALT value to put a GPIO pin into GP Clock mode. // On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21 // for clocks 0 and 1 respectively, however I'll include the full // list for completeness - maybe one day... #define GPIO_CLOCK_SOURCE 1 // gpioToGpClkALT0: static uint8_t gpioToGpClkALT0 [] = { 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, // 0 -> 7 0, 0, 0, 0, 0, 0, 0, 0, // 8 -> 15 0, 0, 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, // 16 -> 23 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 FSEL_ALT0, 0, FSEL_ALT0, 0, 0, 0, 0, 0, // 32 -> 39 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, 0, 0, // 40 -> 47 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ; // gpioToClk: // (word) Offsets to the clock Control and Divisor register static uint8_t gpioToClkCon [] = { -1, -1, -1, -1, 28, 30, 32, -1, // 0 -> 7 -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15 -1, -1, -1, -1, 28, 30, -1, -1, // 16 -> 23 -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31 28, -1, 28, -1, -1, -1, -1, -1, // 32 -> 39 -1, -1, 28, 30, 28, -1, -1, -1, // 40 -> 47 -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55 -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63 } ; static uint8_t gpioToClkDiv [] = { -1, -1, -1, -1, 29, 31, 33, -1, // 0 -> 7 -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15 -1, -1, -1, -1, 29, 31, -1, -1, // 16 -> 23 -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31 29, -1, 29, -1, -1, -1, -1, -1, // 32 -> 39 -1, -1, 29, 31, 29, -1, -1, -1, // 40 -> 47 -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55 -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63 } ; /* * Functions ********************************************************************************* */ /* * wiringPiFailure: * Fail. Or not. ********************************************************************************* */ int wiringPiFailure (int fatal, const char *message, ...) { va_list argp ; char buffer [1024] ; if (!fatal && wiringPiReturnCodes) return -1 ; va_start (argp, message) ; vsnprintf (buffer, 1023, message, argp) ; va_end (argp) ; fprintf (stderr, "%s", buffer) ; exit (EXIT_FAILURE) ; return 0 ; } /* * setupCheck * Another sanity check because some users forget to call the setup * function. Mosty because they need feeding C drip by drip )-: ********************************************************************************* */ static void setupCheck (const char *fName) { if (!wiringPiSetuped) { fprintf (stderr, "%s: You have not called one of the wiringPiSetup\n" " functions, so I'm aborting your program before it crashes anyway.\n", fName) ; exit (EXIT_FAILURE) ; } } /* * gpioMemCheck: * See if we're using the /dev/gpiomem interface, if-so then some operations * can't be done and will crash the Pi. ********************************************************************************* */ static void usingGpioMemCheck (const char *what) { if (usingGpioMem) { fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ; exit (EXIT_FAILURE) ; } } /* * piGpioLayout: * Return a number representing the hardware revision of the board. * This is not strictly the board revision but is used to check the * layout of the GPIO connector - and there are 2 types that we are * really interested in here. The very earliest Pi's and the * ones that came after that which switched some pins .... * * Revision 1 really means the early Model A and B's. * Revision 2 is everything else - it covers the B, B+ and CM. * ... and the Pi 2 - which is a B+ ++ ... * ... and the Pi 0 - which is an A+ ... * * The main difference between the revision 1 and 2 system that I use here * is the mapping of the GPIO pins. From revision 2, the Pi Foundation changed * 3 GPIO pins on the (original) 26-way header - BCM_GPIO 22 was dropped and * replaced with 27, and 0 + 1 - I2C bus 0 was changed to 2 + 3; I2C bus 1. * * Additionally, here we set the piModel2 flag too. This is again, nothing to * do with the actual model, but the major version numbers - the GPIO base * hardware address changed at model 2 and above (not the Zero though) * ********************************************************************************* */ void piGpioLayoutOops (const char *why) { fprintf (stderr, "Oops: Unable to determine board revision from /etc/orangepi-release or /etc/armbian-release.\n") ; fprintf (stderr, " -> %s\n", why) ; fprintf (stderr, " -> You'd best google the error to find out why.\n") ; exit (EXIT_FAILURE) ; } void piBoardId (int * model) { FILE *cpuFd ; char line [40] ; char *c; char revision[40]; unsigned int i = 0; if ((cpuFd = fopen ("/etc/orangepi-release", "r")) == NULL) if ((cpuFd = fopen ("/etc/armbian-release", "r")) == NULL) piGpioLayoutOops ("Unable to open /etc/orangepi-release or /etc/armbian-release."); while (fgets (line, 40, cpuFd) != NULL) if (strncmp (line, "BOARD=", 6) == 0) break ; fclose (cpuFd) ; if (strncmp (line, "BOARD=", 6) != 0) piGpioLayoutOops ("No \"Revision\" line") ; if (wiringPiDebug) printf ("piBoardId: Revision string: %s\n", line) ; // Chomp trailing CR/NL for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) *c = 0 ; // Need to work out if it's using the new or old encoding scheme: // Scan to the first character of the revision number for (c = line ; *c ; ++c) if (*c == '=') break ; if (*c != '=') piGpioLayoutOops ("Revision line (no equal)"); c++; for (i = 0; *c ; ++c) revision[i++] = *c; revision[i] = '.'; if (wiringPiDebug) printf ("piBoardId: Board string: %s\n", revision) ; /**/ if (strncmp(revision, "orangepi3.", 10) == 0) { *model = PI_MODEL_3; } else if (strncmp(revision, "orangepi3-lts.", 14) == 0) { *model = PI_MODEL_3; } else if (strncmp(revision, "orangepioneplus.", 16) == 0) { *model = PI_MODEL_LTIE_2; } else if (strncmp(revision, "orangepilite2.", 14) == 0) { *model = PI_MODEL_LTIE_2; } else if (strncmp(revision, "orangepizero.", 13) == 0) { *model = PI_MODEL_ZERO; } else if (strncmp(revision, "orangepizerolts.", 16) == 0) { *model = PI_MODEL_ZERO; } else if (strncmp(revision, "orangepizero-lts.", 17) == 0) { *model = PI_MODEL_ZERO; } else if (strncmp(revision, "orangepir1.", 11) == 0) { *model = PI_MODEL_ZERO; } else if (strncmp(revision, "orangepi-r1.", 12) == 0) { *model = PI_MODEL_ZERO; } else if (strncmp(revision, "orangepipc.", 11) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepipcplus.", 15) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepione.", 12) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepilite.", 13) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepiplus.", 13) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepiplue2e.", 15) == 0) { *model = PI_MODEL_H3; } else if (strncmp(revision, "orangepizeroplus2h3.", 20) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizeroplus2-h3.", 21) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepiwin.", 12) == 0) { *model = PI_MODEL_WIN; } else if (strncmp(revision, "orangepiwinplus.", 16) == 0) { *model = PI_MODEL_WIN; } else if (strncmp(revision, "orangepiprime.", 14) == 0) { *model = PI_MODEL_PRIME; } else if (strncmp(revision, "orangepipc2.", 12) == 0) { *model = PI_MODEL_PC_2; } else if (strncmp(revision, "orangepizeroplus.", 17) == 0) { *model = PI_MODEL_ZERO_PLUS; } else if (strncmp(revision, "orangepizeroplus2h5.", 20) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizeroplus2-h5.", 21) == 0) { *model = PI_MODEL_ZERO_PLUS_2; } else if (strncmp(revision, "orangepizero2.", 14) == 0) { *model = PI_MODEL_ZERO_2; } else if (strncmp(revision, "orangepizero2w.", 14) == 0) { *model = PI_MODEL_ZERO_2_W; } else if (strncmp(revision, "orangepizero3.", 14) == 0) { *model = PI_MODEL_ZERO_2; } else if (strncmp(revision, "orangepirk3399.", 15) == 0) { *model = PI_MODEL_RK3399; } else if (strncmp(revision, "orangepi-rk3399.", 16) == 0) { *model = PI_MODEL_RK3399; } else if (strncmp(revision, "orangepi800.", 12) == 0) { *model = PI_MODEL_800; } else if (strncmp(revision, "orangepi4.", 10) == 0) { *model = PI_MODEL_4; } else if (strncmp(revision, "orangepi4-lts.", 14) == 0) { *model = PI_MODEL_4_LTS; } else if (strncmp(revision, "orangepir1plus.", 15) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepi-r1plus.", 16) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepir1plus-lts.", 18) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepi-r1plus-lts.", 20) == 0) { *model = PI_MODEL_R1_PLUS; } else if (strncmp(revision, "orangepi5.", 10) == 0) { *model = PI_MODEL_5; } else if (strncmp(revision, "orangepi5b.", 11) == 0) { *model = PI_MODEL_5B; } else if (strncmp(revision, "orangepi5plus.", 14) == 0) { *model = PI_MODEL_5_PLUS; } else if (strncmp(revision, "orangepi900.", 12) == 0) { *model = PI_MODEL_900; } else if (strncmp(revision, "orangepicm4.", 12) == 0) { *model = PI_MODEL_CM4; } else if (strncmp(revision, "orangepi3b.", 11) == 0) { *model = PI_MODEL_3B; } if (wiringPiDebug) printf("piBoardId: model = %d\n", *model); } /* * wpiPinToGpio: * Translate a wiringPi Pin number to native GPIO pin number. * Provided for external support. ********************************************************************************* */ int wpiPinToGpio (int wpiPin) { return pinToGpio [wpiPin & 63] ; } /* * physPinToGpio: * Translate a physical Pin number to native GPIO pin number. * Provided for external support. ********************************************************************************* */ int physPinToGpio (int physPin) { return physToGpio [physPin & 63] ; } /* * setPadDrive: * Set the PAD driver value ********************************************************************************* */ void setPadDrive (int group, int value) { uint32_t wrVal ; if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if ((group < 0) || (group > 2)) return ; wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; *(pads + group + 11) = wrVal ; if (wiringPiDebug) { printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; printf ("Read : %08X\n", *(pads + group + 11)) ; } } } /* * getAlt: * Returns the ALT bits for a given port. Only really of-use * for the gpio readall command (I think) ********************************************************************************* */ int getAlt (int pin) { int alt; pin &= 63; if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin]; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin]; else if (wiringPiMode != WPI_MODE_GPIO) return 0; alt = OrangePi_get_gpio_mode(pin); return alt; } /* * pwmSetMode: * Select the native "balanced" mode, or standard mark:space mode ********************************************************************************* */ void pwmSetMode(int mode) { return; } /* * pwmSetRange: * Set the PWM range register. We set both range registers to the same * value. If you want different in your own code, then write your own. ********************************************************************************* */ void pwmSetRange(unsigned int range) { return; } /* * pwmSetClock: * Set/Change the PWM clock. Originally my code, but changed * (for the better!) by Chris Hall, * after further study of the manual and testing with a 'scope ********************************************************************************* */ void pwmSetClock(int divisor) { return; } /* * gpioClockSet: * Set the frequency on a GPIO clock pin ********************************************************************************* */ void gpioClockSet (int pin, int freq) { int divi, divr, divf ; pin &= 63 ; /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; else if (wiringPiMode != WPI_MODE_GPIO) return ; divi = 19200000 / freq ; divr = 19200000 % freq ; divf = (int)((double)divr * 4096.0 / 19200000.0) ; if (divi > 4095) divi = 4095 ; *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait ; *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock } /* * wiringPiFindNode: * Locate our device node ********************************************************************************* */ struct wiringPiNodeStruct *wiringPiFindNode (int pin) { struct wiringPiNodeStruct *node = wiringPiNodes ; while (node != NULL) if ((pin >= node->pinBase) && (pin <= node->pinMax)) return node ; else node = node->next ; return NULL ; } /* * wiringPiNewNode: * Create a new GPIO node into the wiringPi handling system ********************************************************************************* */ static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } //static unsigned int digitalRead8Dummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return 0 ; } //static void digitalWrite8Dummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) { int pin ; struct wiringPiNodeStruct *node ; // Minimum pin base is 64 if (pinBase < 64) (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ; // Check all pins in-case there is overlap: for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin) if (wiringPiFindNode (pin) != NULL) (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ; node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros if (node == NULL) (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ; node->pinBase = pinBase ; node->pinMax = pinBase + numPins - 1 ; node->pinMode = pinModeDummy ; node->pullUpDnControl = pullUpDnControlDummy ; node->digitalRead = digitalReadDummy ; //node->digitalRead8 = digitalRead8Dummy ; node->digitalWrite = digitalWriteDummy ; //node->digitalWrite8 = digitalWrite8Dummy ; node->pwmWrite = pwmWriteDummy ; node->analogRead = analogReadDummy ; node->analogWrite = analogWriteDummy ; node->next = wiringPiNodes ; wiringPiNodes = node ; return node ; } #ifdef notYetReady /* * pinED01: * pinED10: * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0 * Pin must already be in input mode with appropriate pull up/downs set. ********************************************************************************* */ void pinEnableED01Pi (int pin) { pin = pinToGpio [pin & 63] ; } #endif /* ********************************************************************************* * Core Functions ********************************************************************************* */ /* * pinModeAlt: * This is an un-documented special to let you set any pin to any mode ********************************************************************************* */ void pinModeAlt (int pin, int mode) { int fSel, shift ; setupCheck ("pinModeAlt") ; /* #ifdef CONFIG_ORANGEPI #if !(defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_2G_IOT) if(version == ORANGEPI) { if (wiringPiDebug) printf("PinModeAlt: pin:%d,mode:%d\n", pin, mode); if ((pin & PI_GPIO_MASK) == 0) { 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 (-1 == pin) { printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); return; } if ( mode <= 1 || mode >= 8){ printf("[%s:L%d] the mode:%d is invaild,please check it over!\n", __func__, __LINE__, mode); return; } OrangePi_set_gpio_alt(pin, mode); return; } else { return ; } } #endif #endif */ /* if ((pin & PI_GPIO_MASK) == 0) { if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; else if (wiringPiMode != WPI_MODE_GPIO) return ; fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; } */ } /* * pinMode: * Sets the mode of a pin to be input, output or PWM output ********************************************************************************* */ void pinMode (int pin, int mode) { int fSel, shift, alt ; struct wiringPiNodeStruct *node = wiringPiNodes ; int origPin = pin ; setupCheck ("pinMode") ; if (wiringPiDebug) printf("PinMode: pin:%d,mode:%d\n", pin, mode); if ((pin & PI_GPIO_MASK) == 0) { 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 (-1 == pin) { printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); return; } if (mode == INPUT) { OrangePi_set_gpio_mode(pin, INPUT); return; } else if (mode == OUTPUT) { OrangePi_set_gpio_mode(pin, OUTPUT); return ; } else if (mode == PWM_OUTPUT) { if(pin != 5) { printf("the pin you choose doesn't support hardware PWM\n"); printf("you can select wiringPi pin %d for PWM pin\n", 42); printf("or you can use it in softPwm mode\n"); return; } OrangePi_set_gpio_mode(pin, PWM_OUTPUT); return; } else return; } else { if ((node = wiringPiFindNode (pin)) != NULL) node->pinMode(node, pin, mode); return ; } } /* * pullUpDownCtrl: * Control the internal pull-up/down resistors on a GPIO pin. ********************************************************************************* */ void pullUpDnControl (int pin, int pud) { struct wiringPiNodeStruct *node = wiringPiNodes ; setupCheck ("pullUpDnControl") ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { /**/ 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 (pud == PUD_OFF) { OrangePi_set_gpio_pullUpDnControl(pin, PUD_OFF); } else if (pud == PUD_UP){ OrangePi_set_gpio_pullUpDnControl(pin, PUD_UP); } else if (pud == PUD_DOWN){ OrangePi_set_gpio_pullUpDnControl(pin, PUD_DOWN); } } else // Extension module { if ((node = wiringPiFindNode (pin)) != NULL) node->pullUpDnControl (node, pin, pud) ; return ; } } /* * digitalRead: * Read the value of a given Pin, returning HIGH or LOW ********************************************************************************* */ int digitalRead (int pin) { char c ; int ret; struct wiringPiNodeStruct *node = wiringPiNodes ; if ((pin & PI_GPIO_MASK) == 0) { if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode { if (sysFds [pin] == -1) return LOW ; ret = lseek(sysFds [pin], 0L, SEEK_SET) ; ret = read(sysFds [pin], &c, 1); if (ret < 0) return -1; return (c == '0') ? LOW : HIGH ; } else if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio[pin]; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio[pin]; else if (wiringPiMode != WPI_MODE_GPIO) return -1; if (pin == -1) { printf("[%s %d]Pin %d is invalid, please check it over!\n", __func__, __LINE__, pin); return LOW; } return OrangePi_digitalRead(pin); } else { if ((node = wiringPiFindNode (pin)) == NULL) return LOW ; return node->digitalRead (node, pin) ; } } /* * digitalRead8: * Read 8-bits (a byte) from given start pin. ********************************************************************************* unsigned int digitalRead8 (int pin) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin return 0 ; else { if ((node = wiringPiFindNode (pin)) == NULL) return LOW ; return node->digitalRead8 (node, pin) ; } } */ /* * digitalWrite: * Set an output bit ********************************************************************************* */ void digitalWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; int ret; if ((pin & PI_GPIO_MASK) == 0) { if (wiringPiMode == WPI_MODE_GPIO_SYS) { if (sysFds [pin] != -1) { if (value == LOW) { ret = write (sysFds [pin], "0\n", 2); if (ret < 0) return; } else { ret = write (sysFds [pin], "1\n", 2); if (ret < 0) return; } } return ; } else if (wiringPiMode == WPI_MODE_PINS) { pin = pinToGpio[pin]; } else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio[pin]; else return; if(-1 == pin) { printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); printf("[%s:L%d] the mode is: %d, please check it over!\n", __func__, __LINE__, wiringPiMode); return; } OrangePi_digitalWrite(pin, value); } else { if ((node = wiringPiFindNode(pin)) != NULL) node->digitalWrite(node, pin, value); } return; } /* * digitalWrite8: * Set an output 8-bit byte on the device from the given pin number ********************************************************************************* void digitalWrite8 (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin return ; else { if ((node = wiringPiFindNode (pin)) != NULL) node->digitalWrite8 (node, pin, value) ; } } */ /* * pwmWrite: * Set an output PWM value ********************************************************************************* */ void pwmWrite(int pin, int value) { return; } /* * analogRead: * Read the analog value of a given Pin. * There is no on-board Pi analog hardware, * so this needs to go to a new node. ********************************************************************************* */ int analogRead (int pin) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((node = wiringPiFindNode (pin)) == NULL) return 0 ; else return node->analogRead (node, pin) ; } /* * analogWrite: * Write the analog value to the given Pin. * There is no on-board Pi analog hardware, * so this needs to go to a new node. ********************************************************************************* */ void analogWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; if ((node = wiringPiFindNode (pin)) == NULL) return ; node->analogWrite (node, pin, value) ; } /* * pwmToneWrite: * Pi Specific. * Output the given frequency on the Pi's PWM pin ********************************************************************************* */ void pwmToneWrite (int pin, int freq) { int range ; setupCheck ("pwmToneWrite") ; if (freq == 0) pwmWrite (pin, 0) ; // Off else { range = 600000 / freq ; pwmSetRange (range) ; pwmWrite (pin, freq / 2) ; } } /* * digitalWriteByte: * digitalReadByte: * Pi Specific * Write an 8-bit byte to the first 8 GPIO pins - try to do it as * fast as possible. * However it still needs 2 operations to set the bits, so any external * hardware must not rely on seeing a change as there will be a change * to set the outputs bits to zero, then another change to set the 1's * Reading is just bit fiddling. * These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers * 17, 18, 22, 23, 24, 24, 4 on a Pi v1 rev 0-3 * 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, 3, zero ********************************************************************************* */ void digitalWriteByte (const int value) { int mask = 1 ; int pin ; for (pin = 0 ; pin < 8 ; ++pin) { digitalWrite (pin, (value >> pin) & mask) ; } return ; } unsigned int digitalReadByte (void) { int pin, x ; uint32_t data = 0 ; for (pin = 7 ; pin >= 0 ; --pin){ x = digitalRead(pin); data = (data << 1) | x ; } return data ; } /* * digitalWriteByte2: * digitalReadByte2: * Pi Specific * Write an 8-bit byte to the second set of 8 GPIO pins. This is marginally * faster than the first lot as these are consecutive BCM_GPIO pin numbers. * However they overlap with the original read/write bytes. ********************************************************************************* */ void digitalWriteByte2 (const int value) { register int mask = 1 ; register int pin ; /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) { for (pin = 20 ; pin < 28 ; ++pin) { digitalWrite (pin, value & mask) ; mask <<= 1 ; } return ; } else { *(gpio + gpioToGPCLR [0]) = (~value & 0xFF) << 20 ; // 0x0FF00000; ILJ > CHANGE: Old causes glitch *(gpio + gpioToGPSET [0]) = ( value & 0xFF) << 20 ; } } unsigned int digitalReadByte2 (void) { int pin, x ; uint32_t data = 0 ; /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) { for (pin = 20 ; pin < 28 ; ++pin) { x = digitalRead (pin) ; data = (data << 1) | x ; } } else data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins return data ; } /* * waitForInterrupt: * Pi Specific. * Wait for Interrupt on a GPIO pin. * This is actually done via the /sys/class/gpio interface regardless of * the wiringPi access mode in-use. Maybe sometime it might get a better * way for a bit more efficiency. ********************************************************************************* */ int waitForInterrupt (int pin, int mS) { int fd, x ; uint8_t c ; struct pollfd polls ; int ret; /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) pin = physToGpio [pin] ; if ((fd = sysFds [pin]) == -1) return -2 ; // Setup poll structure polls.fd = fd ; polls.events = POLLPRI | POLLERR ; // Wait for it ... x = poll (&polls, 1, mS) ; // If no error, do a dummy read to clear the interrupt // A one character read appars to be enough. if (x > 0) { lseek (fd, 0, SEEK_SET) ; // Rewind ret = read (fd, &c, 1) ; // Read & clear if (ret < 0) return -1; } return x ; } /* * interruptHandler: * This is a thread and gets started to wait for the interrupt we're * hoping to catch. It will call the user-function when the interrupt * fires. ********************************************************************************* */ static void *interruptHandler (UNU void *arg) { int myPin ; (void)piHiPri (55) ; // Only effective if we run as root myPin = pinPass ; pinPass = -1 ; for (;;) if (waitForInterrupt (myPin, -1) > 0) isrFunctions [myPin] () ; return NULL ; } /* * wiringPiISR: * Pi Specific. * Take the details and create an interrupt handler that will do a call- * back to the user supplied function. ********************************************************************************* */ int wiringPiISR (int pin, int mode, void (*function)(void)) { pthread_t threadId ; const char *modeS ; char fName [64] ; char pinS [8] ; pid_t pid ; int count, i ; char c ; int bcmGpioPin ; int ret; if ((pin < 0) || (pin > 63)) return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED) return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; else if (wiringPiMode == WPI_MODE_PINS) bcmGpioPin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) bcmGpioPin = physToGpio [pin] ; else bcmGpioPin = pin ; // Now export the pin and set the right edge // We're going to use the gpio program to do this, so it assumes // a full installation of wiringPi. It's a bit 'clunky', but it // is a way that will work when we're running in "Sys" mode, as // a non-root user. (without sudo) if (mode != INT_EDGE_SETUP) { /**/ if (mode == INT_EDGE_FALLING) modeS = "falling" ; else if (mode == INT_EDGE_RISING) modeS = "rising" ; else modeS = "both" ; sprintf (pinS, "%d", pin) ; if ((pid = fork ()) < 0) // Fail return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; if (pid == 0) // Child, exec { /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0) { execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; } else if (access ("/usr/bin/gpio", X_OK) == 0) { execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; } else return wiringPiFailure (WPI_FATAL, "wiringPiISR: Can't find gpio program\n") ; } else // Parent, wait wait (NULL) ; } // Now pre-open the /sys/class node - but it may already be open if // we are in Sys mode... if (sysFds [bcmGpioPin] == -1) { sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; } // Clear any initial pending interrupt ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ; for (i = 0 ; i < count ; ++i){ ret = read (sysFds [bcmGpioPin], &c, 1) ; if (ret < 0) return -1; } isrFunctions [pin] = function ; pthread_mutex_lock (&pinMutex) ; pinPass = pin ; pthread_create (&threadId, NULL, interruptHandler, NULL) ; while (pinPass != -1) delay (1) ; pthread_mutex_unlock (&pinMutex) ; return 0 ; } /* * initialiseEpoch: * Initialise our start-of-time variable to be the current unix * time in milliseconds and microseconds. ********************************************************************************* */ static void initialiseEpoch (void) { #ifdef OLD_WAY struct timeval tv ; gettimeofday (&tv, NULL) ; epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ; #else struct timespec ts ; clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; epochMilli = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ; epochMicro = (uint64_t)ts.tv_sec * (uint64_t)1000000 + (uint64_t)(ts.tv_nsec / 1000L) ; #endif } /* * delay: * Wait for some number of milliseconds ********************************************************************************* */ void delay (unsigned int howLong) { struct timespec sleeper, dummy ; sleeper.tv_sec = (time_t)(howLong / 1000) ; sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ; nanosleep (&sleeper, &dummy) ; } /* * delayMicroseconds: * This is somewhat intersting. It seems that on the Pi, a single call * to nanosleep takes some 80 to 130 microseconds anyway, so while * obeying the standards (may take longer), it's not always what we * want! * * So what I'll do now is if the delay is less than 100uS we'll do it * in a hard loop, watching a built-in counter on the ARM chip. This is * somewhat sub-optimal in that it uses 100% CPU, something not an issue * in a microcontroller, but under a multi-tasking, multi-user OS, it's * wastefull, however we've no real choice )-: * * Plan B: It seems all might not be well with that plan, so changing it * to use gettimeofday () and poll on that instead... ********************************************************************************* */ void delayMicrosecondsHard (unsigned int howLong) { struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; tLong.tv_sec = howLong / 1000000 ; tLong.tv_usec = howLong % 1000000 ; timeradd (&tNow, &tLong, &tEnd) ; while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL) ; } void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; unsigned int uSecs = howLong % 1000000 ; unsigned int wSecs = howLong / 1000000 ; /**/ if (howLong == 0) return ; else if (howLong < 100) delayMicrosecondsHard (howLong) ; else { sleeper.tv_sec = wSecs ; sleeper.tv_nsec = (long)(uSecs * 1000L) ; nanosleep (&sleeper, NULL) ; } } /* * millis: * Return a number of milliseconds as an unsigned int. * Wraps at 49 days. ********************************************************************************* */ unsigned int millis (void) { uint64_t now ; #ifdef OLD_WAY struct timeval tv ; gettimeofday (&tv, NULL) ; now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; #else struct timespec ts ; clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; now = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ; #endif return (uint32_t)(now - epochMilli) ; } /* * micros: * Return a number of microseconds as an unsigned int. * Wraps after 71 minutes. ********************************************************************************* */ unsigned int micros (void) { uint64_t now ; #ifdef OLD_WAY struct timeval tv ; gettimeofday (&tv, NULL) ; now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ; #else struct timespec ts ; clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; now = (uint64_t)ts.tv_sec * (uint64_t)1000000 + (uint64_t)(ts.tv_nsec / 1000) ; #endif return (uint32_t)(now - epochMicro) ; } /* * wiringPiVersion: * Return our current version number ********************************************************************************* */ void wiringPiVersion (int *major, int *minor) { *major = VERSION_MAJOR ; *minor = VERSION_MINOR ; } void set_soc_info(void) { switch (OrangePiModel) { case PI_MODEL_3: case PI_MODEL_LTIE_2: case PI_MODEL_ZERO_2: case PI_MODEL_ZERO_2_W: sunxi_gpio_info_t.gpio_base_addr = H6_GPIO_BASE_ADDR; sunxi_gpio_info_t.r_gpio_base_addr = H6_R_GPIO_BASE_ADDR; sunxi_gpio_info_t.gpio_base_offset = 0x0; sunxi_gpio_info_t.r_gpio_base_offset = 0x0; break; case PI_MODEL_ZERO: case PI_MODEL_ZERO_PLUS_2: case PI_MODEL_WIN: case PI_MODEL_PRIME: case PI_MODEL_PC_2: case PI_MODEL_ZERO_PLUS: case PI_MODEL_H3: sunxi_gpio_info_t.gpio_base_addr = H3_GPIO_BASE_ADDR; sunxi_gpio_info_t.r_gpio_base_addr = H3_R_GPIO_BASE_ADDR; sunxi_gpio_info_t.gpio_base_offset = 0x800; sunxi_gpio_info_t.r_gpio_base_offset = 0xc00; break; default: break; } } /* * wiringPiSetup: * Must be called once at the start of your program execution. * * Default setup: Initialises the system into wiringPi Pin mode and uses the * memory mapped hardware directly. * * Changed now to revert to "gpio" mode if we're running on a Compute Module. ********************************************************************************* */ int wiringPiSetup (void) { int fd; // It's actually a fatal error to call any of the wiringPiSetup routines more than once, // (you run out of file handles!) but I'm fed-up with the useless twats who email // me bleating that there is a bug in my code, so screw-em. if (wiringPiSetuped) return 0 ; wiringPiSetuped = TRUE ; if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; if (getenv (ENV_CODES) != NULL) wiringPiReturnCodes = TRUE ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetup called\n") ; piBoardId (&OrangePiModel) ; wiringPiMode = WPI_MODE_PINS ; switch (OrangePiModel) { case PI_MODEL_3: pinToGpio = pinToGpio_3; physToGpio = physToGpio_3; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_3; break; case PI_MODEL_LTIE_2: pinToGpio = pinToGpio_LITE_2; physToGpio = physToGpio_LITE_2; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_LITE_2; break; case PI_MODEL_ZERO: pinToGpio = pinToGpio_ZERO; physToGpio = physToGpio_ZERO; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_ZERO; break; case PI_MODEL_ZERO_PLUS_2: pinToGpio = pinToGpio_ZERO_PLUS_2; physToGpio = physToGpio_ZERO_PLUS_2; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_ZERO_PLUS_2; break; case PI_MODEL_WIN: pinToGpio = pinToGpio_WIN; physToGpio = physToGpio_WIN; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_WIN; break; case PI_MODEL_PRIME: pinToGpio = pinToGpio_PRIME; physToGpio = physToGpio_PRIME; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_PRIME; break; case PI_MODEL_PC_2: pinToGpio = pinToGpio_PC_2; physToGpio = physToGpio_PC_2; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_PC_2; break; case PI_MODEL_ZERO_PLUS: pinToGpio = pinToGpio_ZERO_PLUS; physToGpio = physToGpio_ZERO_PLUS; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_ZERO_PLUS; break; case PI_MODEL_ZERO_2: pinToGpio = pinToGpio_ZERO_2; physToGpio = physToGpio_ZERO_2; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_ZERO_2; break; case PI_MODEL_ZERO_2_W: pinToGpio = pinToGpio_ZERO_2_W; physToGpio = physToGpio_ZERO_2_W; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_ZERO_2_W; break; case PI_MODEL_800: pinToGpio = pinToGpio_800; physToGpio = physToGpio_800; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_800; break; case PI_MODEL_4: pinToGpio = pinToGpio_4; physToGpio = physToGpio_4; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_4; break; case PI_MODEL_4_LTS: pinToGpio = pinToGpio_4_LTS; physToGpio = physToGpio_4_LTS; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_4_LTS; break; case PI_MODEL_RK3399: pinToGpio = pinToGpio_RK3399; physToGpio = physToGpio_RK3399; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_RK3399; break; case PI_MODEL_R1_PLUS: pinToGpio = pinToGpio_R1_PLUS; physToGpio = physToGpio_R1_PLUS; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_R1_PLUS; break; case PI_MODEL_H3: pinToGpio = pinToGpio_H3; physToGpio = physToGpio_H3; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_H3; break; case PI_MODEL_5: pinToGpio = pinToGpio_5; physToGpio = physToGpio_5; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_5; break; case PI_MODEL_5B: pinToGpio = pinToGpio_5B; physToGpio = physToGpio_5B; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_5B; break; case PI_MODEL_5_PLUS: pinToGpio = pinToGpio_5PLUS; physToGpio = physToGpio_5PLUS; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_5PLUS; break; case PI_MODEL_900: pinToGpio = pinToGpio_900; physToGpio = physToGpio_900; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_900; break; case PI_MODEL_CM4: case PI_MODEL_3B: pinToGpio = pinToGpio_CM4; physToGpio = physToGpio_CM4; ORANGEPI_PIN_MASK = ORANGEPI_PIN_MASK_CM4; break; default: printf ("Oops - unable to determine board type... model: %d\n", OrangePiModel); break ; } set_soc_info(); // Open the master /dev/ memory control device // Device strategy: December 2016: // Try /dev/mem. If that fails, then // try /dev/gpiomem. If that fails then game over. if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0){ if ((fd = open ("/dev/gpiomem", 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" " 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)) ; } switch (OrangePiModel) { case PI_MODEL_3: case PI_MODEL_LTIE_2: case PI_MODEL_ZERO_2: case PI_MODEL_ZERO: case PI_MODEL_ZERO_PLUS_2: case PI_MODEL_WIN: case PI_MODEL_PRIME: case PI_MODEL_PC_2: case PI_MODEL_ZERO_PLUS: case PI_MODEL_H3: case PI_MODEL_ZERO_2_W: sunxi_gpio_info_t.gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, sunxi_gpio_info_t.gpio_base_addr); if ((int32_t)(unsigned long)sunxi_gpio_info_t.gpio == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); sunxi_gpio_info_t.r_gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, sunxi_gpio_info_t.r_gpio_base_addr); if ((int32_t)(unsigned long)sunxi_gpio_info_t.r_gpio == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); break; case PI_MODEL_R1_PLUS: rk3328_soc_info_t.cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3328_CRU_BASE); if ((int32_t)(unsigned long)rk3328_soc_info_t.cru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (CRU_BASE) failed: %s\n", strerror(errno)); rk3328_soc_info_t.grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3328_GRF_BASE); if ((int32_t)(unsigned long)rk3328_soc_info_t.grf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GRF_BASE) failed: %s\n", strerror(errno)); rk3328_soc_info_t.gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3328_GPIO2_BASE); if ((int32_t)(unsigned long)rk3328_soc_info_t.gpio2_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO2_BASE) failed: %s\n", strerror(errno)); rk3328_soc_info_t.gpio3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3328_GPIO3_BASE); if ((int32_t)(unsigned long)rk3328_soc_info_t.gpio3_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO3_BASE) failed: %s\n", strerror(errno)); break; case PI_MODEL_RK3399: case PI_MODEL_4: case PI_MODEL_4_LTS: case PI_MODEL_800: rk3399_soc_info_t.gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_GPIO2_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.gpio2_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO2_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_CRU_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.cru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (CRU_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.pmucru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_PMUCRU_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.pmucru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (PMUCRU_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_GRF_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.grf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GRF_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.pmugrf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_PMUGRF_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.pmugrf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (PMUGRF_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.gpio1_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_GPIO1_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.grf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO1_BASE) failed: %s\n", strerror(errno)); rk3399_soc_info_t.gpio4_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3399_GPIO4_BASE); if ((int32_t)(unsigned long)rk3399_soc_info_t.gpio4_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO4_BASE) failed: %s\n", strerror(errno)); break; case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: /* GPIO Register */ rk3588_soc_info_t.gpio0_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_GPIO0_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.gpio0_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_GPIO0_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.gpio1_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_GPIO1_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.gpio1_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_GPIO1_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_GPIO2_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.gpio2_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_GPIO2_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.gpio3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_GPIO3_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.gpio3_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_GPIO3_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.gpio4_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_GPIO4_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.gpio4_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_GPIO4_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.pmu1_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PMU1_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1_ioc_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PMU1_IOC_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.pmu2_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PMU2_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu2_ioc_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PMU2_IOC_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.bus_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_BUS_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.bus_ioc_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_BUS_IOC_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.cur_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_CRU_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_CRU_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.pmu1cur_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_PMU1CRU_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_PMU1CRU_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.vccio1_4_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_VCCIO1_4_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_VCCIO1_4_IOC_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.vccio3_5_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_VCCIO3_5_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_VCCIO3_5_IOC_BASE) failed: %s\n", strerror(errno)); rk3588_soc_info_t.vccio6_ioc_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3588_VCCIO6_IOC_BASE); if ((int32_t)(unsigned long)rk3588_soc_info_t.pmu1cur_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3588_VCCIO6_IOC_BASE) failed: %s\n", strerror(errno)); break; case PI_MODEL_CM4: case PI_MODEL_3B: /* GPIO Register */ rk3566_soc_info_t.gpio0_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_GPIO0_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.gpio0_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_GPIO0_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.gpio1_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_GPIO1_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.gpio1_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_GPIO1_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_GPIO2_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.gpio2_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_GPIO2_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.gpio3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_GPIO3_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.gpio3_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_GPIO3_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.gpio4_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_GPIO4_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.gpio4_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_GPIO4_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.pmu_grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_PMU_GRF_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.pmu_grf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_PMU_GRF_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.sys_grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_SYS_GRF_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.sys_grf_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_SYS_GRF_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_CRU_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.cru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_CRU_BASE) failed: %s\n", strerror(errno)); rk3566_soc_info_t.pmu_cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, RK3566_PMU_CRU_BASE); if ((int32_t)(unsigned long)rk3566_soc_info_t.pmu_cru_base == -1) return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (RK3566_PMU_CRU_BASE) failed: %s\n", strerror(errno)); break; default: printf("model %d is error\n", OrangePiModel); break ; } initialiseEpoch () ; return 0 ; } /* * wiringPiSetupGpio: * Must be called once at the start of your program execution. * * GPIO setup: Initialises the system into GPIO Pin mode and uses the * memory mapped hardware directly. ********************************************************************************* */ int wiringPiSetupGpio (void) { (void)wiringPiSetup () ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupGpio called\n") ; wiringPiMode = WPI_MODE_GPIO ; return 0 ; } /* * wiringPiSetupPhys: * Must be called once at the start of your program execution. * * Phys setup: Initialises the system into Physical Pin mode and uses the * memory mapped hardware directly. ********************************************************************************* */ int wiringPiSetupPhys (void) { (void)wiringPiSetup () ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupPhys called\n") ; wiringPiMode = WPI_MODE_PHYS ; return 0 ; } /* * wiringPiSetupSys: * Must be called once at the start of your program execution. * * Initialisation (again), however this time we are using the /sys/class/gpio * interface to the GPIO systems - slightly slower, but always usable as * a non-root user, assuming the devices are already exported and setup correctly. */ int wiringPiSetupSys (void) { int pin ; int tmpGpio; char fName [128] ; if (wiringPiSysSetuped) return 0 ; wiringPiSysSetuped = TRUE ; if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; if (getenv (ENV_CODES) != NULL) wiringPiReturnCodes = TRUE ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; piBoardId (&OrangePiModel) ; switch (OrangePiModel) { case PI_MODEL_3: pinToGpio = pinToGpio_3; physToGpio = physToGpio_3; break; case PI_MODEL_LTIE_2: pinToGpio = pinToGpio_LITE_2; physToGpio = physToGpio_LITE_2; break; case PI_MODEL_ZERO: pinToGpio = pinToGpio_LITE_2; physToGpio = physToGpio_LITE_2; break; case PI_MODEL_ZERO_PLUS_2: pinToGpio = pinToGpio_ZERO_PLUS_2; physToGpio = physToGpio_ZERO_PLUS_2; break; case PI_MODEL_WIN: pinToGpio = pinToGpio_WIN; physToGpio = physToGpio_WIN; break; case PI_MODEL_PRIME: pinToGpio = pinToGpio_PRIME; physToGpio = physToGpio_PRIME; break; case PI_MODEL_PC_2: pinToGpio = pinToGpio_PC_2; physToGpio = physToGpio_PC_2; break; case PI_MODEL_ZERO_PLUS: pinToGpio = pinToGpio_ZERO_PLUS; physToGpio = physToGpio_ZERO_PLUS; break; case PI_MODEL_ZERO_2: pinToGpio = pinToGpio_ZERO_2; physToGpio = physToGpio_ZERO_2; break; case PI_MODEL_ZERO_2_W: pinToGpio = pinToGpio_ZERO_2_W; physToGpio = physToGpio_ZERO_2_W; break; case PI_MODEL_800: pinToGpio = pinToGpio_800; physToGpio = physToGpio_800; break; case PI_MODEL_4: pinToGpio = pinToGpio_4; physToGpio = physToGpio_4; break; case PI_MODEL_4_LTS: pinToGpio = pinToGpio_4_LTS; physToGpio = physToGpio_4_LTS; break; case PI_MODEL_RK3399: pinToGpio = pinToGpio_RK3399; physToGpio = physToGpio_RK3399; break; case PI_MODEL_R1_PLUS: pinToGpio = pinToGpio_R1_PLUS; physToGpio = physToGpio_R1_PLUS; break; default: pinToGpio = pinToGpio_H3; physToGpio = physToGpio_H3; break ; } // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later for (pin = 1 ; pin < 28 ; ++pin) { tmpGpio = pinToGpio[pin]; sprintf (fName, "/sys/class/gpio/gpio%d/value", tmpGpio) ; sysFds [pin] = open (fName, O_RDWR) ; } initialiseEpoch () ; wiringPiMode = WPI_MODE_GPIO_SYS; return 0 ; } /* * Read register value helper */ unsigned int readR(unsigned int addr) { unsigned int val = 0; unsigned int mmap_base; unsigned int mmap_seek; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: val = 0; mmap_base = (addr & (0xfffff000)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3588_GPIO0_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio0_base + mmap_seek)); else if(mmap_base == RK3588_GPIO1_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio1_base + mmap_seek)); else if(mmap_base == RK3588_GPIO2_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio2_base + mmap_seek)); else if(mmap_base == RK3588_GPIO3_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio3_base + mmap_seek)); else if(mmap_base == RK3588_GPIO4_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio4_base + mmap_seek)); else if(mmap_base == RK3588_PMU1_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu1_ioc_base + mmap_seek)); else if(mmap_base == RK3588_BUS_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.bus_ioc_base + mmap_seek)); else if(mmap_base == RK3588_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.cur_base + mmap_seek)); else if(mmap_base == RK3588_PMU1CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu1cur_base + mmap_seek)); else if(mmap_base == RK3588_PMU2_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu2_ioc_base + mmap_seek)); else if(mmap_base == RK3588_VCCIO1_4_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio1_4_ioc_base + mmap_seek)); else if(mmap_base == RK3588_VCCIO3_5_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio3_5_ioc_base + mmap_seek)); else if(mmap_base == RK3588_VCCIO6_IOC_BASE) val = *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio6_ioc_base + mmap_seek)); return val; break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: val = 0; mmap_base = (addr & (0xfffff000)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3399_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.cru_base + mmap_seek)); else if(mmap_base == RK3399_GRF_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.grf_base + mmap_seek)); else if(mmap_base == RK3399_GPIO2_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio2_base + mmap_seek)); else if(mmap_base == RK3399_GPIO1_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio1_base + mmap_seek)); else if(mmap_base == RK3399_PMUCRU_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.pmucru_base + mmap_seek)); else if(mmap_base == RK3399_PMUGRF_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.pmugrf_base + mmap_seek)); else if(mmap_base == RK3399_GPIO4_BASE) val = *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio4_base + mmap_seek)); return val; break; case PI_MODEL_R1_PLUS: val = 0; mmap_base = (addr & (0xfffff000)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3328_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3328_soc_info_t.cru_base + mmap_seek)); else if(mmap_base == RK3328_GRF_BASE) val = *((unsigned int *)((unsigned char *)rk3328_soc_info_t.grf_base + mmap_seek)); else if(mmap_base == RK3328_GPIO2_BASE) val = *((unsigned int *)((unsigned char *)rk3328_soc_info_t.gpio2_base + mmap_seek)); else if(mmap_base == RK3328_GPIO3_BASE) val = *((unsigned int *)((unsigned char *)rk3328_soc_info_t.gpio3_base + mmap_seek)); return val; break; case PI_MODEL_CM4: case PI_MODEL_3B: val = 0; mmap_base = (addr & (0xfffff000)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3566_GPIO0_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio0_base + mmap_seek)); else if(mmap_base == RK3566_GPIO1_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio1_base + mmap_seek)); else if(mmap_base == RK3566_GPIO2_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio2_base + mmap_seek)); else if(mmap_base == RK3566_GPIO3_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio3_base + mmap_seek)); else if(mmap_base == RK3566_GPIO4_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio4_base + mmap_seek)); else if(mmap_base == RK3566_PMU_GRF_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_grf_base + mmap_seek)); else if(mmap_base == RK3566_SYS_GRF_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.sys_grf_base + mmap_seek)); else if(mmap_base == RK3566_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.cru_base + mmap_seek)); else if(mmap_base == RK3566_PMU_CRU_BASE) val = *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_cru_base + mmap_seek)); return val; break; default: val = 0; mmap_base = (addr & 0xfffff000); mmap_seek = ((addr - mmap_base) >> 2); if (addr >= sunxi_gpio_info_t.r_gpio_base_addr) val = *(sunxi_gpio_info_t.r_gpio + mmap_seek); else val = *(sunxi_gpio_info_t.gpio + mmap_seek); return val; break; } return -1; } /* * Wirte value to register helper */ void writeR(unsigned int val, unsigned int addr) { unsigned int mmap_base; unsigned int mmap_seek; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: mmap_base = (addr & (~0xfff)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3588_GPIO0_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio0_base + mmap_seek)) = val; else if(mmap_base == RK3588_GPIO1_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio1_base + mmap_seek)) = val; else if(mmap_base == RK3588_GPIO2_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio2_base + mmap_seek)) = val; else if(mmap_base == RK3588_GPIO3_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio3_base + mmap_seek)) = val; else if(mmap_base == RK3588_GPIO4_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.gpio4_base + mmap_seek)) = val; else if(mmap_base == RK3588_PMU1_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu1_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_BUS_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.bus_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_CRU_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.cur_base + mmap_seek)) = val; else if(mmap_base == RK3588_PMU1CRU_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu1cur_base + mmap_seek)) = val; else if(mmap_base == RK3588_PMU2_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.pmu2_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_VCCIO1_4_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio1_4_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_VCCIO3_5_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio3_5_ioc_base + mmap_seek)) = val; else if(mmap_base == RK3588_VCCIO6_IOC_BASE) *((unsigned int *)((unsigned char *)rk3588_soc_info_t.vccio6_ioc_base + mmap_seek)) = val; break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: mmap_base = (addr & (~0xfff)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3399_CRU_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.cru_base + mmap_seek)) = val; else if(mmap_base == RK3399_GRF_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.grf_base + mmap_seek)) = val; else if(mmap_base == RK3399_GPIO2_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio2_base + mmap_seek)) = val; else if(mmap_base == RK3399_GPIO1_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio1_base + mmap_seek)) = val; else if(mmap_base == RK3399_PMUCRU_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.pmucru_base + mmap_seek)) = val; else if(mmap_base == RK3399_PMUGRF_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.pmugrf_base + mmap_seek)) = val; else if(mmap_base == RK3399_GPIO4_BASE) *((unsigned int *)((unsigned char *)rk3399_soc_info_t.gpio4_base + mmap_seek)) = val; break; case PI_MODEL_R1_PLUS: mmap_base = (addr & (~0xfff)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3328_CRU_BASE) *((unsigned int *)((unsigned char *)rk3328_soc_info_t.cru_base + mmap_seek)) = val; else if(mmap_base == RK3328_GRF_BASE) *((unsigned int *)((unsigned char *)rk3328_soc_info_t.grf_base + mmap_seek)) = val; else if(mmap_base == RK3328_GPIO2_BASE) *((unsigned int *)((unsigned char *)rk3328_soc_info_t.gpio2_base + mmap_seek)) = val; else if(mmap_base == RK3328_GPIO3_BASE) *((unsigned int *)((unsigned char *)rk3328_soc_info_t.gpio3_base + mmap_seek)) = val; break; case PI_MODEL_CM4: case PI_MODEL_3B: mmap_base = (addr & (~0xfff)); mmap_seek = (addr - mmap_base); if(mmap_base == RK3566_GPIO0_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio0_base + mmap_seek)) = val; else if(mmap_base == RK3566_GPIO1_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio1_base + mmap_seek)) = val; else if(mmap_base == RK3566_GPIO2_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio2_base + mmap_seek)) = val; else if(mmap_base == RK3566_GPIO3_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio3_base + mmap_seek)) = val; else if(mmap_base == RK3566_GPIO4_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.gpio4_base + mmap_seek)) = val; else if(mmap_base == RK3566_PMU_GRF_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_grf_base + mmap_seek)) = val; else if(mmap_base == RK3566_SYS_GRF_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.sys_grf_base + mmap_seek)) = val; else if(mmap_base == RK3566_CRU_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.cru_base + mmap_seek)) = val; else if(mmap_base == RK3566_PMU_CRU_BASE) *((unsigned int *)((unsigned char *)rk3566_soc_info_t.pmu_cru_base + mmap_seek)) = val; break; default: mmap_base = (addr & 0xfffff000); mmap_seek = ((addr - mmap_base) >> 2); if (addr >= sunxi_gpio_info_t.r_gpio_base_addr) *(sunxi_gpio_info_t.r_gpio + mmap_seek) = val; else *(sunxi_gpio_info_t.gpio + mmap_seek) = val; break; } } int OrangePi_get_gpio_mode(int pin) { unsigned int regval = 0; unsigned int bank = pin >> 5; unsigned int index = pin - (bank << 5); unsigned int phyaddr = 0; unsigned char mode = -1; unsigned int grf_phyaddr = 0, ddr_phyaddr = 0; unsigned int rk3588_pmu1_ioc_phyaddr; unsigned int rk3588_bus_ioc_phyaddr; int offset; switch (OrangePiModel) { case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: offset = ((index - ((index >> 3) << 3))); if(bank == 1){ grf_phyaddr = RK3399_PMUGRF_BASE + ((index >> 3) << 2) + 0x10; ddr_phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } else if(bank == 2){ grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2); ddr_phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } else if(bank == 4){ grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2) +0x20; ddr_phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(grf_phyaddr); mode = (regval >> (offset << 1)) & 0x3;//获取控制模式的那两位的值 if(mode == 0){ //如果是gpio模式 regval = readR(ddr_phyaddr);//获取gpio方向寄存器的值 return (regval >> index) & 1;//index对应的gpio的方向值,0为in,1为out } return mode + 1;//如果不是gpio模式,返回的alt,从2开始,0和1是in和out } break; case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: rk3588_bus_ioc_phyaddr = RK3588_BUS_IOC_BASE + (0x20 * bank) + ((index >> 2) << 2); if(bank == 0){ if (index < 12){ ;/* Todo */ }else{ ddr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } } else if(bank == 1){ ddr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } else if(bank == 2){ ddr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } else if(bank == 3){ ddr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } else if(bank == 4){ ddr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } if (ORANGEPI_PIN_MASK[bank][index] != -1) { if ( bank == 0 && index < 12 ) ;/*Todo*/ else regval = readR(rk3588_bus_ioc_phyaddr); mode = (regval >> ((index % 4) << 2)) & 0xf;//获取控制模式的那四位的值 if(mode == 0){ //如果是gpio模式 regval = readR(ddr_phyaddr); //获取gpio方向寄存器的值 return (regval >> (index % 16)) & 0x1; //index对应的gpio的方向值,0为in,1为out } return mode + 1; //如果不是gpio模式,返回的alt,从2开始,0和1是in和out } break; case PI_MODEL_R1_PLUS: offset = ((index - ((index >> 3) << 3))); if(bank == 2) { //ddr_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET; ddr_phyaddr = 0xff230004; //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10; if(0 == (index >> 3))//gpio2_ax { grf_phyaddr = RK3328_GRF_BASE + 0x20; } else if(3 == (index >> 3))//gpio2_dx { grf_phyaddr = RK3328_GRF_BASE + 0x34; } } else if(bank == 3) { //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; ddr_phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET; if (0 == (index >> 3)) { if(4 == offset)//gpio3_a4 { grf_phyaddr = RK3328_GRF_BASE + 0x38; } else//gpio3_a567 { grf_phyaddr = RK3328_GRF_BASE + 0x3c; } } else if(2 == (index >> 3)) //gpio3_c { grf_phyaddr = RK3328_GRF_BASE + 0x48; } } if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(grf_phyaddr); writeR(0xffff9877, 0xff440240); if(3 == bank && (0 == (index >> 3))) //gpio3_ax需要写3位 { mode = (regval >> ((offset % 5) * 3)) & 0x7; } else { mode = (regval >> (offset << 1)) & 0x3; } if(mode == 0){ regval = readR(ddr_phyaddr); return (regval >> index) & 1; } return mode + 1; } break; case PI_MODEL_CM4: case PI_MODEL_3B: if(bank == 0){ grf_phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET + ((pin >> 2) << 2); ddr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2); } else{ grf_phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_IOMUX_L_OFFSET + (((pin - 32) >> 2) << 2); ddr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2); } offset = (index % 4) << 2; if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(grf_phyaddr); mode = (regval >> offset) & 0x7; if(mode == 0){ //如果是gpio模式 regval = readR(ddr_phyaddr);//获取gpio方向寄存器的值 return (regval >> (index % 16)) & 0x1;//index对应的gpio的方向值,0为in,1为out } return mode + 1;//如果不是gpio模式,返回的alt,从2开始,0和1是in和out } break; default: offset = ((index - ((index >> 3) << 3)) << 2); if (bank == 11) phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 3) << 2); else phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 3) << 2); /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(phyaddr); mode = (regval >> offset) & 7; } return mode; break; } return -1; } /* * Set GPIO Mode */ int OrangePi_set_gpio_mode(int pin, int mode) { unsigned int regval = 0; unsigned int bank = pin >> 5; unsigned int index = pin - (bank << 5); unsigned int phyaddr = 0; int offset; unsigned int cru_phyaddr =0, grf_phyaddr = 0, gpio_phyaddr = 0, ddr_phyaddr = 0; unsigned int cru_val = 0; unsigned int rk3588_pmu1_ioc_phyaddr; unsigned int rk3588_bus_ioc_phyaddr; unsigned int temp = 0; unsigned int bit_enable; unsigned int grf_val = 0; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: rk3588_bus_ioc_phyaddr = RK3588_BUS_IOC_BASE + (0x20 * bank) + ((index >> 2) << 2); if(bank == 0){ if (index < 12){ ;/* Todo */ }else{ ddr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); } cru_phyaddr = RK3588_PMU1CRU_BASE + RK3588_PMU1CRU_GATE_CON5_OFFSET; cru_val = 0xffff9fff; } else if(bank == 1){ ddr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON16_OFFSET; cru_val = 0xffff3fff; } else if(bank == 2){ ddr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } else if(bank == 3){ ddr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } else if(bank == 4){ ddr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(cru_phyaddr); regval &= cru_val; writeR(regval, cru_phyaddr); regval = readR(rk3588_bus_ioc_phyaddr); regval |= 0xffff0000; regval &= ~(0xf << ((index % 4) << 2)); writeR(regval, rk3588_bus_ioc_phyaddr); regval = readR(rk3588_bus_ioc_phyaddr); /* Set Input */ if(INPUT == mode) { regval = readR(ddr_phyaddr); regval |= 0xffff0000; regval &= ~(1 << (index % 16)); writeR(regval, ddr_phyaddr); if (wiringPiDebug){ regval = readR(ddr_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } } else if(OUTPUT == mode) { regval = readR(ddr_phyaddr); regval |= 0xffff0000; regval |= (1 << (index % 16)); writeR(regval, ddr_phyaddr); if (wiringPiDebug){ regval = readR(ddr_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } } else { printf("Unknow mode\n"); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: offset = ((index - ((index >> 3) << 3))); if(bank == 1){ cru_phyaddr = RK3399_PMUCRU_BASE + RK3399_PMUCRU_CLKGATE_CON1_OFFSET; grf_phyaddr = RK3399_PMUGRF_BASE + ((index >> 3) << 2) + 0x10; gpio_phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } else if(bank == 2){ cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET; grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2); gpio_phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } else if(bank == 4){ cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET; grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2) +0x20; gpio_phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { if (wiringPiDebug) printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); /* Set Input */ if(INPUT == mode) { writeR(0xffff0180, cru_phyaddr); regval = readR(grf_phyaddr); regval |= 0x3 << ((offset << 1) | 0x10); regval &= ~(0x3 << (offset << 1)); writeR(regval, grf_phyaddr); regval = readR(gpio_phyaddr); regval &= ~(1 << index); writeR(regval, gpio_phyaddr); if (wiringPiDebug){ regval = readR(gpio_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } } else if(OUTPUT == mode) { /* Set Output */ writeR(0xffff0180, cru_phyaddr); regval = readR(grf_phyaddr); regval |= 0x3 << ((offset << 1) | 0x10); regval &= ~(0x3 << (offset << 1)); writeR(regval, grf_phyaddr); regval = readR(gpio_phyaddr); regval |= 1 << index; writeR(regval, gpio_phyaddr); if (wiringPiDebug) { regval = readR(gpio_phyaddr); printf("Out mode get value: 0x%x\n",regval); } } else { printf("Unknow mode\n"); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_R1_PLUS: offset = ((index - ((index >> 3) << 3))); if(bank == 2) { cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET; //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10; gpio_phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET; if(0 == (index >> 3))//gpio2_ax { grf_phyaddr = RK3328_GRF_BASE + 0x20; } else if(3 == (index >> 3))//gpio2_dx { grf_phyaddr = RK3328_GRF_BASE + 0x34; } } else if(bank == 3) { cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET; //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; gpio_phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET; if (0 == (index >> 3)) { if(4 == offset)//gpio3_a4 { grf_phyaddr = RK3328_GRF_BASE + 0x38; } else//gpio3_a567 { grf_phyaddr = RK3328_GRF_BASE + 0x3c; } } else if(2 == (index >> 3)) //gpio3_c { grf_phyaddr = RK3328_GRF_BASE + 0x48; } } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { if (wiringPiDebug) printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); /* Set Input */ if(INPUT == mode) { writeR(0xffff9877, cru_phyaddr); regval = readR(grf_phyaddr); if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需要写3位 { regval |= 0xffff0000; regval &= ~(0x7 << ((offset % 5) * 3)); } else //其他的写两位 { regval |= 0xffff0000; regval &= ~(0x3 << (offset << 1)); } writeR(regval, grf_phyaddr); regval = readR(gpio_phyaddr); regval &= ~(1 << index); writeR(regval, gpio_phyaddr); if (wiringPiDebug) { regval = readR(gpio_phyaddr); printf("Input mode set over reg val: %#x\n",regval); } } else if(OUTPUT == mode) { /* Set Output */ writeR(0xffff9877, cru_phyaddr); regval = readR(grf_phyaddr); if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需要写3位 { regval |= 0xffff0000; regval &= ~(0x7 << ((offset % 5) * 3)); } else //其他的写两位 { regval |= 0xffff0000; regval &= ~(0x3 << (offset << 1)); } writeR(regval, grf_phyaddr); regval = readR(gpio_phyaddr); regval |= 1 << index; writeR(regval, gpio_phyaddr); if (wiringPiDebug) { regval = readR(gpio_phyaddr); printf("Out mode get value: 0x%x\n",regval); } } else { printf("Unknow mode\n"); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_CM4: case PI_MODEL_3B: if(bank == 0){ cru_phyaddr = RK3566_PMU_CRU_BASE + RK3566_PMUCRU_PMUGATE_CON01_OFFSET; cru_val = ~((0x3 << 9) | (0x3 << (16 + 9))); grf_phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET + ((pin >> 2) << 2); ddr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2); } else{ cru_phyaddr = RK3566_CRU_BASE + RK3566_CRU_GATE_CON31_OFFSET; cru_val = ~((0xff << 2) | (0xff << (16 + 2))); grf_phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_IOMUX_L_OFFSET + (((pin - 32) >> 2) << 2); ddr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2); } offset = (index % 4) << 2; bit_enable = 0x7 << (16 + offset); /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(cru_phyaddr); regval &= cru_val; writeR(regval, cru_phyaddr); regval = readR(grf_phyaddr); if(wiringPiDebug) printf("read val(%#x) from register[%#x]\n", regval, grf_phyaddr); regval |= bit_enable; regval &= ~(0x7 << offset); if (wiringPiDebug) printf("write val(%#x) to register[%#x]\n", regval, grf_phyaddr); writeR(regval, grf_phyaddr); regval = readR(grf_phyaddr); if(wiringPiDebug) printf("set over reg val: 0x%x\n", regval); regval = readR(ddr_phyaddr); if(wiringPiDebug) printf("read val ddr (%#x) from register[%#x]\n", regval, ddr_phyaddr); regval |= 0x1 << (16 + (index % 16)); if(INPUT == mode) regval &= ~(1 << (index % 16)); else regval |= (1 << (index % 16)); writeR(regval, ddr_phyaddr); if (wiringPiDebug) printf("write val(%#x) to register[%#x]\n", regval, ddr_phyaddr); regval = readR(ddr_phyaddr); if (wiringPiDebug) printf("set over reg val: 0x%x\n", regval); } else { printf("Pin mode failed!\n"); } break; default: offset = ((index - ((index >> 3) << 3)) << 2); if (bank == 11) phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 3) << 2); else phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 3) << 2); /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(phyaddr); if (wiringPiDebug) printf("Before read reg val: 0x%x offset:%d\n",regval,offset); if (wiringPiDebug) printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); /* Set Input */ if(INPUT == mode) { regval &= ~(7 << offset); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("Input mode set over reg val: %#x\n",regval); } else if(OUTPUT == mode) { /* Set Output */ regval &= ~(7 << offset); regval |= (1 << offset); if (wiringPiDebug) printf("Out mode ready set val: 0x%x\n",regval); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("Out mode get value: 0x%x\n",regval); } else { printf("Unknow mode\n"); } } else { printf("Pin mode failed!\n"); } break; } return 0; } int OrangePi_set_gpio_alt(int pin, int mode) { unsigned int regval = 0; unsigned int bank = pin >> 5; unsigned int index = pin - (bank << 5); unsigned int phyaddr = 0; int offset = ((index - ((index >> 3) << 3)) << 2); if (bank == 11) phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + ((index >> 3) << 2); else phyaddr = sunxi_gpio_info_t.gpio_base_addr + (bank * 36) + ((index >> 3) << 2); /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { if (wiringPiDebug) printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); regval = readR(phyaddr); regval &= ~(7 << offset); regval |= (mode << offset); writeR(regval, phyaddr); } else { printf("Pin alt mode failed!\n"); } return 0; } /* * OrangePi Digital write */ int OrangePi_digitalWrite(int pin, int value) { unsigned int bank = pin >> 5; unsigned int index = pin - (bank << 5); unsigned int phyaddr = 0; unsigned int regval = 0; unsigned int cru_phyaddr =0, gpio_phyaddr = 0, dr_phyaddr = 0; unsigned int cru_val = 0; unsigned int temp = 0; unsigned int bit_enable = 0; unsigned int offset; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: if(bank == 0){ dr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_PMU1CRU_BASE + RK3588_PMU1CRU_GATE_CON5_OFFSET; cru_val = 0xffff9fff; } else if(bank == 1){ dr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON16_OFFSET; cru_val = 0xffff3fff; } else if(bank == 2){ dr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } else if(bank == 3){ dr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } else if(bank == 4){ dr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2); cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET; cru_val = 0xffffffc0; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(cru_phyaddr); regval &= cru_val; writeR(regval, cru_phyaddr); if(0 == value) { regval = readR(dr_phyaddr); regval |= 0xffff0000; regval &= ~(1 << (index % 16)); writeR(regval, dr_phyaddr); regval = readR(dr_phyaddr); if (wiringPiDebug) printf("LOW val set over reg val: 0x%x\n", regval); } else { regval = readR(dr_phyaddr); regval |= 0xffff0000; regval |= (1 << (index % 16)); writeR(regval, dr_phyaddr); regval = readR(dr_phyaddr); if (wiringPiDebug) printf("HIGH val set over reg val: 0x%x\n", regval); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: if(bank == 1) { phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET; cru_phyaddr = RK3399_PMUCRU_BASE + RK3399_PMUCRU_CLKGATE_CON1_OFFSET; } else if(bank == 2) { phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET; cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET; } else if(bank == 4) { phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET; cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { writeR(0xffff0180, cru_phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("befor write reg val: 0x%x,index:%d\n", regval, index); if(0 == value) { regval &= ~(1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("LOW val set over reg val: 0x%x\n", regval); } else { regval |= (1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("HIGH val set over reg val: 0x%x\n", regval); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_R1_PLUS: if(bank == 2) { phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_SWPORTA_DR_OFFSET; cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET; } else if(bank == 3) { phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DR_OFFSET; cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { writeR(0xffff9877, cru_phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("befor write reg val: 0x%x,index:%d\n", regval, index); if(0 == value) { regval &= ~(1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("LOW val set over reg val: 0x%x\n", regval); } else { regval |= (1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("HIGH val set over reg val: 0x%x\n", regval); } } else { printf("Pin mode failed!\n"); } break; case PI_MODEL_CM4: case PI_MODEL_3B: if(bank == 0){ dr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DR_L_OFFSET + ((index >> 4) << 2); cru_phyaddr = RK3566_PMU_CRU_BASE + RK3566_PMUCRU_PMUGATE_CON01_OFFSET; cru_val = ~((0x3 << 9) | (0x3 << (16 + 9))); } else{ dr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DR_L_OFFSET + ((index >> 4) << 2); cru_phyaddr = RK3566_CRU_BASE + RK3566_CRU_GATE_CON31_OFFSET; cru_val = ~((0xff << 2) | (0xff << (16 + 2))); } offset = index % 16; bit_enable = 0x1 << (16 + offset); /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(cru_phyaddr); regval &= cru_val; writeR(regval, cru_phyaddr); regval = readR(dr_phyaddr); if(wiringPiDebug) printf("read val(%#x) from register[%#x]\n", regval, dr_phyaddr);; regval |= bit_enable; if(0 == value) regval &= ~(1 << offset); else regval |= (1 << offset); writeR(regval, dr_phyaddr); if (wiringPiDebug) printf("write val(%#x) to register[%#x]\n", regval, dr_phyaddr); regval = readR(dr_phyaddr); if (wiringPiDebug) printf("set over reg val: 0x%x\n", regval); } else { printf("Pin mode failed!\n"); } break; default: if (bank == 11) { phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + 0x10; } else { phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + 0x10; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { regval = readR(phyaddr); if (wiringPiDebug) printf("befor write reg val: 0x%x,index:%d\n", regval, index); if(0 == value) { regval &= ~(1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("LOW val set over reg val: 0x%x\n", regval); } else { regval |= (1 << index); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("HIGH val set over reg val: 0x%x\n", regval); } } else { printf("Pin mode failed!\n"); } break; } return 0; } /* * OrangePi Digital Read */ int OrangePi_digitalRead(int pin) { int bank = pin >> 5; int index = pin - (bank << 5); int val; unsigned int phyaddr = 0; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: if(bank == 0) phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_EXT_PORT_OFFSET; else if(bank == 1) phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_EXT_PORT_OFFSET; else if(bank == 2) phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_EXT_PORT_OFFSET; else if(bank == 3) phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_EXT_PORT_OFFSET; else if(bank == 4) phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_EXT_PORT_OFFSET; break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: if(bank == 1) phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_EXT_PORTA_OFFSET; else if(bank == 2) phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_EXT_PORTA_OFFSET; else if(bank == 4) phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_EXT_PORTA_OFFSET; break; case PI_MODEL_R1_PLUS: if(bank == 2) phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_EXT_PORTA_OFFSET; else if(bank == 3) phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_EXT_PORTA_OFFSET; break; case PI_MODEL_CM4: case PI_MODEL_3B: if(bank == 0) phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_EXT_PORT_OFFSET; else phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_EXT_PORT_OFFSET; break; default: if (bank == 11) { phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + 0x10; } else { phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + 0x10; } break; } if (ORANGEPI_PIN_MASK[bank][index] != -1) { val = readR(phyaddr); val = val >> index; val &= 1; if (wiringPiDebug) printf("Read reg val: 0x%#x, bank:%d, index:%d\n", val, bank, index); return val; } return 0; } void OrangePi_set_gpio_pullUpDnControl (int pin, int pud) { unsigned int bank = pin >> 5; unsigned int index = pin - (bank << 5); unsigned int regval; unsigned int offset; unsigned int phyaddr = 0; unsigned int bit_enable; unsigned int bit_value = 0; switch (OrangePiModel) { case PI_MODEL_5: case PI_MODEL_5B: case PI_MODEL_5_PLUS: case PI_MODEL_900: if(bank == 0 && index < 12) phyaddr = RK3588_PMU1_IOC_BASE + RK3588_PMU1_IOC_GPIO0A_P + ((index >> 3) << 2); else if(bank == 0 && index > 11 && index < 31) phyaddr = RK3588_PMU2_IOC_BASE + RK3588_PMU2_IOC_GPIO0B_P + (((index - 8) >> 3) << 2); else if(bank == 1) phyaddr = RK3588_VCCIO1_4_IOC_BASE + RK3588_VCCIO1_4_IOC_GPIO1A_P + ((index >> 3) << 2); else if(bank < 4 || (bank == 4 && index > 17)) phyaddr = RK3588_VCCIO3_5_IOC_BASE + RK3588_VCCIO3_5_IOC_GPIO2A_P + (((pin - 64) >> 3) << 2); else if(bank == 4 && index < 18) phyaddr = RK3588_VCCIO6_IOC_BASE + RK3588_VCCIO6_IOC_GPIO4A_P + ((index >> 3) << 2); offset = (index % 8) << 1; bit_enable = 3 << ( 16 + offset); /* */if (PUD_UP == pud) bit_value = 3; else if (PUD_DOWN == pud) bit_value = 1; else if (PUD_OFF == pud) bit_value = 0; break; case PI_MODEL_800: case PI_MODEL_4_LTS: case PI_MODEL_4: case PI_MODEL_RK3399: /* */if ( bank > 1) phyaddr = RK3399_GRF_BASE + RK3399_GRF_GPIO2_3_4_P_OFFSET + (((pin - 64) >> 3) << 2); else if ( bank == 1 || pin < 16) phyaddr = RK3399_PMUGRF_BASE + RK3399_PMUGRF_GPIO0_1_P_OFFSET + (((pin - 0) >> 3) << 2); else { printf("gpio0 Group c,d does not support PU/PD control\n"); return ; } //offset = index - ((index >> 3) << 3); offset = (index % 8) << 1; bit_enable = 3 << ( 16 + offset); /* */if (PUD_UP == pud) { if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */ bit_value = 3; else bit_value = 1; } else if (PUD_DOWN == pud) { if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */ bit_value = 1; else bit_value = 2; } else if (PUD_OFF == pud) { bit_value = 0; } break; case PI_MODEL_CM4: case PI_MODEL_3B: if (bank == 0) phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_P_OFFSET + (((pin - 0) >> 3) << 2); else phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_P_OFFSET + (((pin - 32) >> 3) << 2); offset = (index % 8) << 1; bit_enable = 3 << ( 16 + offset); /* */if (PUD_UP == pud) bit_value = 1; else if (PUD_DOWN == pud) bit_value = 2; else if (PUD_OFF == pud) bit_value = 0; break; default: //int offset = ((index - ((index >> 4) << 4)) << 1); offset = ((index % 16) << 1); if (bank == 11) phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 4) << 2) + 0x1c; else phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 4) << 2) + 0x1c; bit_enable = 0; /* */if (PUD_UP == pud) bit_value = 1; else if (PUD_DOWN == pud) bit_value = 2; else if (PUD_OFF == pud) bit_value = 0; break; } /* Ignore unused gpio */ if (ORANGEPI_PIN_MASK[bank][index] != -1) { if (wiringPiDebug) printf("bank: %d, index: %d\n", bank, index); regval = readR(phyaddr); if (wiringPiDebug) printf("read val(%#x) from register[%#x]\n", regval, phyaddr); /* clear bit */ regval &= ~(3 << offset); /* bit write enable*/ regval |= bit_enable; /* set bit */ regval |= (bit_value & 3) << offset; if (wiringPiDebug) printf("write val(%#x) to register[%#x]\n", regval, phyaddr); writeR(regval, phyaddr); regval = readR(phyaddr); if (wiringPiDebug) printf("over reg val: %#x\n", regval); } }