ODROID-C4: New support for ODROID-C4
Signed-off-by: Yang Deokgyu <secugyu@gmail.com> Signed-off-by: Luke Go <sangch.go@gmail.com> Change-Id: I0fd2de97d95bb8bf71cc1975081177571b1e8301
This commit is contained in:
committed by
Deokgyu Yang
parent
8c26c89486
commit
ffeba7f622
@@ -24,6 +24,7 @@ cc_library_shared {
|
|||||||
"wiringPi/wiringPi.c",
|
"wiringPi/wiringPi.c",
|
||||||
"wiringPi/mcp23017.c",
|
"wiringPi/mcp23017.c",
|
||||||
"wiringPi/odroidc2.c",
|
"wiringPi/odroidc2.c",
|
||||||
|
"wiringPi/odroidc4.c",
|
||||||
"wiringPi/drcSerial.c",
|
"wiringPi/drcSerial.c",
|
||||||
"wiringPi/mcp23s08.c",
|
"wiringPi/mcp23s08.c",
|
||||||
"wiringPi/odroidn1.c",
|
"wiringPi/odroidn1.c",
|
||||||
|
|||||||
2
build
2
build
@@ -64,7 +64,7 @@ configure_gpiomem() {
|
|||||||
*c|*c1|*c2)
|
*c|*c1|*c2)
|
||||||
$sudo cp -f udev/rules.d/99-odroid-wiringpi-meson.rules /etc/udev/rules.d/
|
$sudo cp -f udev/rules.d/99-odroid-wiringpi-meson.rules /etc/udev/rules.d/
|
||||||
;;
|
;;
|
||||||
*n2)
|
*n2|*c4)
|
||||||
$sudo cp -f udev/rules.d/99-odroid-wiringpi-aml.rules /etc/udev/rules.d/
|
$sudo cp -f udev/rules.d/99-odroid-wiringpi-aml.rules /etc/udev/rules.d/
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
2
debian/odroid-wiringpi.postinst
vendored
2
debian/odroid-wiringpi.postinst
vendored
@@ -20,7 +20,7 @@ case "$1" in
|
|||||||
*c|*c1|*c2)
|
*c|*c1|*c2)
|
||||||
cp -f /tmp/odroid-wiringpi/rules.d/99-odroid-wiringpi-meson.rules /etc/udev/rules.d/
|
cp -f /tmp/odroid-wiringpi/rules.d/99-odroid-wiringpi-meson.rules /etc/udev/rules.d/
|
||||||
;;
|
;;
|
||||||
*n2)
|
*n2|*c4)
|
||||||
cp -f /tmp/odroid-wiringpi/rules.d/99-odroid-wiringpi-aml.rules /etc/udev/rules.d/
|
cp -f /tmp/odroid-wiringpi/rules.d/99-odroid-wiringpi-aml.rules /etc/udev/rules.d/
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -481,6 +481,68 @@ static const char *physNamesOdroidN2 [64] =
|
|||||||
NULL,NULL,NULL,
|
NULL,NULL,NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static const char *physNamesOdroidC4All [64] =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
" 3.3V", "5V ",
|
||||||
|
" SDA.2", "5V ",
|
||||||
|
" SCL.2", "GND(0V) ",
|
||||||
|
"GPIO.481", "TxD1 ",
|
||||||
|
" GND(0V)", "RxD1 ",
|
||||||
|
"GPIO.479", "GPIO.492",
|
||||||
|
"GPIO.480", "GND(0V) ",
|
||||||
|
"GPIO.483", "GPIO.476",
|
||||||
|
" 3.3V", "GPIO.477",
|
||||||
|
" MOSI", "GND(0V) ",
|
||||||
|
" MISO", "GPIO.478",
|
||||||
|
" SLCK", "SS ",
|
||||||
|
" GND(0V)", "GPIO. 23",
|
||||||
|
" SDA.3", "SCL.3 ",
|
||||||
|
"GPIO.490", "GND(0V) ",
|
||||||
|
"GPIO.491", "GPIO. 24",
|
||||||
|
"GPIO.482", "GND(0V) ",
|
||||||
|
"GPIO.495", "GPIO. 22",
|
||||||
|
" AIN.2", "1V8 ",
|
||||||
|
" GND(0V)", "AIN.0 ",
|
||||||
|
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static const char *physNamesOdroidC4 [64] =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
" 3.3V", "5V ",
|
||||||
|
" SDA.2", "5V ",
|
||||||
|
" SCL.2", "0V ",
|
||||||
|
" IO.481", "TxD1 ",
|
||||||
|
" 0V", "RxD1 ",
|
||||||
|
" IO.479", "IO.492 ",
|
||||||
|
" IO.480", "0V ",
|
||||||
|
" IO.483", "IO.476 ",
|
||||||
|
" 3.3V", "IO.477 ",
|
||||||
|
" MOSI", "0V ",
|
||||||
|
" MISO", "IO.478 ",
|
||||||
|
" SLCK", "SS ",
|
||||||
|
" 0V", "IO. 23 ",
|
||||||
|
" SDA.3", "SCL.3 ",
|
||||||
|
" IO.490", "0V ",
|
||||||
|
" IO.491", "IO. 24 ",
|
||||||
|
" IO.482", "0V ",
|
||||||
|
" IO.495", "IO. 22 ",
|
||||||
|
" AIN.2", "1V8 ",
|
||||||
|
" 0V", "AIN.0 ",
|
||||||
|
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
NULL,NULL,NULL,
|
||||||
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
static void readallPhys(int model, int UNU rev, int physPin, const char *physNames[], int isAll) {
|
static void readallPhys(int model, int UNU rev, int physPin, const char *physNames[], int isAll) {
|
||||||
int pin ;
|
int pin ;
|
||||||
@@ -533,6 +595,7 @@ static void readallPhys(int model, int UNU rev, int physPin, const char *physNam
|
|||||||
break;
|
break;
|
||||||
case MODEL_ODROID_XU3:
|
case MODEL_ODROID_XU3:
|
||||||
case MODEL_ODROID_N2:
|
case MODEL_ODROID_N2:
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
printf (" | %2d | %5s", getPadDrive(pin), pupd[getPUPD(pin)]);
|
printf (" | %2d | %5s", getPadDrive(pin), pupd[getPUPD(pin)]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -573,6 +636,7 @@ static void readallPhys(int model, int UNU rev, int physPin, const char *physNam
|
|||||||
break;
|
break;
|
||||||
case MODEL_ODROID_XU3:
|
case MODEL_ODROID_XU3:
|
||||||
case MODEL_ODROID_N2:
|
case MODEL_ODROID_N2:
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
printf (" | %-5s | %-2d", pupd[getPUPD(pin)], getPadDrive(pin));
|
printf (" | %-5s | %-2d", pupd[getPUPD(pin)], getPadDrive(pin));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -696,6 +760,10 @@ void doReadall(int argc, char *argv[]) {
|
|||||||
headerName = (isAll == FALSE) ? "--- N2 ---" : "---- Model ODROID-N2 ----";
|
headerName = (isAll == FALSE) ? "--- N2 ---" : "---- Model ODROID-N2 ----";
|
||||||
physNames = (char *) ((isAll == FALSE) ? physNamesOdroidN2 : physNamesOdroidN2All);
|
physNames = (char *) ((isAll == FALSE) ? physNamesOdroidN2 : physNamesOdroidN2All);
|
||||||
break;
|
break;
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
|
headerName = (isAll == FALSE) ? "--- C4 ---" : "---- Model ODROID-C4 ----";
|
||||||
|
physNames = (char *) ((isAll == FALSE) ? physNamesOdroidC4 : physNamesOdroidC4All);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Oops - unknown model: %d\n", model);
|
printf("Oops - unknown model: %d\n", model);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ SRC = pins.tex \
|
|||||||
odroid_c1.tex \
|
odroid_c1.tex \
|
||||||
odroid_c2.tex \
|
odroid_c2.tex \
|
||||||
odroid_n1.tex \
|
odroid_n1.tex \
|
||||||
odroid_n2.tex
|
odroid_n2.tex \
|
||||||
|
odroid_c4.tex
|
||||||
|
|
||||||
DVI = $(SRC:.tex=.dvi)
|
DVI = $(SRC:.tex=.dvi)
|
||||||
|
|
||||||
|
|||||||
BIN
pins/odroid_c4.pdf
Normal file
BIN
pins/odroid_c4.pdf
Normal file
Binary file not shown.
99
pins/odroid_c4.tex
Normal file
99
pins/odroid_c4.tex
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
\documentclass[11pt,a4paper]{article}
|
||||||
|
\parskip 1ex
|
||||||
|
\parindent 0em
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\pagestyle{plain}
|
||||||
|
\pagenumbering{arabic}
|
||||||
|
\setlength{\topmargin}{0pt}
|
||||||
|
\setlength{\headheight}{0pt}
|
||||||
|
\setlength{\headsep}{0pt}
|
||||||
|
\setlength{\topskip}{0pt}
|
||||||
|
\setlength{\textheight}{240mm}
|
||||||
|
\setlength{\footskip}{5ex}
|
||||||
|
\setlength{\oddsidemargin}{0pt}
|
||||||
|
\setlength{\evensidemargin}{0pt}
|
||||||
|
\setlength{\textwidth}{160mm}
|
||||||
|
\usepackage[dvips]{graphics,color}
|
||||||
|
\usepackage{helvet}
|
||||||
|
\renewcommand{\familydefault}{\sfdefault}
|
||||||
|
\begin{document}
|
||||||
|
\begin{sffamily}
|
||||||
|
\definecolor{rtb-black}{rgb} {0.0, 0.0, 0.0}
|
||||||
|
\definecolor{rtb-navy}{rgb} {0.0, 0.0, 0.5}
|
||||||
|
\definecolor{rtb-green}{rgb} {0.0, 0.5, 0.0}
|
||||||
|
\definecolor{rtb-teal}{rgb} {0.0, 0.5, 0.5}
|
||||||
|
\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0}
|
||||||
|
\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5}
|
||||||
|
\definecolor{rtb-olive}{rgb} {0.5, 0.5, 0.0}
|
||||||
|
\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7}
|
||||||
|
\definecolor{rtb-grey}{rgb} {0.5, 0.5, 0.5}
|
||||||
|
\definecolor{rtb-blue}{rgb} {0.0, 0.0, 1.0}
|
||||||
|
\definecolor{rtb-lime}{rgb} {0.0, 1.0, 0.0}
|
||||||
|
\definecolor{rtb-aqua}{rgb} {0.0, 1.0, 1.0}
|
||||||
|
\definecolor{rtb-red}{rgb} {1.0, 0.0, 0.0}
|
||||||
|
\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0}
|
||||||
|
\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0}
|
||||||
|
\definecolor{rtb-white}{rgb} {1.0, 1.0, 1.0}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\bfseries{WiringPi: GPIO Pin Numbering Tables}\\
|
||||||
|
\tt{https://wiki.odroid.com/odroid-c4/hardware/}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|}
|
||||||
|
\hline
|
||||||
|
\multicolumn{8}{|c|}{\bfseries{ODROID-C4: 40 Pin GPIO connector(J2)}}\\
|
||||||
|
\hline
|
||||||
|
\hline
|
||||||
|
WiringPi Pin & Native GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & Native GPIO & WiringPi Pin\\
|
||||||
|
\hline
|
||||||
|
\hline
|
||||||
|
& & \textcolor{rtb-red}{3.3v} & \raggedleft{1} & 2 & \textcolor{rtb-maroon}{5v} & & \\
|
||||||
|
\hline
|
||||||
|
8 & 493 (GPIOX.17) & \textcolor{rtb-aqua}{SDA1} & \raggedleft{3} & 4 & \textcolor{rtb-maroon}{5v} & & \\
|
||||||
|
\hline
|
||||||
|
9 & 494 (GPIOX.18) & \textcolor{rtb-aqua}{SCL1} & \raggedleft{5} & 6 & \textcolor{rtb-black}{0v} & & \\
|
||||||
|
\hline
|
||||||
|
7 & 481 (GPIOX.5) & \textcolor{rtb-green}{GPIO7} & \raggedleft{7} & 8 & \textcolor{rtb-yellow}{TxD} & 488 (GPIOX.12) & 15\\
|
||||||
|
\hline
|
||||||
|
& & \textcolor{rtb-black}{0v} & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD} & 489 (GPIOX.13) & 16\\
|
||||||
|
\hline
|
||||||
|
0 & 479 (GPIOX.3) & \textcolor{rtb-green}{GPIO0} & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1} & 492 (GPIOX.16) & 1\\
|
||||||
|
\hline
|
||||||
|
2 & 480 (GPIOX.4) & \textcolor{rtb-green}{GPIO2} & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v} & & \\
|
||||||
|
\hline
|
||||||
|
3 & 483 (GPIOX.7) & \textcolor{rtb-green}{GPIO3} & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4} & 476 (GPIOX.0) & 4\\
|
||||||
|
\hline
|
||||||
|
& & \textcolor{rtb-red}{3.3v} & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5} & 477 (GPIOX.1) & 5\\
|
||||||
|
\hline
|
||||||
|
12 & 484 (GPIOX.8) & \textcolor{rtb-green}{GPIO12} & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v} & & \\
|
||||||
|
\hline
|
||||||
|
13 & 485 (GPIOX.9) & \textcolor{rtb-green}{GPIO13} & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6} & 478 (GPIOX.2) & 6\\
|
||||||
|
\hline
|
||||||
|
14 & 487 (GPIOX.11) & \textcolor{rtb-green}{GPIO14} & \raggedleft{23} & 24 & \textcolor{rtb-green}{GPIO10} & 486 (GPIOX.10) & 10\\
|
||||||
|
\hline
|
||||||
|
& & \textcolor{rtb-black}{0v} & \raggedleft{25} & 26 & \textcolor{rtb-green}{GPIO11} & 23 (GPIOH.6) & 11\\
|
||||||
|
\hline
|
||||||
|
30 & 474 (GPIOA.14) & \textcolor{rtb-aqua}{SDA2} & \raggedleft{27} & 28 & \textcolor{rtb-aqua}{SCL2} & 475 (GPIOA.15) & 31\\
|
||||||
|
\hline
|
||||||
|
21 & 490 (GPIOX.14) & \textcolor{rtb-green}{GPIO21} & \raggedleft{29} & 30 & \textcolor{rtb-black}{0v} & & \\
|
||||||
|
\hline
|
||||||
|
22 & 491 (GPIOX.15) & \textcolor{rtb-green}{GPIO22} & \raggedleft{31} & 32 & \textcolor{rtb-green}{GPIO26} & 24 (GPIOH.7) & 26\\
|
||||||
|
\hline
|
||||||
|
23 & 482 (GPIOX.6) & \textcolor{rtb-green}{GPIO23} & \raggedleft{33} & 34 & \textcolor{rtb-black}{0v} & & \\
|
||||||
|
\hline
|
||||||
|
24 & 495 (GPIOX.19) & \textcolor{rtb-green}{GPIO24} & \raggedleft{35} & 36 & \textcolor{rtb-green}{GPIO27} & 22 (GPIOH.5) & 27\\
|
||||||
|
\hline
|
||||||
|
25 & ADC.AIN1 & \textcolor{rtb-green}{GPIO25} & \raggedleft{37} & 38 & \textcolor{rtb-green}{GPIO28} & 1.8V Ref Out & 28\\
|
||||||
|
\hline
|
||||||
|
& & \textcolor{rtb-black}{0v} & \raggedleft{39} & 40 & \textcolor{rtb-green}{GPIO29} & ADC.AIN0 & 29\\
|
||||||
|
\hline
|
||||||
|
\hline
|
||||||
|
WiringPi Pin & Native GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & Native GPIO & WiringPi Pin\\
|
||||||
|
\hline
|
||||||
|
\end{tabular}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\end{sffamily}
|
||||||
|
\end{document}
|
||||||
@@ -68,7 +68,8 @@ SRC = wiringPi.c \
|
|||||||
odroidc2.c \
|
odroidc2.c \
|
||||||
odroidxu3.c \
|
odroidxu3.c \
|
||||||
odroidn1.c \
|
odroidn1.c \
|
||||||
odroidn2.c
|
odroidn2.c \
|
||||||
|
odroidc4.c
|
||||||
|
|
||||||
HEADERS = $(shell ls *.h)
|
HEADERS = $(shell ls *.h)
|
||||||
|
|
||||||
@@ -155,6 +156,7 @@ odroidc2.o : wiringPi.h odroidc2.h
|
|||||||
odroidxu3.o : wiringPi.h odroidxu3.h
|
odroidxu3.o : wiringPi.h odroidxu3.h
|
||||||
odroidn1.o : wiringPi.h odroidn1.h
|
odroidn1.o : wiringPi.h odroidn1.h
|
||||||
odroidn2.o : wiringPi.h odroidn2.h
|
odroidn2.o : wiringPi.h odroidn2.h
|
||||||
|
odroidc4.o : wiringPi.h odroidc4.h
|
||||||
|
|
||||||
wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h
|
wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h
|
||||||
wiringSerial.o: wiringSerial.h
|
wiringSerial.o: wiringSerial.h
|
||||||
|
|||||||
704
wiringPi/odroidc4.c
Normal file
704
wiringPi/odroidc4.c
Normal file
@@ -0,0 +1,704 @@
|
|||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// WiringPi ODROID-C4 Board Control file (AMLogic 64Bits Platform)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <asm/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#include "softPwm.h"
|
||||||
|
#include "softTone.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#include "wiringPi.h"
|
||||||
|
#include "odroidc4.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// wiringPi gpio map define
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static const int pinToGpio[64] = {
|
||||||
|
// wiringPi number to native gpio number
|
||||||
|
479, 492, // 0 | 1 : GPIOX.3, GPIOX.16
|
||||||
|
480, 483, // 2 | 3 : GPIOX.4, GPIOX.7
|
||||||
|
476, 477, // 4 | 5 : GPIOX.0, GPIOX.1
|
||||||
|
478, 481, // 6 | 7 : GPIOX.2, GPIOX.5
|
||||||
|
493, 494, // 8 | 9 : GPIOX.17(I2C-2_SDA), GPIOX.18(I2C-2_SCL)
|
||||||
|
486, 23, // 10 | 11 : GPIOX.10(SPI_SS), GPIOH.6
|
||||||
|
484, 485, // 12 | 13 : GPIOX.8(SPI_MOSI), GPIOX.9(SPI_MISO)
|
||||||
|
487, 488, // 14 | 15 : GPIOX.11(SPI_CLK), GPIOX.12(UART_TX_B)
|
||||||
|
489, -1, // 16 | 17 : GPIOX.13(UART_RX_B),
|
||||||
|
-1, - 1, // 18 | 19 :
|
||||||
|
-1, 490, // 20 | 21 : , GPIOX.14
|
||||||
|
491, 482, // 22 | 23 : GPIOX.15, GPIOX.6
|
||||||
|
495, -1, // 24 | 25 : GPIOX.19, ADC.AIN3
|
||||||
|
24, 22, // 26 | 27 : GPIOH.7, GPIOH.5
|
||||||
|
-1, - 1, // 28 | 29 : REF1.8V OUT, ADC.AIC4
|
||||||
|
474, 475, // 30 | 31 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
||||||
|
// Padding:
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32...47
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 48...63
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int phyToGpio[64] = {
|
||||||
|
// physical header pin number to native gpio number
|
||||||
|
-1, // 0
|
||||||
|
-1, -1, // 1 | 2 : 3.3V, 5.0V
|
||||||
|
493, -1, // 3 | 4 : GPIOX.17(I2C-2_SDA), 5.0V
|
||||||
|
494, -1, // 5 | 6 : GPIOX.18(I2C-2_SCL), GND
|
||||||
|
481, 488, // 7 | 8 : GPIOX.5, GPIOX.12(UART_TX_B)
|
||||||
|
-1, 489, // 9 | 10 : GND, GPIOX.13(UART_RX_B)
|
||||||
|
479, 492, // 11 | 12 : GPIOX.3, GPIOX.16
|
||||||
|
480, -1, // 13 | 14 : GPIOX.4, GND
|
||||||
|
483, 476, // 15 | 16 : GPIOX.7, GPIOX.0
|
||||||
|
-1, 477, // 17 | 18 : 3.3V, GPIOX.1
|
||||||
|
484, -1, // 19 | 20 : GPIOX.8(SPI_MOSI), GND
|
||||||
|
485, 478, // 21 | 22 : GPIOX.9(SPI_MISO), GPIOX.2
|
||||||
|
487, 486, // 23 | 24 : GPIOX.11(SPI_CLK), GPIOX.10(SPI_SS)
|
||||||
|
-1, 23, // 25 | 26 : GND, GPIOH.6
|
||||||
|
474, 475, // 27 | 28 : GPIOA.14(I2C-3_SDA), GPIOA.15(I2C-3_SCL)
|
||||||
|
490, -1, // 29 | 30 : GPIOX.14, GND
|
||||||
|
491, 24, // 31 | 32 : GPIOX.15, GPIOH.7
|
||||||
|
482, -1, // 33 | 34 : GPIOX.6, GND
|
||||||
|
495, 22, // 35 | 36 : GPIOX.19, GPIOH.5
|
||||||
|
-1, -1, // 37 | 38 : ADC.AIN3, 1.8V REF OUT
|
||||||
|
-1, -1, // 39 | 40 : GND, ADC.AIC4
|
||||||
|
// Not used
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, // 41...48
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, // 49...56
|
||||||
|
-1, -1, -1, -1, -1, -1, -1 // 57...63
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// Global variable define
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// wiringPi Pinmap control arrary
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/* ADC file descriptor */
|
||||||
|
static int adcFds[2];
|
||||||
|
|
||||||
|
/* GPIO mmap control */
|
||||||
|
static volatile uint32_t *gpio;
|
||||||
|
|
||||||
|
/* wiringPi Global library */
|
||||||
|
static struct libodroid *lib = NULL;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// Function prototype define
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToGPSETReg (int pin);
|
||||||
|
static int gpioToGPLEVReg (int pin);
|
||||||
|
static int gpioToPUENReg (int pin);
|
||||||
|
static int gpioToPUPDReg (int pin);
|
||||||
|
static int gpioToShiftReg (int pin);
|
||||||
|
static int gpioToGPFSELReg (int pin);
|
||||||
|
static int gpioToDSReg (int pin);
|
||||||
|
static int gpioToMuxReg (int pin);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// wiringPi core function
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _getModeToGpio (int mode, int pin);
|
||||||
|
static int _setPadDrive (int pin, int value);
|
||||||
|
static int _getPadDrive (int pin);
|
||||||
|
static int _pinMode (int pin, int mode);
|
||||||
|
static int _getAlt (int pin);
|
||||||
|
static int _getPUPD (int pin);
|
||||||
|
static int _pullUpDnControl (int pin, int pud);
|
||||||
|
static int _digitalRead (int pin);
|
||||||
|
static int _digitalWrite (int pin, int value);
|
||||||
|
static int _analogRead (int pin);
|
||||||
|
static int _digitalWriteByte (const unsigned int value);
|
||||||
|
static unsigned int _digitalReadByte (void);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
// board init function
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void init_gpio_mmap (void);
|
||||||
|
static void init_adc_fds (void);
|
||||||
|
|
||||||
|
void init_odroidc4 (struct libodroid *libwiring);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Set regsiter
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToGPSETReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_OUTP_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_OUTP_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_OUTP_REG_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------r-*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Input regsiter
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToGPLEVReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_INP_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_INP_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_INP_REG_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Pull up/down enable regsiter
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToPUENReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_PUEN_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_PUEN_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_PUEN_REG_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Pull up/down regsiter
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToPUPDReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_PUPD_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_PUPD_REG_OFFSET;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_PUPD_REG_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO bit
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToShiftReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return pin - C4_GPIOH_PIN_START;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return pin - C4_GPIOA_PIN_START;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return pin - C4_GPIOX_PIN_START;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Function register
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToGPFSELReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_FSEL_REG_OFFSET;
|
||||||
|
if(pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_FSEL_REG_OFFSET;
|
||||||
|
if(pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_FSEL_REG_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Drive Strength register
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToDSReg (int pin)
|
||||||
|
{
|
||||||
|
if (pin >= C4_GPIOH_PIN_START && pin <= C4_GPIOH_PIN_END)
|
||||||
|
return C4_GPIOH_DS_REG_3A_OFFSET;
|
||||||
|
if (pin >= C4_GPIOA_PIN_START && pin <= C4_GPIOA_PIN_END)
|
||||||
|
return C4_GPIOA_DS_REG_5A_OFFSET;
|
||||||
|
if (pin >= C4_GPIOX_PIN_START && pin <= C4_GPIOX_PIN_MID)
|
||||||
|
return C4_GPIOX_DS_REG_2A_OFFSET;
|
||||||
|
if (pin > C4_GPIOX_PIN_MID && pin <= C4_GPIOX_PIN_END)
|
||||||
|
return C4_GPIOX_DS_REG_2B_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
//
|
||||||
|
// offset to the GPIO Pin Mux register
|
||||||
|
//
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int gpioToMuxReg (int pin)
|
||||||
|
{
|
||||||
|
switch (pin) {
|
||||||
|
case C4_GPIOH_PIN_START ...C4_GPIOH_PIN_END:
|
||||||
|
return C4_GPIOH_MUX_B_REG_OFFSET;
|
||||||
|
case C4_GPIOA_PIN_START ...C4_GPIOA_PIN_START + 7:
|
||||||
|
return C4_GPIOA_MUX_D_REG_OFFSET;
|
||||||
|
case C4_GPIOA_PIN_START + 8 ...C4_GPIOA_PIN_END:
|
||||||
|
return C4_GPIOA_MUX_E_REG_OFFSET;
|
||||||
|
case C4_GPIOX_PIN_START ...C4_GPIOX_PIN_START + 7:
|
||||||
|
return C4_GPIOX_MUX_3_REG_OFFSET;
|
||||||
|
case C4_GPIOX_PIN_START + 8 ...C4_GPIOX_PIN_START + 15:
|
||||||
|
return C4_GPIOX_MUX_4_REG_OFFSET;
|
||||||
|
case C4_GPIOX_PIN_START + 16 ...C4_GPIOX_PIN_END:
|
||||||
|
return C4_GPIOX_MUX_5_REG_OFFSET;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _getModeToGpio (int mode, int pin)
|
||||||
|
{
|
||||||
|
int retPin = -1;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
/* Native gpio number */
|
||||||
|
case MODE_GPIO:
|
||||||
|
retPin = pin;
|
||||||
|
break;
|
||||||
|
/* Native gpio number for sysfs */
|
||||||
|
case MODE_GPIO_SYS:
|
||||||
|
retPin = lib->sysFds[pin] != -1 ? pin : -1;
|
||||||
|
break;
|
||||||
|
/* wiringPi number */
|
||||||
|
case MODE_PINS:
|
||||||
|
retPin = pin < 64 ? pinToGpio[pin] : -1;
|
||||||
|
break;
|
||||||
|
/* header pin number */
|
||||||
|
case MODE_PHYS:
|
||||||
|
retPin = pin < 64 ? phyToGpio[pin] : -1;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retPin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _setPadDrive (int pin, int value)
|
||||||
|
{
|
||||||
|
int ds, shift;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (value < 0 || value > 3) {
|
||||||
|
msg(MSG_WARN, "%s : Invalid value %d (Must be 0 ~ 3)\n", __func__, value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ds = gpioToDSReg(pin);
|
||||||
|
shift = gpioToShiftReg(pin);
|
||||||
|
shift = pin > C4_GPIOX_PIN_MID ? (shift - 16) * 2 : shift * 2;
|
||||||
|
|
||||||
|
*(gpio + ds) &= ~(0b11 << shift);
|
||||||
|
*(gpio + ds) |= (value << shift);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _getPadDrive (int pin)
|
||||||
|
{
|
||||||
|
int ds, shift;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ds = gpioToDSReg(pin);
|
||||||
|
shift = gpioToShiftReg(pin);
|
||||||
|
shift = pin > C4_GPIOX_PIN_MID ? (shift - 16) * 2 : shift * 2;
|
||||||
|
|
||||||
|
return (*(gpio + ds) >> shift) & 0b11;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _pinMode (int pin, int mode)
|
||||||
|
{
|
||||||
|
int fsel, shift, origPin = pin;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
softPwmStop (origPin);
|
||||||
|
softToneStop (origPin);
|
||||||
|
|
||||||
|
fsel = gpioToGPFSELReg(pin);
|
||||||
|
shift = gpioToShiftReg (pin);
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case INPUT:
|
||||||
|
*(gpio + fsel) = (*(gpio + fsel) | (1 << shift));
|
||||||
|
break;
|
||||||
|
case OUTPUT:
|
||||||
|
*(gpio + fsel) = (*(gpio + fsel) & ~(1 << shift));
|
||||||
|
break;
|
||||||
|
case SOFT_PWM_OUTPUT:
|
||||||
|
softPwmCreate (pin, 0, 100);
|
||||||
|
break;
|
||||||
|
case SOFT_TONE_OUTPUT:
|
||||||
|
softToneCreate (pin);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _getAlt (int pin)
|
||||||
|
{
|
||||||
|
int fsel, mux, shift, target, mode;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fsel = gpioToGPFSELReg(pin);
|
||||||
|
mux = gpioToMuxReg(pin);
|
||||||
|
target = shift = gpioToShiftReg(pin);
|
||||||
|
|
||||||
|
while (target >= 8) {
|
||||||
|
target -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = (*(gpio + mux) >> (target * 4)) & 0xF;
|
||||||
|
return mode ? mode + 1 : (*(gpio + fsel) & (1 << shift)) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _getPUPD (int pin)
|
||||||
|
{
|
||||||
|
int puen, pupd, shift;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
puen = gpioToPUENReg(pin);
|
||||||
|
pupd = gpioToPUPDReg(pin);
|
||||||
|
shift = gpioToShiftReg(pin);
|
||||||
|
|
||||||
|
if (*(gpio + puen) & (1 << shift))
|
||||||
|
return *(gpio + pupd) & (1 << shift) ? 1 : 2;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _pullUpDnControl (int pin, int pud)
|
||||||
|
{
|
||||||
|
int shift = 0;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
shift = gpioToShiftReg(pin);
|
||||||
|
|
||||||
|
if (pud) {
|
||||||
|
// Enable Pull/Pull-down resister
|
||||||
|
*(gpio + gpioToPUENReg(pin)) =
|
||||||
|
(*(gpio + gpioToPUENReg(pin)) | (1 << shift));
|
||||||
|
|
||||||
|
if (pud == PUD_UP)
|
||||||
|
*(gpio + gpioToPUPDReg(pin)) =
|
||||||
|
(*(gpio + gpioToPUPDReg(pin)) | (1 << shift));
|
||||||
|
else
|
||||||
|
*(gpio + gpioToPUPDReg(pin)) =
|
||||||
|
(*(gpio + gpioToPUPDReg(pin)) & ~(1 << shift));
|
||||||
|
} else // Disable Pull/Pull-down resister
|
||||||
|
*(gpio + gpioToPUENReg(pin)) =
|
||||||
|
(*(gpio + gpioToPUENReg(pin)) & ~(1 << shift));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _digitalRead (int pin)
|
||||||
|
{
|
||||||
|
char c ;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS) {
|
||||||
|
if (lib->sysFds[pin] == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
lseek (lib->sysFds[pin], 0L, SEEK_SET);
|
||||||
|
if (read(lib->sysFds[pin], &c, 1) < 0) {
|
||||||
|
msg(MSG_WARN, "%s: Failed with reading from sysfs GPIO node. \n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (c == '0') ? LOW : HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((*(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin))) != 0)
|
||||||
|
return HIGH ;
|
||||||
|
else
|
||||||
|
return LOW ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _digitalWrite (int pin, int value)
|
||||||
|
{
|
||||||
|
if (lib->mode == MODE_GPIO_SYS) {
|
||||||
|
if (lib->sysFds[pin] != -1) {
|
||||||
|
if (value == LOW) {
|
||||||
|
if (write(lib->sysFds[pin], "0\n", 2) < 0)
|
||||||
|
msg(MSG_WARN, "%s: Failed with reading from sysfs GPIO node. \n", __func__);
|
||||||
|
} else {
|
||||||
|
if (write(lib->sysFds[pin], "1\n", 2) < 0)
|
||||||
|
msg(MSG_WARN, "%s: Failed with reading from sysfs GPIO node. \n", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (value == LOW)
|
||||||
|
*(gpio + gpioToGPSETReg(pin)) &= ~(1 << gpioToShiftReg(pin));
|
||||||
|
else
|
||||||
|
*(gpio + gpioToGPSETReg(pin)) |= (1 << gpioToShiftReg(pin));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _analogRead (int pin)
|
||||||
|
{
|
||||||
|
char value[5] = {0,};
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* wiringPi ADC number = pin 25, pin 29 */
|
||||||
|
switch (pin) {
|
||||||
|
case 3: case 25:
|
||||||
|
pin = 0;
|
||||||
|
break;
|
||||||
|
case 2: case 29:
|
||||||
|
pin = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (adcFds [pin] == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lseek (adcFds [pin], 0L, SEEK_SET);
|
||||||
|
if (read(adcFds [pin], &value[0], 4) < 0) {
|
||||||
|
msg(MSG_WARN, "%s: Error occurs when it reads from ADC file descriptor. \n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return atoi(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int _digitalWriteByte (const unsigned int value)
|
||||||
|
{
|
||||||
|
union reg_bitfield gpiox;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
gpiox.wvalue = *(gpio + C4_GPIOX_INP_REG_OFFSET);
|
||||||
|
|
||||||
|
/* Wiring PI GPIO0 = C4 GPIOX.3 */
|
||||||
|
gpiox.bits.bit3 = (value & 0x01);
|
||||||
|
/* Wiring PI GPIO1 = C4 GPIOX.16 */
|
||||||
|
gpiox.bits.bit16 = (value & 0x02);
|
||||||
|
/* Wiring PI GPIO2 = C4 GPIOX.4 */
|
||||||
|
gpiox.bits.bit4 = (value & 0x04);
|
||||||
|
/* Wiring PI GPIO3 = C4 GPIOX.7 */
|
||||||
|
gpiox.bits.bit7 = (value & 0x08);
|
||||||
|
/* Wiring PI GPIO4 = C4 GPIOX.0 */
|
||||||
|
gpiox.bits.bit0 = (value & 0x10);
|
||||||
|
/* Wiring PI GPIO5 = C4 GPIOX.1 */
|
||||||
|
gpiox.bits.bit1 = (value & 0x20);
|
||||||
|
/* Wiring PI GPIO6 = C4 GPIOX.2 */
|
||||||
|
gpiox.bits.bit2 = (value & 0x40);
|
||||||
|
/* Wiring PI GPIO7 = C4 GPIOX.5 */
|
||||||
|
gpiox.bits.bit5 = (value & 0x80);
|
||||||
|
|
||||||
|
*(gpio + C4_GPIOX_OUTP_REG_OFFSET) = gpiox.wvalue;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static unsigned int _digitalReadByte (void)
|
||||||
|
{
|
||||||
|
union reg_bitfield gpiox;
|
||||||
|
unsigned int value = 0;
|
||||||
|
|
||||||
|
if (lib->mode == MODE_GPIO_SYS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
gpiox.wvalue = *(gpio + C4_GPIOX_INP_REG_OFFSET);
|
||||||
|
|
||||||
|
/* Wiring PI GPIO0 = C4 GPIOX.3 */
|
||||||
|
if (gpiox.bits.bit3)
|
||||||
|
value |= 0x01;
|
||||||
|
/* Wiring PI GPIO1 = C4 GPIOX.16 */
|
||||||
|
if (gpiox.bits.bit16)
|
||||||
|
value |= 0x02;
|
||||||
|
/* Wiring PI GPIO2 = C4 GPIOX.4 */
|
||||||
|
if (gpiox.bits.bit4)
|
||||||
|
value |= 0x04;
|
||||||
|
/* Wiring PI GPIO3 = C4 GPIOX.7 */
|
||||||
|
if (gpiox.bits.bit7)
|
||||||
|
value |= 0x08;
|
||||||
|
/* Wiring PI GPIO4 = C4 GPIOX.0 */
|
||||||
|
if (gpiox.bits.bit0)
|
||||||
|
value |= 0x10;
|
||||||
|
/* Wiring PI GPIO5 = C4 GPIOX.1 */
|
||||||
|
if (gpiox.bits.bit1)
|
||||||
|
value |= 0x20;
|
||||||
|
/* Wiring PI GPIO6 = C4 GPIOX.2 */
|
||||||
|
if (gpiox.bits.bit2)
|
||||||
|
value |= 0x40;
|
||||||
|
/* Wiring PI GPIO7 = C4 GPIOX.5 */
|
||||||
|
if (gpiox.bits.bit5)
|
||||||
|
value |= 0x80;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void init_gpio_mmap (void)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
void *mapped;
|
||||||
|
|
||||||
|
/* GPIO mmap setup */
|
||||||
|
if (!getuid()) {
|
||||||
|
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
|
||||||
|
msg (MSG_ERR,
|
||||||
|
"wiringPiSetup: Unable to open /dev/mem: %s\n",
|
||||||
|
strerror (errno));
|
||||||
|
} else {
|
||||||
|
if (access("/dev/gpiomem",0) == 0) {
|
||||||
|
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0)
|
||||||
|
msg (MSG_ERR,
|
||||||
|
"wiringPiSetup: Unable to open /dev/gpiomem: %s\n",
|
||||||
|
strerror (errno));
|
||||||
|
} else
|
||||||
|
msg (MSG_ERR,
|
||||||
|
"wiringPiSetup: /dev/gpiomem doesn't exist. Please try again with sudo.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
msg(MSG_ERR, "wiringPiSetup: Cannot open memory area for GPIO use. \n");
|
||||||
|
} else {
|
||||||
|
// #define C4_GPIO_BASE 0xff634000
|
||||||
|
#ifdef ANDROID
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
mapped = mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, C4_GPIO_BASE);
|
||||||
|
#else
|
||||||
|
mapped = mmap64(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off64_t)C4_GPIO_BASE);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
mapped = mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, C4_GPIO_BASE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mapped == MAP_FAILED)
|
||||||
|
msg(MSG_ERR, "wiringPiSetup: mmap (GPIO) failed: %s \n", strerror (errno));
|
||||||
|
else
|
||||||
|
gpio = (uint32_t *) mapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void init_adc_fds (void)
|
||||||
|
{
|
||||||
|
const char *AIN25_NODE, *AIN29_NODE;
|
||||||
|
|
||||||
|
/* ADC node setup */
|
||||||
|
AIN25_NODE = "/sys/devices/platform/ff809000.saradc/iio:device0/in_voltage2_raw";
|
||||||
|
AIN29_NODE = "/sys/devices/platform/ff809000.saradc/iio:device0/in_voltage0_raw";
|
||||||
|
|
||||||
|
adcFds[0] = open(AIN25_NODE, O_RDONLY);
|
||||||
|
adcFds[1] = open(AIN29_NODE, O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void init_odroidc4 (struct libodroid *libwiring)
|
||||||
|
{
|
||||||
|
init_gpio_mmap();
|
||||||
|
|
||||||
|
init_adc_fds();
|
||||||
|
|
||||||
|
/* wiringPi Core function initialize */
|
||||||
|
libwiring->getModeToGpio = _getModeToGpio;
|
||||||
|
libwiring->setPadDrive = _setPadDrive;
|
||||||
|
libwiring->getPadDrive = _getPadDrive;
|
||||||
|
libwiring->pinMode = _pinMode;
|
||||||
|
libwiring->getAlt = _getAlt;
|
||||||
|
libwiring->getPUPD = _getPUPD;
|
||||||
|
libwiring->pullUpDnControl = _pullUpDnControl;
|
||||||
|
libwiring->digitalRead = _digitalRead;
|
||||||
|
libwiring->digitalWrite = _digitalWrite;
|
||||||
|
libwiring->analogRead = _analogRead;
|
||||||
|
libwiring->digitalWriteByte = _digitalWriteByte;
|
||||||
|
libwiring->digitalReadByte = _digitalReadByte;
|
||||||
|
|
||||||
|
/* specify pin base number */
|
||||||
|
libwiring->pinBase = C4_GPIO_PIN_BASE;
|
||||||
|
|
||||||
|
/* global variable setup */
|
||||||
|
lib = libwiring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
65
wiringPi/odroidc4.h
Normal file
65
wiringPi/odroidc4.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
|
||||||
|
WiringPi ODROID-C4 Board Header file
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#ifndef __ODROID_C4_H__
|
||||||
|
#define __ODROID_C4_H__
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#define C4_GPIO_BASE 0xFF634000
|
||||||
|
|
||||||
|
#define C4_GPIO_PIN_BASE 460
|
||||||
|
|
||||||
|
#define C4_GPIOH_PIN_START 17 // GPIOH_0
|
||||||
|
#define C4_GPIOH_PIN_END 25 // GPIOH_8
|
||||||
|
#define C4_GPIOA_PIN_START C4_GPIO_PIN_BASE // GPIOA_0
|
||||||
|
#define C4_GPIOA_PIN_END (C4_GPIO_PIN_BASE + 15) // GPIOA_15
|
||||||
|
#define C4_GPIOX_PIN_START (C4_GPIO_PIN_BASE + 16) // GPIOX_0
|
||||||
|
#define C4_GPIOX_PIN_MID (C4_GPIO_PIN_BASE + 31) // GPIOX_15
|
||||||
|
#define C4_GPIOX_PIN_END (C4_GPIO_PIN_BASE + 35) // GPIOX_19
|
||||||
|
|
||||||
|
#define C4_GPIOH_FSEL_REG_OFFSET 0x119
|
||||||
|
#define C4_GPIOH_OUTP_REG_OFFSET 0x11A
|
||||||
|
#define C4_GPIOH_INP_REG_OFFSET 0x11B
|
||||||
|
#define C4_GPIOH_PUPD_REG_OFFSET 0x13D
|
||||||
|
#define C4_GPIOH_PUEN_REG_OFFSET 0x14B
|
||||||
|
#define C4_GPIOH_DS_REG_3A_OFFSET 0x1D4
|
||||||
|
#define C4_GPIOH_MUX_B_REG_OFFSET 0x1BB
|
||||||
|
|
||||||
|
#define C4_GPIOA_FSEL_REG_OFFSET 0x120
|
||||||
|
#define C4_GPIOA_OUTP_REG_OFFSET 0x121
|
||||||
|
#define C4_GPIOA_INP_REG_OFFSET 0x122
|
||||||
|
#define C4_GPIOA_PUPD_REG_OFFSET 0x13F
|
||||||
|
#define C4_GPIOA_PUEN_REG_OFFSET 0x14D
|
||||||
|
#define C4_GPIOA_DS_REG_5A_OFFSET 0x1D6
|
||||||
|
#define C4_GPIOA_MUX_D_REG_OFFSET 0x1BD
|
||||||
|
#define C4_GPIOA_MUX_E_REG_OFFSET 0x1BE
|
||||||
|
|
||||||
|
#define C4_GPIOX_FSEL_REG_OFFSET 0x116
|
||||||
|
#define C4_GPIOX_OUTP_REG_OFFSET 0x117
|
||||||
|
#define C4_GPIOX_INP_REG_OFFSET 0x118
|
||||||
|
#define C4_GPIOX_PUPD_REG_OFFSET 0x13C
|
||||||
|
#define C4_GPIOX_PUEN_REG_OFFSET 0x14A
|
||||||
|
#define C4_GPIOX_DS_REG_2A_OFFSET 0x1D2
|
||||||
|
#define C4_GPIOX_DS_REG_2B_OFFSET 0x1D3
|
||||||
|
#define C4_GPIOX_MUX_3_REG_OFFSET 0x1B3
|
||||||
|
#define C4_GPIOX_MUX_4_REG_OFFSET 0x1B4
|
||||||
|
#define C4_GPIOX_MUX_5_REG_OFFSET 0x1B5
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void init_odroidc4 (struct libodroid *libwiring);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#endif /* __ODROID_C4_H__ */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "odroidxu3.h"
|
#include "odroidxu3.h"
|
||||||
#include "odroidn1.h"
|
#include "odroidn1.h"
|
||||||
#include "odroidn2.h"
|
#include "odroidn2.h"
|
||||||
|
#include "odroidc4.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
// Const string define
|
// Const string define
|
||||||
@@ -49,6 +50,7 @@ const char *piModelNames [16] =
|
|||||||
"ODROID-XU3/4",
|
"ODROID-XU3/4",
|
||||||
"ODROID-N1",
|
"ODROID-N1",
|
||||||
"ODROID-N2",
|
"ODROID-N2",
|
||||||
|
"ODROID-C4",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *piRevisionNames [16] =
|
const char *piRevisionNames [16] =
|
||||||
@@ -441,6 +443,11 @@ int piGpioLayout (void)
|
|||||||
libwiring.maker = MAKER_AMLOGIC;
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
libwiring.mem = 4;
|
libwiring.mem = 4;
|
||||||
libwiring.rev = 1;
|
libwiring.rev = 1;
|
||||||
|
} else if (strncmp (c, "05", 2) == 0) {
|
||||||
|
libwiring.model = MODEL_ODROID_C4;
|
||||||
|
libwiring.maker = MAKER_AMLOGIC;
|
||||||
|
libwiring.mem = 4;
|
||||||
|
libwiring.rev = 1;
|
||||||
} else {
|
} else {
|
||||||
libwiring.model = MODEL_UNKNOWN;
|
libwiring.model = MODEL_UNKNOWN;
|
||||||
libwiring.maker = MAKER_UNKNOWN;
|
libwiring.maker = MAKER_UNKNOWN;
|
||||||
@@ -474,6 +481,7 @@ int piBoardRev (void)
|
|||||||
* Rev 1.1 : /sys/class/odroid/boardrev value is 1 (Mass board)
|
* Rev 1.1 : /sys/class/odroid/boardrev value is 1 (Mass board)
|
||||||
* 03xx - Model ODROID N1, 4096M, Hardkernel
|
* 03xx - Model ODROID N1, 4096M, Hardkernel
|
||||||
* 04xx - Model ODROID N2, 4096M, Hardkernel
|
* 04xx - Model ODROID N2, 4096M, Hardkernel
|
||||||
|
* 05xx - Model ODROID C4, 4096M, Hardkernel
|
||||||
*/
|
*/
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
|
void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
|
||||||
@@ -1073,6 +1081,9 @@ int wiringPiSetup (void)
|
|||||||
case MODEL_ODROID_N2:
|
case MODEL_ODROID_N2:
|
||||||
init_odroidn2(&libwiring);
|
init_odroidn2(&libwiring);
|
||||||
break;
|
break;
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
|
init_odroidc4(&libwiring);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return wiringPiFailure (WPI_ALMOST,
|
return wiringPiFailure (WPI_ALMOST,
|
||||||
"wiringPiSetup: Unknown model\n");
|
"wiringPiSetup: Unknown model\n");
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#define MODEL_ODROID_XU3 3
|
#define MODEL_ODROID_XU3 3
|
||||||
#define MODEL_ODROID_N1 4
|
#define MODEL_ODROID_N1 4
|
||||||
#define MODEL_ODROID_N2 5
|
#define MODEL_ODROID_N2 5
|
||||||
|
#define MODEL_ODROID_C4 6
|
||||||
|
|
||||||
#define MAKER_UNKNOWN 0
|
#define MAKER_UNKNOWN 0
|
||||||
#define MAKER_AMLOGIC 1
|
#define MAKER_AMLOGIC 1
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ int wiringPiI2CSetup (const int devId)
|
|||||||
device = "/dev/i2c-4";
|
device = "/dev/i2c-4";
|
||||||
break;
|
break;
|
||||||
case MODEL_ODROID_N2:
|
case MODEL_ODROID_N2:
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
device = "/dev/i2c-2";
|
device = "/dev/i2c-2";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ int wiringPiSPISetupMode (int channel, int speed, int mode)
|
|||||||
switch(model) {
|
switch(model) {
|
||||||
case MODEL_ODROID_C1:
|
case MODEL_ODROID_C1:
|
||||||
case MODEL_ODROID_N2:
|
case MODEL_ODROID_N2:
|
||||||
|
case MODEL_ODROID_C4:
|
||||||
sprintf(device, "%s%d", spiDevType0, channel);
|
sprintf(device, "%s%d", spiDevType0, channel);
|
||||||
break;
|
break;
|
||||||
case MODEL_ODROID_XU3:
|
case MODEL_ODROID_XU3:
|
||||||
|
|||||||
Reference in New Issue
Block a user