4967 lines
153 KiB
C
Executable File
4967 lines
153 KiB
C
Executable File
/*
|
||
* 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为in,1为out
|
||
}
|
||
return mode + 1;//如果不是gpio模式,返回的alt,从2开始,0和1是in和out
|
||
}
|
||
break;
|
||
|
||
case PI_MODEL_5: case PI_MODEL_5B:
|
||
case PI_MODEL_5_PLUS:
|
||
case PI_MODEL_900:
|
||
|
||
rk3588_bus_ioc_phyaddr = RK3588_BUS_IOC_BASE + (0x20 * bank) + ((index >> 2) << 2);
|
||
if(bank == 0){
|
||
if (index < 12){
|
||
;/* Todo */
|
||
}else{
|
||
ddr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
}
|
||
else if(bank == 1){
|
||
ddr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
else if(bank == 2){
|
||
ddr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
else if(bank == 3){
|
||
ddr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
else if(bank == 4){
|
||
ddr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1) {
|
||
|
||
if ( bank == 0 && index < 12 )
|
||
;/*Todo*/
|
||
else
|
||
regval = readR(rk3588_bus_ioc_phyaddr);
|
||
|
||
mode = (regval >> ((index % 4) << 2)) & 0xf;//获取控制模式的那四位的值
|
||
if(mode == 0){ //如果是gpio模式
|
||
regval = readR(ddr_phyaddr); //获取gpio方向寄存器的值
|
||
return (regval >> (index % 16)) & 0x1; //index对应的gpio的方向值,0为in,1为out
|
||
}
|
||
|
||
return mode + 1; //如果不是gpio模式,返回的alt,从2开始,0和1是in和out
|
||
}
|
||
break;
|
||
|
||
case PI_MODEL_R1_PLUS:
|
||
|
||
offset = ((index - ((index >> 3) << 3)));
|
||
if(bank == 2)
|
||
{
|
||
//ddr_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET;
|
||
ddr_phyaddr = 0xff230004;
|
||
//grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10;
|
||
if(0 == (index >> 3))//gpio2_ax
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x20;
|
||
}
|
||
else if(3 == (index >> 3))//gpio2_dx
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x34;
|
||
}
|
||
}
|
||
else if(bank == 3)
|
||
{
|
||
//grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20;
|
||
ddr_phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET;
|
||
if (0 == (index >> 3))
|
||
{
|
||
if(4 == offset)//gpio3_a4
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x38;
|
||
}
|
||
else//gpio3_a567
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x3c;
|
||
}
|
||
}
|
||
else if(2 == (index >> 3)) //gpio3_c
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x48;
|
||
}
|
||
}
|
||
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(grf_phyaddr);
|
||
writeR(0xffff9877, 0xff440240);
|
||
|
||
if(3 == bank && (0 == (index >> 3))) //gpio3_ax需要写3位
|
||
{
|
||
mode = (regval >> ((offset % 5) * 3)) & 0x7;
|
||
}
|
||
else
|
||
{
|
||
mode = (regval >> (offset << 1)) & 0x3;
|
||
}
|
||
if(mode == 0){
|
||
regval = readR(ddr_phyaddr);
|
||
return (regval >> index) & 1;
|
||
}
|
||
return mode + 1;
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_CM4:
|
||
case PI_MODEL_3B:
|
||
|
||
if(bank == 0){
|
||
grf_phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET + ((pin >> 2) << 2);
|
||
ddr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2);
|
||
}
|
||
else{
|
||
grf_phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_IOMUX_L_OFFSET + (((pin - 32) >> 2) << 2);
|
||
ddr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2);
|
||
}
|
||
|
||
offset = (index % 4) << 2;
|
||
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1) {
|
||
regval = readR(grf_phyaddr);
|
||
mode = (regval >> offset) & 0x7;
|
||
|
||
if(mode == 0){ //如果是gpio模式
|
||
regval = readR(ddr_phyaddr);//获取gpio方向寄存器的值
|
||
return (regval >> (index % 16)) & 0x1;//index对应的gpio的方向值,0为in,1为out
|
||
}
|
||
return mode + 1;//如果不是gpio模式,返回的alt,从2开始,0和1是in和out
|
||
}
|
||
break;
|
||
|
||
default:
|
||
|
||
offset = ((index - ((index >> 3) << 3)) << 2);
|
||
|
||
if (bank == 11)
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 3) << 2);
|
||
else
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 3) << 2);
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(phyaddr);
|
||
mode = (regval >> offset) & 7;
|
||
}
|
||
|
||
return mode;
|
||
|
||
break;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
/*
|
||
* Set GPIO Mode
|
||
*/
|
||
int OrangePi_set_gpio_mode(int pin, int mode)
|
||
{
|
||
unsigned int regval = 0;
|
||
unsigned int bank = pin >> 5;
|
||
unsigned int index = pin - (bank << 5);
|
||
unsigned int phyaddr = 0;
|
||
int offset;
|
||
unsigned int cru_phyaddr =0, grf_phyaddr = 0, gpio_phyaddr = 0, ddr_phyaddr = 0;
|
||
unsigned int cru_val = 0;
|
||
unsigned int rk3588_pmu1_ioc_phyaddr;
|
||
unsigned int rk3588_bus_ioc_phyaddr;
|
||
unsigned int temp = 0;
|
||
unsigned int bit_enable;
|
||
unsigned int grf_val = 0;
|
||
|
||
switch (OrangePiModel)
|
||
{
|
||
case PI_MODEL_5: case PI_MODEL_5B:
|
||
case PI_MODEL_5_PLUS:
|
||
case PI_MODEL_900:
|
||
|
||
rk3588_bus_ioc_phyaddr = RK3588_BUS_IOC_BASE + (0x20 * bank) + ((index >> 2) << 2);
|
||
if(bank == 0){
|
||
if (index < 12){
|
||
;/* Todo */
|
||
}else{
|
||
ddr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
}
|
||
cru_phyaddr = RK3588_PMU1CRU_BASE + RK3588_PMU1CRU_GATE_CON5_OFFSET;
|
||
cru_val = 0xffff9fff;
|
||
}
|
||
else if(bank == 1){
|
||
ddr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON16_OFFSET;
|
||
cru_val = 0xffff3fff;
|
||
}
|
||
else if(bank == 2){
|
||
ddr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
else if(bank == 3){
|
||
ddr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
else if(bank == 4){
|
||
ddr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DDR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(cru_phyaddr);
|
||
regval &= cru_val;
|
||
writeR(regval, cru_phyaddr);
|
||
|
||
regval = readR(rk3588_bus_ioc_phyaddr);
|
||
regval |= 0xffff0000;
|
||
regval &= ~(0xf << ((index % 4) << 2));
|
||
writeR(regval, rk3588_bus_ioc_phyaddr);
|
||
regval = readR(rk3588_bus_ioc_phyaddr);
|
||
|
||
/* Set Input */
|
||
if(INPUT == mode)
|
||
{
|
||
regval = readR(ddr_phyaddr);
|
||
regval |= 0xffff0000;
|
||
regval &= ~(1 << (index % 16));
|
||
writeR(regval, ddr_phyaddr);
|
||
|
||
if (wiringPiDebug){
|
||
regval = readR(ddr_phyaddr);
|
||
printf("Input mode set over reg val: %#x\n",regval);
|
||
}
|
||
}
|
||
else if(OUTPUT == mode)
|
||
{
|
||
regval = readR(ddr_phyaddr);
|
||
regval |= 0xffff0000;
|
||
regval |= (1 << (index % 16));
|
||
writeR(regval, ddr_phyaddr);
|
||
|
||
if (wiringPiDebug){
|
||
regval = readR(ddr_phyaddr);
|
||
printf("Input mode set over reg val: %#x\n",regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Unknow mode\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_800: case PI_MODEL_4_LTS:
|
||
case PI_MODEL_4: case PI_MODEL_RK3399:
|
||
|
||
offset = ((index - ((index >> 3) << 3)));
|
||
|
||
if(bank == 1){
|
||
cru_phyaddr = RK3399_PMUCRU_BASE + RK3399_PMUCRU_CLKGATE_CON1_OFFSET;
|
||
grf_phyaddr = RK3399_PMUGRF_BASE + ((index >> 3) << 2) + 0x10;
|
||
gpio_phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET;
|
||
}
|
||
|
||
else if(bank == 2){
|
||
cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET;
|
||
grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2);
|
||
gpio_phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET;
|
||
}
|
||
else if(bank == 4){
|
||
cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET;
|
||
grf_phyaddr = RK3399_GRF_BASE + ((index >> 3) << 2) +0x20;
|
||
gpio_phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_SWPORTA_DDR_OFFSET;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
if (wiringPiDebug)
|
||
printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
|
||
|
||
/* Set Input */
|
||
if(INPUT == mode)
|
||
{
|
||
writeR(0xffff0180, cru_phyaddr);
|
||
regval = readR(grf_phyaddr);
|
||
regval |= 0x3 << ((offset << 1) | 0x10);
|
||
regval &= ~(0x3 << (offset << 1));
|
||
writeR(regval, grf_phyaddr);
|
||
regval = readR(gpio_phyaddr);
|
||
regval &= ~(1 << index);
|
||
writeR(regval, gpio_phyaddr);
|
||
|
||
if (wiringPiDebug){
|
||
regval = readR(gpio_phyaddr);
|
||
printf("Input mode set over reg val: %#x\n",regval);
|
||
}
|
||
}
|
||
else if(OUTPUT == mode)
|
||
{
|
||
/* Set Output */
|
||
writeR(0xffff0180, cru_phyaddr);
|
||
regval = readR(grf_phyaddr);
|
||
regval |= 0x3 << ((offset << 1) | 0x10);
|
||
regval &= ~(0x3 << (offset << 1));
|
||
writeR(regval, grf_phyaddr);
|
||
regval = readR(gpio_phyaddr);
|
||
regval |= 1 << index;
|
||
writeR(regval, gpio_phyaddr);
|
||
|
||
if (wiringPiDebug)
|
||
{
|
||
regval = readR(gpio_phyaddr);
|
||
printf("Out mode get value: 0x%x\n",regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Unknow mode\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_R1_PLUS:
|
||
|
||
offset = ((index - ((index >> 3) << 3)));
|
||
|
||
if(bank == 2)
|
||
{
|
||
cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET;
|
||
//grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10;
|
||
gpio_phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET;
|
||
if(0 == (index >> 3))//gpio2_ax
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x20;
|
||
}
|
||
else if(3 == (index >> 3))//gpio2_dx
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x34;
|
||
}
|
||
}
|
||
else if(bank == 3)
|
||
{
|
||
cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET;
|
||
//grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20;
|
||
gpio_phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DDR_OFFSET;
|
||
if (0 == (index >> 3))
|
||
{
|
||
if(4 == offset)//gpio3_a4
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x38;
|
||
}
|
||
else//gpio3_a567
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x3c;
|
||
}
|
||
}
|
||
else if(2 == (index >> 3)) //gpio3_c
|
||
{
|
||
grf_phyaddr = RK3328_GRF_BASE + 0x48;
|
||
}
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
if (wiringPiDebug)
|
||
printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
|
||
|
||
/* Set Input */
|
||
if(INPUT == mode)
|
||
{
|
||
writeR(0xffff9877, cru_phyaddr);
|
||
|
||
regval = readR(grf_phyaddr);
|
||
if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需要写3位
|
||
{
|
||
regval |= 0xffff0000;
|
||
regval &= ~(0x7 << ((offset % 5) * 3));
|
||
}
|
||
else //其他的写两位
|
||
{
|
||
regval |= 0xffff0000;
|
||
regval &= ~(0x3 << (offset << 1));
|
||
}
|
||
writeR(regval, grf_phyaddr);
|
||
|
||
regval = readR(gpio_phyaddr);
|
||
regval &= ~(1 << index);
|
||
writeR(regval, gpio_phyaddr);
|
||
if (wiringPiDebug)
|
||
{
|
||
regval = readR(gpio_phyaddr);
|
||
printf("Input mode set over reg val: %#x\n",regval);
|
||
}
|
||
}
|
||
else if(OUTPUT == mode)
|
||
{
|
||
/* Set Output */
|
||
writeR(0xffff9877, cru_phyaddr);
|
||
|
||
regval = readR(grf_phyaddr);
|
||
if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需要写3位
|
||
{
|
||
regval |= 0xffff0000;
|
||
regval &= ~(0x7 << ((offset % 5) * 3));
|
||
}
|
||
else //其他的写两位
|
||
{
|
||
regval |= 0xffff0000;
|
||
regval &= ~(0x3 << (offset << 1));
|
||
}
|
||
writeR(regval, grf_phyaddr);
|
||
|
||
regval = readR(gpio_phyaddr);
|
||
regval |= 1 << index;
|
||
writeR(regval, gpio_phyaddr);
|
||
if (wiringPiDebug)
|
||
{
|
||
regval = readR(gpio_phyaddr);
|
||
printf("Out mode get value: 0x%x\n",regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Unknow mode\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_CM4:
|
||
case PI_MODEL_3B:
|
||
if(bank == 0){
|
||
cru_phyaddr = RK3566_PMU_CRU_BASE + RK3566_PMUCRU_PMUGATE_CON01_OFFSET;
|
||
cru_val = ~((0x3 << 9) | (0x3 << (16 + 9)));
|
||
grf_phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_IOMUX_L_OFFSET + ((pin >> 2) << 2);
|
||
ddr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2);
|
||
}
|
||
else{
|
||
cru_phyaddr = RK3566_CRU_BASE + RK3566_CRU_GATE_CON31_OFFSET;
|
||
cru_val = ~((0xff << 2) | (0xff << (16 + 2)));
|
||
grf_phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_IOMUX_L_OFFSET + (((pin - 32) >> 2) << 2);
|
||
ddr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DDR_L_OFFSET + ((index >> 4) << 2);
|
||
}
|
||
|
||
offset = (index % 4) << 2;
|
||
bit_enable = 0x7 << (16 + offset);
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(cru_phyaddr);
|
||
regval &= cru_val;
|
||
writeR(regval, cru_phyaddr);
|
||
regval = readR(grf_phyaddr);
|
||
if(wiringPiDebug)
|
||
printf("read val(%#x) from register[%#x]\n", regval, grf_phyaddr);
|
||
regval |= bit_enable;
|
||
regval &= ~(0x7 << offset);
|
||
if (wiringPiDebug)
|
||
printf("write val(%#x) to register[%#x]\n", regval, grf_phyaddr);
|
||
writeR(regval, grf_phyaddr);
|
||
regval = readR(grf_phyaddr);
|
||
if(wiringPiDebug)
|
||
printf("set over reg val: 0x%x\n", regval);
|
||
|
||
regval = readR(ddr_phyaddr);
|
||
if(wiringPiDebug)
|
||
printf("read val ddr (%#x) from register[%#x]\n", regval, ddr_phyaddr);
|
||
|
||
regval |= 0x1 << (16 + (index % 16));
|
||
if(INPUT == mode)
|
||
regval &= ~(1 << (index % 16));
|
||
else
|
||
regval |= (1 << (index % 16));
|
||
|
||
writeR(regval, ddr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("write val(%#x) to register[%#x]\n", regval, ddr_phyaddr);
|
||
|
||
regval = readR(ddr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
break;
|
||
|
||
default:
|
||
|
||
offset = ((index - ((index >> 3) << 3)) << 2);
|
||
|
||
if (bank == 11)
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 3) << 2);
|
||
else
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 3) << 2);
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("Before read reg val: 0x%x offset:%d\n",regval,offset);
|
||
|
||
if (wiringPiDebug)
|
||
printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
|
||
|
||
/* Set Input */
|
||
if(INPUT == mode)
|
||
{
|
||
regval &= ~(7 << offset);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("Input mode set over reg val: %#x\n",regval);
|
||
}
|
||
else if(OUTPUT == mode)
|
||
{
|
||
/* Set Output */
|
||
regval &= ~(7 << offset);
|
||
regval |= (1 << offset);
|
||
if (wiringPiDebug)
|
||
printf("Out mode ready set val: 0x%x\n",regval);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("Out mode get value: 0x%x\n",regval);
|
||
}
|
||
else
|
||
{
|
||
printf("Unknow mode\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int OrangePi_set_gpio_alt(int pin, int mode)
|
||
{
|
||
unsigned int regval = 0;
|
||
unsigned int bank = pin >> 5;
|
||
unsigned int index = pin - (bank << 5);
|
||
unsigned int phyaddr = 0;
|
||
int offset = ((index - ((index >> 3) << 3)) << 2);
|
||
|
||
if (bank == 11)
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + ((index >> 3) << 2);
|
||
else
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + (bank * 36) + ((index >> 3) << 2);
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
if (wiringPiDebug)
|
||
printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index);
|
||
|
||
regval = readR(phyaddr);
|
||
regval &= ~(7 << offset);
|
||
regval |= (mode << offset);
|
||
writeR(regval, phyaddr);
|
||
}
|
||
else
|
||
{
|
||
printf("Pin alt mode failed!\n");
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* OrangePi Digital write
|
||
*/
|
||
int OrangePi_digitalWrite(int pin, int value)
|
||
{
|
||
unsigned int bank = pin >> 5;
|
||
unsigned int index = pin - (bank << 5);
|
||
unsigned int phyaddr = 0;
|
||
unsigned int regval = 0;
|
||
unsigned int cru_phyaddr =0, gpio_phyaddr = 0, dr_phyaddr = 0;
|
||
unsigned int cru_val = 0;
|
||
unsigned int temp = 0;
|
||
unsigned int bit_enable = 0;
|
||
unsigned int offset;
|
||
|
||
switch (OrangePiModel)
|
||
{
|
||
case PI_MODEL_5: case PI_MODEL_5B:
|
||
case PI_MODEL_5_PLUS:
|
||
case PI_MODEL_900:
|
||
|
||
if(bank == 0){
|
||
dr_phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_PMU1CRU_BASE + RK3588_PMU1CRU_GATE_CON5_OFFSET;
|
||
cru_val = 0xffff9fff;
|
||
}
|
||
else if(bank == 1){
|
||
dr_phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON16_OFFSET;
|
||
cru_val = 0xffff3fff;
|
||
}
|
||
else if(bank == 2){
|
||
dr_phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
else if(bank == 3){
|
||
dr_phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
else if(bank == 4){
|
||
dr_phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_SWPORT_DR_L_OFFSET + ((index / 16) << 2);
|
||
cru_phyaddr = RK3588_CRU_BASE + RK3588_CRU_GATE_CON17_OFFSET;
|
||
cru_val = 0xffffffc0;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(cru_phyaddr);
|
||
regval &= cru_val;
|
||
writeR(regval, cru_phyaddr);
|
||
|
||
if(0 == value)
|
||
{
|
||
regval = readR(dr_phyaddr);
|
||
regval |= 0xffff0000;
|
||
regval &= ~(1 << (index % 16));
|
||
writeR(regval, dr_phyaddr);
|
||
regval = readR(dr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("LOW val set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
regval = readR(dr_phyaddr);
|
||
regval |= 0xffff0000;
|
||
regval |= (1 << (index % 16));
|
||
writeR(regval, dr_phyaddr);
|
||
regval = readR(dr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("HIGH val set over reg val: 0x%x\n", regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_800: case PI_MODEL_4_LTS:
|
||
case PI_MODEL_4: case PI_MODEL_RK3399:
|
||
|
||
if(bank == 1)
|
||
{
|
||
phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET;
|
||
cru_phyaddr = RK3399_PMUCRU_BASE + RK3399_PMUCRU_CLKGATE_CON1_OFFSET;
|
||
}
|
||
else if(bank == 2)
|
||
{
|
||
phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET;
|
||
cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET;
|
||
}
|
||
else if(bank == 4)
|
||
{
|
||
phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_SWPORTA_DR_OFFSET;
|
||
cru_phyaddr = RK3399_CRU_BASE + RK3399_CRU_CLKGATE_CON31_OFFSET;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
|
||
writeR(0xffff0180, cru_phyaddr);
|
||
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("befor write reg val: 0x%x,index:%d\n", regval, index);
|
||
|
||
if(0 == value)
|
||
{
|
||
regval &= ~(1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("LOW val set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
regval |= (1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("HIGH val set over reg val: 0x%x\n", regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
case PI_MODEL_R1_PLUS:
|
||
|
||
if(bank == 2)
|
||
{
|
||
phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_SWPORTA_DR_OFFSET;
|
||
cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET;
|
||
}
|
||
else if(bank == 3)
|
||
{
|
||
phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_SWPORTA_DR_OFFSET;
|
||
cru_phyaddr = RK3328_CRU_BASE + RK3328_CRU_CLKGATE_CON16_OFFSET;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
writeR(0xffff9877, cru_phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("befor write reg val: 0x%x,index:%d\n", regval, index);
|
||
|
||
if(0 == value)
|
||
{
|
||
regval &= ~(1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("LOW val set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
regval |= (1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("HIGH val set over reg val: 0x%x\n", regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_CM4:
|
||
case PI_MODEL_3B:
|
||
|
||
if(bank == 0){
|
||
dr_phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_SWPORT_DR_L_OFFSET + ((index >> 4) << 2);
|
||
cru_phyaddr = RK3566_PMU_CRU_BASE + RK3566_PMUCRU_PMUGATE_CON01_OFFSET;
|
||
cru_val = ~((0x3 << 9) | (0x3 << (16 + 9)));
|
||
}
|
||
else{
|
||
dr_phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_SWPORT_DR_L_OFFSET + ((index >> 4) << 2);
|
||
cru_phyaddr = RK3566_CRU_BASE + RK3566_CRU_GATE_CON31_OFFSET;
|
||
cru_val = ~((0xff << 2) | (0xff << (16 + 2)));
|
||
}
|
||
|
||
offset = index % 16;
|
||
bit_enable = 0x1 << (16 + offset);
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(cru_phyaddr);
|
||
regval &= cru_val;
|
||
writeR(regval, cru_phyaddr);
|
||
|
||
regval = readR(dr_phyaddr);
|
||
|
||
if(wiringPiDebug)
|
||
printf("read val(%#x) from register[%#x]\n", regval, dr_phyaddr);;
|
||
|
||
regval |= bit_enable;
|
||
|
||
if(0 == value)
|
||
regval &= ~(1 << offset);
|
||
else
|
||
regval |= (1 << offset);
|
||
|
||
writeR(regval, dr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("write val(%#x) to register[%#x]\n", regval, dr_phyaddr);
|
||
|
||
regval = readR(dr_phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
if (bank == 11)
|
||
{
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + 0x10;
|
||
}
|
||
else
|
||
{
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + 0x10;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("befor write reg val: 0x%x,index:%d\n", regval, index);
|
||
|
||
if(0 == value)
|
||
{
|
||
regval &= ~(1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("LOW val set over reg val: 0x%x\n", regval);
|
||
}
|
||
else
|
||
{
|
||
regval |= (1 << index);
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("HIGH val set over reg val: 0x%x\n", regval);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("Pin mode failed!\n");
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* OrangePi Digital Read
|
||
*/
|
||
int OrangePi_digitalRead(int pin)
|
||
{
|
||
int bank = pin >> 5;
|
||
int index = pin - (bank << 5);
|
||
int val;
|
||
unsigned int phyaddr = 0;
|
||
|
||
switch (OrangePiModel)
|
||
{
|
||
case PI_MODEL_5: case PI_MODEL_5B:
|
||
case PI_MODEL_5_PLUS:
|
||
case PI_MODEL_900:
|
||
|
||
if(bank == 0)
|
||
phyaddr = RK3588_GPIO0_BASE + RK3588_GPIO_EXT_PORT_OFFSET;
|
||
else if(bank == 1)
|
||
phyaddr = RK3588_GPIO1_BASE + RK3588_GPIO_EXT_PORT_OFFSET;
|
||
else if(bank == 2)
|
||
phyaddr = RK3588_GPIO2_BASE + RK3588_GPIO_EXT_PORT_OFFSET;
|
||
else if(bank == 3)
|
||
phyaddr = RK3588_GPIO3_BASE + RK3588_GPIO_EXT_PORT_OFFSET;
|
||
else if(bank == 4)
|
||
phyaddr = RK3588_GPIO4_BASE + RK3588_GPIO_EXT_PORT_OFFSET;
|
||
|
||
break;
|
||
|
||
case PI_MODEL_800: case PI_MODEL_4_LTS:
|
||
case PI_MODEL_4: case PI_MODEL_RK3399:
|
||
|
||
if(bank == 1)
|
||
phyaddr = RK3399_GPIO1_BASE + RK3399_GPIO_EXT_PORTA_OFFSET;
|
||
else if(bank == 2)
|
||
phyaddr = RK3399_GPIO2_BASE + RK3399_GPIO_EXT_PORTA_OFFSET;
|
||
else if(bank == 4)
|
||
phyaddr = RK3399_GPIO4_BASE + RK3399_GPIO_EXT_PORTA_OFFSET;
|
||
|
||
break;
|
||
|
||
case PI_MODEL_R1_PLUS:
|
||
|
||
if(bank == 2)
|
||
phyaddr = RK3328_GPIO2_BASE + RK3328_GPIO_EXT_PORTA_OFFSET;
|
||
else if(bank == 3)
|
||
phyaddr = RK3328_GPIO3_BASE + RK3328_GPIO_EXT_PORTA_OFFSET;
|
||
|
||
break;
|
||
|
||
case PI_MODEL_CM4:
|
||
case PI_MODEL_3B:
|
||
|
||
if(bank == 0)
|
||
phyaddr = RK3566_GPIO0_BASE + RK3566_GPIO_EXT_PORT_OFFSET;
|
||
else
|
||
phyaddr = RK3566_GPIO1_BASE + ((bank - 1) << 16) + RK3566_GPIO_EXT_PORT_OFFSET;
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
if (bank == 11)
|
||
{
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + 0x10;
|
||
}
|
||
else
|
||
{
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + 0x10;
|
||
}
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
val = readR(phyaddr);
|
||
val = val >> index;
|
||
val &= 1;
|
||
if (wiringPiDebug)
|
||
printf("Read reg val: 0x%#x, bank:%d, index:%d\n", val, bank, index);
|
||
|
||
return val;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void OrangePi_set_gpio_pullUpDnControl (int pin, int pud)
|
||
{
|
||
unsigned int bank = pin >> 5;
|
||
unsigned int index = pin - (bank << 5);
|
||
unsigned int regval;
|
||
unsigned int offset;
|
||
unsigned int phyaddr = 0;
|
||
unsigned int bit_enable;
|
||
unsigned int bit_value = 0;
|
||
|
||
switch (OrangePiModel)
|
||
{
|
||
case PI_MODEL_5: case PI_MODEL_5B:
|
||
case PI_MODEL_5_PLUS:
|
||
case PI_MODEL_900:
|
||
|
||
if(bank == 0 && index < 12)
|
||
phyaddr = RK3588_PMU1_IOC_BASE + RK3588_PMU1_IOC_GPIO0A_P + ((index >> 3) << 2);
|
||
else if(bank == 0 && index > 11 && index < 31)
|
||
phyaddr = RK3588_PMU2_IOC_BASE + RK3588_PMU2_IOC_GPIO0B_P + (((index - 8) >> 3) << 2);
|
||
else if(bank == 1)
|
||
phyaddr = RK3588_VCCIO1_4_IOC_BASE + RK3588_VCCIO1_4_IOC_GPIO1A_P + ((index >> 3) << 2);
|
||
else if(bank < 4 || (bank == 4 && index > 17))
|
||
phyaddr = RK3588_VCCIO3_5_IOC_BASE + RK3588_VCCIO3_5_IOC_GPIO2A_P + (((pin - 64) >> 3) << 2);
|
||
else if(bank == 4 && index < 18)
|
||
phyaddr = RK3588_VCCIO6_IOC_BASE + RK3588_VCCIO6_IOC_GPIO4A_P + ((index >> 3) << 2);
|
||
|
||
offset = (index % 8) << 1;
|
||
bit_enable = 3 << ( 16 + offset);
|
||
|
||
/* */if (PUD_UP == pud)
|
||
bit_value = 3;
|
||
else if (PUD_DOWN == pud)
|
||
bit_value = 1;
|
||
else if (PUD_OFF == pud)
|
||
bit_value = 0;
|
||
|
||
break;
|
||
|
||
case PI_MODEL_800: case PI_MODEL_4_LTS:
|
||
case PI_MODEL_4: case PI_MODEL_RK3399:
|
||
|
||
/* */if ( bank > 1)
|
||
phyaddr = RK3399_GRF_BASE + RK3399_GRF_GPIO2_3_4_P_OFFSET + (((pin - 64) >> 3) << 2);
|
||
else if ( bank == 1 || pin < 16)
|
||
phyaddr = RK3399_PMUGRF_BASE + RK3399_PMUGRF_GPIO0_1_P_OFFSET + (((pin - 0) >> 3) << 2);
|
||
else {
|
||
printf("gpio0 Group c,d does not support PU/PD control\n");
|
||
return ;
|
||
}
|
||
|
||
//offset = index - ((index >> 3) << 3);
|
||
offset = (index % 8) << 1;
|
||
bit_enable = 3 << ( 16 + offset);
|
||
|
||
/* */if (PUD_UP == pud) {
|
||
if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */
|
||
bit_value = 3;
|
||
else
|
||
bit_value = 1;
|
||
}
|
||
else if (PUD_DOWN == pud) {
|
||
if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */
|
||
bit_value = 1;
|
||
else
|
||
bit_value = 2;
|
||
}
|
||
else if (PUD_OFF == pud) {
|
||
bit_value = 0;
|
||
}
|
||
|
||
break;
|
||
|
||
case PI_MODEL_CM4:
|
||
case PI_MODEL_3B:
|
||
|
||
if (bank == 0)
|
||
phyaddr = RK3566_PMU_GRF_BASE + RK3566_PMU_GRF_GPIO0A_P_OFFSET + (((pin - 0) >> 3) << 2);
|
||
else
|
||
phyaddr = RK3566_SYS_GRF_BASE + RK3566_GRF_GPIO1A_P_OFFSET + (((pin - 32) >> 3) << 2);
|
||
|
||
offset = (index % 8) << 1;
|
||
bit_enable = 3 << ( 16 + offset);
|
||
|
||
/* */if (PUD_UP == pud)
|
||
bit_value = 1;
|
||
else if (PUD_DOWN == pud)
|
||
bit_value = 2;
|
||
else if (PUD_OFF == pud)
|
||
bit_value = 0;
|
||
break;
|
||
|
||
default:
|
||
//int offset = ((index - ((index >> 4) << 4)) << 1);
|
||
offset = ((index % 16) << 1);
|
||
|
||
if (bank == 11)
|
||
phyaddr = sunxi_gpio_info_t.r_gpio_base_addr + sunxi_gpio_info_t.r_gpio_base_offset + ((index >> 4) << 2) + 0x1c;
|
||
else
|
||
phyaddr = sunxi_gpio_info_t.gpio_base_addr + sunxi_gpio_info_t.gpio_base_offset + (bank * 36) + ((index >> 4) << 2) + 0x1c;
|
||
|
||
bit_enable = 0;
|
||
|
||
/* */if (PUD_UP == pud)
|
||
bit_value = 1;
|
||
else if (PUD_DOWN == pud)
|
||
bit_value = 2;
|
||
else if (PUD_OFF == pud)
|
||
bit_value = 0;
|
||
|
||
break;
|
||
}
|
||
|
||
/* Ignore unused gpio */
|
||
if (ORANGEPI_PIN_MASK[bank][index] != -1)
|
||
{
|
||
if (wiringPiDebug)
|
||
printf("bank: %d, index: %d\n", bank, index);
|
||
|
||
regval = readR(phyaddr);
|
||
if (wiringPiDebug)
|
||
printf("read val(%#x) from register[%#x]\n", regval, phyaddr);
|
||
|
||
/* clear bit */
|
||
regval &= ~(3 << offset);
|
||
|
||
/* bit write enable*/
|
||
regval |= bit_enable;
|
||
|
||
/* set bit */
|
||
regval |= (bit_value & 3) << offset;
|
||
|
||
if (wiringPiDebug)
|
||
printf("write val(%#x) to register[%#x]\n", regval, phyaddr);
|
||
|
||
writeR(regval, phyaddr);
|
||
regval = readR(phyaddr);
|
||
|
||
if (wiringPiDebug)
|
||
printf("over reg val: %#x\n", regval);
|
||
}
|
||
}
|