wiringOP-Python/wiringOP/wiringPi/wiringPi.c

4967 lines
153 KiB
C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* wiringPi:
* Arduino look-a-like Wiring library for the Raspberry Pi
* Copyright (c) 2012-2017 Gordon Henderson
* Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com>
*
* 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 <http://www.gnu.org/licenses/>.
***********************************************************************
*/
// 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 <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <poll.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>
#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, <chris@kchall.plus.com>
* 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为in1为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为in1为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为in1为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);
}
}