diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a02d1a3 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +clean: + make -C wiringPi clean + make -C devLib clean + make -C gpio clean + make -C examples clean + make -C examples/Gertboard clean + make -C examples/PiFace clean + make -C examples/q2w clean + make -C examples/PiGlow clean + +install: + make -C wiringPi + make -C wiringPi install + make -C devLib + make -C devLib install + make -C gpio + make -C gpio install + mkdir -p /usr/share/wiringPi/examples/Gertboard + mkdir -p /usr/share/wiringPi/examples/PiFace + mkdir -p /usr/share/wiringPi/examples/PiGlow + mkdir -p /usr/share/wiringPi/examples/q2w + find examples -exec install -m 0644 -D -t /usr/share/wiringPi/examples {} \; diff --git a/README.TXT b/README.TXT index 7789b2e..8afcf39 100644 --- a/README.TXT +++ b/README.TXT @@ -17,6 +17,8 @@ accepted to Github.... Please see http://wiringpi.com/ + + Documentation for installing this repo on ODROIDs is found in the ODROID wiki. Please see https://wiki.odroid.com/ and select the appropriate board model from the list. for the official documentation, etc. and the best way to submit bug reports, etc. is by sending an email to projects@drogon.net diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c deleted file mode 100644 index 1b1c0dd..0000000 --- a/devLib/piFaceOld.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * piFace.: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012-2013 Gordon Henderson - * - * This file to interface with the PiFace peripheral device which - * has an MCP23S17 GPIO device connected via the SPI bus. - *********************************************************************** - * 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 . - *********************************************************************** - */ - - -#include -#include - -#include -#include - -#include "../wiringPi/mcp23x0817.h" - -#include "piFace.h" - -#define PIFACE_SPEED 4000000 -#define PIFACE_DEVNO 0 - - - -/* - * writeByte: - * Write a byte to a register on the MCP23S17 on the SPI bus. - ********************************************************************************* - */ - -static void writeByte (uint8_t reg, uint8_t data) -{ - uint8_t spiData [4] ; - - spiData [0] = CMD_WRITE ; - spiData [1] = reg ; - spiData [2] = data ; - - wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; -} - -/* - * readByte: - * Read a byte from a register on the MCP23S17 on the SPI bus. - ********************************************************************************* - */ - -static uint8_t readByte (uint8_t reg) -{ - uint8_t spiData [4] ; - - spiData [0] = CMD_READ ; - spiData [1] = reg ; - - wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; - - return spiData [2] ; -} - - -/* - * myDigitalWrite: - * Perform the digitalWrite function on the PiFace board - ********************************************************************************* - */ - -void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) -{ - uint8_t mask, old ; - - pin -= node->pinBase ; - mask = 1 << pin ; - old = readByte (MCP23x17_GPIOA) ; - - if (value == 0) - old &= (~mask) ; - else - old |= mask ; - - writeByte (MCP23x17_GPIOA, old) ; -} - - -/* - * myDigitalRead: - * Perform the digitalRead function on the PiFace board - ********************************************************************************* - */ - -int myDigitalRead (struct wiringPiNodeStruct *node, int pin) -{ - uint8_t mask, reg ; - - mask = 1 << ((pin - node->pinBase) & 7) ; - - if (pin < 8) - reg = MCP23x17_GPIOB ; // Input regsiter - else - reg = MCP23x17_OLATA ; // Output latch regsiter - - if ((readByte (reg) & mask) != 0) - return HIGH ; - else - return LOW ; -} - - -/* - * myPullUpDnControl: - * Perform the pullUpDnControl function on the PiFace board - ********************************************************************************* - */ - -void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) -{ - uint8_t mask, old ; - - mask = 1 << (pin - node->pinBase) ; - old = readByte (MCP23x17_GPPUB) ; - - if (pud == 0) - old &= (~mask) ; - else - old |= mask ; - - writeByte (MCP23x17_GPPUB, old) ; -} - - -/* - * piFaceSetup - * Setup the SPI interface and initialise the MCP23S17 chip - * We create one node with 16 pins - each if the first 8 pins being read - * and write - although the operations actually go to different - * hardware ports. The top 8 let you read the state of the output register. - ********************************************************************************* - */ - -int piFaceSetup (const int pinBase) -{ - int x ; - struct wiringPiNodeStruct *node ; - - if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0) - return x ; - -// Setup the MCP23S17 - - writeByte (MCP23x17_IOCON, IOCON_INIT) ; - writeByte (MCP23x17_IODIRA, 0x00) ; // Port A -> Outputs - writeByte (MCP23x17_IODIRB, 0xFF) ; // Port B -> Inputs - - node = wiringPiNewNode (pinBase, 16) ; - node->digitalRead = myDigitalRead ; - node->digitalWrite = myDigitalWrite ; - node->pullUpDnControl = myPullUpDnControl ; - - return 0 ; -} diff --git a/gpio/gpio.c b/gpio/gpio.c old mode 100644 new mode 100755 index 43e6934..8567e77 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -53,11 +53,16 @@ extern void doPins (void) ; # define FALSE (1==2) #endif -#define VERSION "2.21" +/* + 2.31 : ODROID-C1/ODROID-C2 wiringPi support + 2.33 : ODROID-C1/ODROID-C2 GPIO sysfs irq support +*/ +#define VERSION "2.33" #define PI_USB_POWER_CONTROL 38 #define I2CDETECT "/usr/sbin/i2cdetect" int wpMode ; +int piModel = PI_MODEL_UNKNOWN; char *usage = "Usage: gpio -v\n" " gpio -h\n" @@ -208,28 +213,114 @@ static void doLoad (int argc, char *argv []) else _doLoadUsage (argv) ; - if (!moduleLoaded (module1)) - { - sprintf (cmd, "modprobe %s%s", module1, args1) ; - system (cmd) ; - } - - if (!moduleLoaded (module2)) - { - sprintf (cmd, "modprobe %s%s", module2, args2) ; - system (cmd) ; + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + if (strcasecmp (argv [2], "i2c") == 0) { + if (piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2) { + module1 = "aml-i2c"; + file1 = "/dev/i2c-1"; + file2 = "/dev/i2c-2"; + + if (!moduleLoaded(module1)) { + sprintf (cmd, "PATH=/bin:/usr/bin:/sbin:/usr/local/bin modprobe %s", module1) ; + system (cmd) ; + } + } + else { + file1 = "/dev/i2c-4"; /* i2c smbus : 0x12c70000 */ + file2 = "/dev/i2c-1"; /* hsi2c : 0x12cb0000 */ + } + + sleep (1) ; // To let things get settled + changeOwner (argv [0], file1) ; + changeOwner (argv [0], file2) ; + } + else { + if (piModel == PI_MODEL_ODROIDC2) { + fprintf (stderr, "ODROID-C2 : H/W SPI not support!\n") ; + return; + } + if (piModel == PI_MODEL_ODROIDC) { + file1 = "/dev/spidev0.0"; + module1 = "spidev"; + module2 = "spicc"; + if (!moduleLoaded(module1)) { + sprintf (cmd, "PATH=/bin:/usr/bin:/sbin:/usr/local/bin modprobe %s%s", module1, args1) ; + system (cmd) ; + } + if (!moduleLoaded(module2)) { + sprintf (cmd, "PATH=/bin:/usr/bin:/sbin:/usr/local/bin modprobe %s", module2) ; + system (cmd) ; + } + if (!moduleLoaded (module2)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; + exit (1) ; + } + + sleep (1) ; // To let things get settled + changeOwner (argv [0], file1) ; + } + else { + module1 = "spidev"; + file1 = "/dev/spidev1.0"; + + if (!moduleLoaded (module1)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module1) ; + fprintf (stderr, "\nYou need modified dtb file for spidev.\n"); + fprintf (stderr, "\nstep 1)\n"); + fprintf (stderr, " - install device-tree-compiler.\n"); + fprintf (stderr, " sudo apt-get install device-tree-compiler\n"); + fprintf (stderr, "\nstep 2)\n"); + fprintf (stderr, " - modified dtb file.\n"); + fprintf (stderr, " sudo -s\n"); + fprintf (stderr, " fdtput -c /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev\n"); + fprintf (stderr, " fdtput -t s /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev compatible \"spidev\"\n"); + fprintf (stderr, " fdtput -t x /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev reg 0\n"); + fprintf (stderr, " fdtput -t i /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev spi-max-frequency 20000000\n"); + fprintf (stderr, " fdtput -c /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev/controller-data\n"); + fprintf (stderr, " fdtput -t x /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev/controller-data cs-gpio 0x44, 0x5, 0x0\n"); + fprintf (stderr, " fdtput -t x /media/boot/exynos5422-odroidxu3.dtb /spi@12d30000/spidev/controller-data samsung,spi-feedback-delay 0\n"); + fprintf (stderr, "\nstep 3)\n"); + fprintf (stderr, " - reboot system.\n"); + fprintf (stderr, " sudo reboot\n"); + fprintf (stderr, "\nstep 4)\n"); + fprintf (stderr, " - check your SPI node.\n"); + fprintf (stderr, " ls /dev/spidev1.0\n"); + // fdtput + exit (1) ; + } + + sleep (1) ; // To let things get settled + changeOwner (argv [0], file1) ; + } + } } + else { + if (!moduleLoaded (module1)) + { + sprintf (cmd, "PATH=/bin:/usr/bin:/sbin:/usr/local/bin modprobe %s%s", module1, args1) ; + system (cmd) ; + } - if (!moduleLoaded (module2)) - { - fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; - exit (1) ; - } + if (!moduleLoaded (module2)) + { + sprintf (cmd, "PATH=/bin:/usr/bin:/sbin:/usr/local/bin modprobe %s%s", module2, args2) ; + system (cmd) ; + } - sleep (1) ; // To let things get settled + if (!moduleLoaded (module2)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; + exit (1) ; + } + sleep (1) ; // To let things get settled - changeOwner (argv [0], file1) ; - changeOwner (argv [0], file2) ; + changeOwner (argv [0], file1) ; + changeOwner (argv [0], file2) ; + } } @@ -277,7 +368,8 @@ static void doExports (int argc, char *argv []) char fName [128] ; char buf [16] ; - for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective + // ODROIDC GPIO Max 128, ODROIDXU_34 GPIO Max 256 + for (first = 0, i = 0 ; i < 256 ; ++i) // Crude, but effective { // Try to read the direction @@ -370,7 +462,9 @@ void doExport (int argc, char *argv []) mode = argv [3] ; - if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) + sprintf (fName, "/sys/class/%s/export", "gpio"); + + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; exit (1) ; @@ -380,6 +474,7 @@ void doExport (int argc, char *argv []) fclose (fd) ; sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -401,9 +496,11 @@ void doExport (int argc, char *argv []) // Change ownership so the current user can actually use it! sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + changeOwner (argv [0], fName) ; sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + changeOwner (argv [0], fName) ; } @@ -470,6 +567,9 @@ void doEdge (int argc, char *argv []) char *mode ; char fName [128] ; + // Reset irq gpio + doUnexport(3, argv); // unexport argc == 3 + if (argc != 4) { fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ; @@ -481,16 +581,18 @@ void doEdge (int argc, char *argv []) // Export the pin and set direction to input - if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) + sprintf (fName, "/sys/class/%s/export", "gpio"); + + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; exit (1) ; } - fprintf (fd, "%d\n", pin) ; fclose (fd) ; - sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin); + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -500,7 +602,8 @@ void doEdge (int argc, char *argv []) fprintf (fd, "in\n") ; fclose (fd) ; - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin); + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; @@ -519,10 +622,12 @@ void doEdge (int argc, char *argv []) // Change ownership of the value and edge files, so the current user can actually use it! - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin); + changeOwner (argv [0], fName) ; - sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin); + changeOwner (argv [0], fName) ; fclose (fd) ; @@ -540,6 +645,7 @@ void doUnexport (int argc, char *argv []) { FILE *fd ; int pin ; + char fName [128] ; if (argc != 3) { @@ -549,7 +655,9 @@ void doUnexport (int argc, char *argv []) pin = atoi (argv [2]) ; - if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) + sprintf (fName, "/sys/class/%s/unexport", "gpio") ; + + if ((fd = fopen (fName, "w")) == NULL) { fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; exit (1) ; @@ -573,7 +681,8 @@ void doUnexportall (char *progName) FILE *fd ; int pin ; - for (pin = 0 ; pin < 63 ; ++pin) + // ODROIDC GPIO Max 128, ODROIDXU_34 GPIO Max 256 + for (pin = 0 ; pin < 256 ; ++pin) { if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) { @@ -626,9 +735,12 @@ static void doReset (char *progName) piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) + /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) endPin = 16 ; - else if (model == PI_MODEL_BP) + else if ((model == PI_MODEL_BP) || + (model == PI_MODEL_ODROIDC) || + (model == PI_MODEL_ODROIDC2) || + (model == PI_MODEL_ODROIDXU_34)) endPin = 39 ; else if (model == PI_MODEL_CM) { @@ -1180,6 +1292,9 @@ int main (int argc, char *argv []) return 0 ; } + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + piModel = model; + if (strcmp (argv [1], "-v") == 0) { printf ("gpio version: %s\n", VERSION) ; @@ -1187,18 +1302,25 @@ int main (int argc, char *argv []) printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; printf ("For details type: %s -warranty\n", argv [0]) ; printf ("\n") ; - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; if (model == PI_MODEL_UNKNOWN) { printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ; printf (" projects@drogon.net\n") ; printf ("with a copy of your /proc/cpuinfo if possible\n") ; } + else if ( model == PI_MODEL_ODROIDC || + model == PI_MODEL_ODROIDXU_34 || + model == PI_MODEL_ODROIDC2 ) + { + printf ("Hardkernel ODROID Details:\n") ; + printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s\n", + piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker]) ; + } else { printf ("Raspberry Pi Details:\n") ; printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", - piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ; + piModelNames [model], piRevisionNames [rev], mem, piMakerNames [maker], overVolted ? "[OV]" : "") ; } return 0 ; } diff --git a/gpio/readall.c b/gpio/readall.c old mode 100644 new mode 100755 index aba8de8..f05b298 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -147,6 +147,125 @@ static char *physNames [64] = NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, } ; +static char *physNamesOdroidc [64] = +{ + NULL, + + " 3.3v", "5v ", + " SDA.1", "5V ", + " SCL.1", "0v ", + "GPIO. 83", "TxD1 ", + " 0v", "RxD1 ", + "GPIO. 88", "GPIO. 87", + "GPIO.116", "0v ", + "GPIO.115", "GPIO.104", + " 3.3v", "GPIO.102", + " MOSI", "0v ", + " MISO", "GPIO.103", + " SCLK", "CE0 ", + " 0v", "GPIO.118", + " SDA.2", "SCL.2 ", + "GPIO.101", "0v ", + "GPIO.100", "GPIO. 99", + "GPIO.108", "0v ", + "GPIO.97 ", "GPIO. 98", + " AIN.1", "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 char *physNamesOdroidc2_Rev1_1 [64] = +{ + NULL, + + " 3.3v", "5v ", + " SDA.1", "5V ", + " SCL.1", "0v ", + "GPIO.249", "TxD1 ", + " 0v", "RxD1 ", + "GPIO.247", "GPIO.238", + "GPIO.239", "0v ", + "GPIO.237", "GPIO.236", + " 3.3v", "GPIO.233", + "GPIO.235", "0v ", + "GPIO.232", "GPIO.231", + "GPIO.230", "GPIO.229", + " 0v", "GPIO.225", + " SDA.2", "SCL.2 ", + "GPIO.228", "0v ", + "GPIO.219", "GPIO.224", + "GPIO.234", "0v ", + "GPIO.214", "GPIO.218", + " AIN.1", "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 char *physNamesOdroidc2_Rev1_0 [64] = +{ + NULL, + + " 3.3v", "5v ", + " SDA.1", "5V ", + " SCL.1", "0v ", + "GPIO.214", "--------", + " 0v", "--------", + "GPIO.219", "GPIO.218", + "GPIO.247", "0v ", + "--------", "GPIO.235", + " 3.3v", "GPIO.233", + "GPIO.238", "0v ", + "GPIO.237", "GPIO.234", + "GPIO.236", "GPIO.248", + " 0v", "GPIO.249", + " SDA.2", "SCL.2 ", + "GPIO.232", "0v ", + "GPIO.231", "GPIO.230", + "GPIO.239", "0v ", + "GPIO.228", "GPIO.229", + " AIN.1", "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 char *physNamesOdroidXU [64] = +{ + NULL, + + " 3.3v", "5v ", + "I2C1.SDA", "5V ", + "I2C1.SCL", "0v ", + "GPIO. 18", "UART0.TX", + " 0v", "UART0.RX", + "GPIO.174", "GPIO.173", + "GPIO. 21", "0v ", + "GPIO. 22", "GPIO. 19", + " 3.3v", "GPIO. 23", + " MOSI", "0v ", + " MISO", "GPIO. 24", + " SCLK", "CE0 ", + " 0v", "GPIO. 25", + "I2C5.SDA", "I2C5.SCL", + "GPIO. 28", "0v ", + "GPIO. 30", "GPIO. 29", + "GPIO. 31", "0v ", + "POWER ON", "GPIO. 33", + " AIN.0", "1v8 ", + " 0v", "AIN.3 ", + + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL, +} ; /* * readallPhys: @@ -305,6 +424,183 @@ void piPlusReadall (int model) printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; } +static void readallPhysOdroidC (int physPin, int model, int rev) +{ + int pin ; + + if ((physPinToGpio (physPin) == -1) && (physToWpi [physPin] == -1)) + printf (" | | "); + else if (physPinToGpio (physPin) != -1) + printf (" | %3d | %3d", physPinToGpio (physPin), physToWpi [physPin]); + else + printf (" | | %3d", physToWpi [physPin]); + + if (model == PI_MODEL_ODROIDC) + printf (" | %s", physNamesOdroidc [physPin]) ; + else { + if (rev == PI_VERSION_1) + printf (" | %s", physNamesOdroidc2_Rev1_0 [physPin]) ; + else + printf (" | %s", physNamesOdroidc2_Rev1_1 [physPin]) ; + } + + if ((physToWpi [physPin] == -1) || (physPinToGpio (physPin) == -1)) + printf (" | | "); + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + if( physPinToGpio (physPin) == -1 ) { + printf (" | | ") ; + } + else { + printf (" | %4s", alts [getAlt (pin)]) ; + printf (" | %d", digitalRead (pin)) ; + } + } + +// Pin numbers: + + printf (" | %2d", physPin) ; + ++physPin ; + printf (" || %-2d", physPin) ; + +// Same, reversed + + if ((physToWpi [physPin] == -1) || (physPinToGpio (physPin) == -1)) + printf (" | | "); + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + if (physPinToGpio (physPin) == -1) { + printf (" | | ") ; + } + else { + printf (" | %d", digitalRead (pin)) ; + printf (" | %-4s", alts [getAlt (pin)]) ; + } + } + + if (model == PI_MODEL_ODROIDC) + printf (" | %-6s", physNamesOdroidc [physPin]) ; + else { + if (rev == PI_VERSION_1) + printf (" | %-6s", physNamesOdroidc2_Rev1_0 [physPin]) ; + else + printf (" | %-6s", physNamesOdroidc2_Rev1_1 [physPin]) ; + } + + if ((physPinToGpio (physPin) == -1) && (physToWpi [physPin] == -1)) + printf (" | | "); + else if (physPinToGpio (physPin) != -1) + printf (" | %-3d | %-3d", physToWpi [physPin], physPinToGpio (physPin)); + else + printf (" | %-3d | ", physToWpi [physPin]); + + printf (" |\n") ; +} + +void ReadallOdroidC (int model, int rev) +{ + int pin ; + + if(model == PI_MODEL_ODROIDC2) + printf (" +------+-----+----------+------+ Model ODROID-C2 +------+----------+-----+------+\n") ; + else + printf (" +------+-----+----------+------+- Model ODROID-C -+------+----------+-----+------+\n") ; + + printf (" | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |\n") ; + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n") ; + for (pin = 1 ; pin <= 40 ; pin += 2) + readallPhysOdroidC (pin, model, rev) ; + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n") ; +} + +static void readallPhysOdroidXU (int physPin) +{ + int pin ; + + if ((physPinToGpio (physPin) == -1) && (physToWpi [physPin] == -1)) + printf (" | | ") ; + else if (physPinToGpio (physPin) != -1) + printf (" | %3d | %3d", physPinToGpio (physPin), physToWpi [physPin]); + else + printf (" | | %3d", physToWpi [physPin]); + + printf (" | %s", physNamesOdroidXU [physPin]) ; + + if ((physToWpi [physPin] == -1) || (physPinToGpio (physPin) == -1)) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %4s", alts [getAlt (pin)]) ; + printf (" | %d", digitalRead (pin)) ; + } + +// Pin numbers: + + printf (" | %2d", physPin) ; + ++physPin ; + printf (" || %-2d", physPin) ; + +// Same, reversed + + if ((physToWpi [physPin] == -1) || (physPinToGpio (physPin) == -1)) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %d", digitalRead (pin)) ; + printf (" | %-4s", alts [getAlt (pin)]) ; + } + + printf (" | %-6s", physNamesOdroidXU [physPin]) ; + + if ((physPinToGpio (physPin) == -1) && (physToWpi [physPin] == -1)) + printf (" | | ") ; + else if (physPinToGpio (physPin) != -1) + printf (" | %-3d | %-3d", physToWpi [physPin], physPinToGpio (physPin)); + else + printf (" | %-3d | ", physToWpi [physPin]); + + printf (" |\n") ; +} + +void ReadallOdroidXU (void) +{ + int pin ; + + printf (" +------+-----+----------+------ Model ODROID-XU3/4 ------+----------+-----+------+\n") ; + printf (" | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |\n") ; + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n") ; + for (pin = 1 ; pin <= 40 ; pin += 2) + readallPhysOdroidXU (pin) ; + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n") ; +} void doReadall (void) { @@ -324,6 +620,10 @@ void doReadall (void) piPlusReadall (model) ; else if (model == PI_MODEL_CM) cmReadall () ; + else if (model == PI_MODEL_ODROIDC || model == PI_MODEL_ODROIDC2) + ReadallOdroidC (model, rev); + else if (model == PI_MODEL_ODROIDXU_34) + ReadallOdroidXU(); else printf ("Oops - unable to determine board type... model: %d\n", model) ; } diff --git a/postinstall-pak b/postinstall-pak new file mode 100644 index 0000000..469eb47 --- /dev/null +++ b/postinstall-pak @@ -0,0 +1,7 @@ +#!/bin/bash +echo +echo "WiringPi for C1 is now installed" +echo "Please check the wiki: http://odroid.com/dokuwiki/doku.php?id=en:odroid-c1" +echo "For extra references:" +echo "Github: https://github.com/hardkernel/wiringPi" +echo "Examples folder is copied to /usr/share/wiringPi/examples" diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c old mode 100644 new mode 100755 index ba45f4d..6d1c110 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -51,7 +51,6 @@ // Added in the 2 UART pins // Change maxPins to numPins to more accurately reflect purpose - #include #include #include @@ -69,6 +68,7 @@ #include #include #include +#include #include "softPwm.h" #include "softTone.h" @@ -80,6 +80,10 @@ #define FALSE (1==2) #endif +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + // Environment Variables #define ENV_DEBUG "WIRINGPI_DEBUG" @@ -131,15 +135,15 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) -#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) -#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) -#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) -#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) +#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) +#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) +#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) +#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) -#define PAGE_SIZE (4*1024) -#define BLOCK_SIZE (4*1024) +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) // PWM // Word offsets into the PWM control region @@ -175,19 +179,19 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // 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) +#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 uint32_t *gpio ; +static volatile uint32_t *gpio, *gpio1; static volatile uint32_t *pwm ; static volatile uint32_t *clk ; static volatile uint32_t *pads ; @@ -203,7 +207,7 @@ static volatile uint32_t *timerIrqRaw ; // and PI_VERSION_X defines in wiringPi.h // Only intended for the gpio command - use at your own risk! -const char *piModelNames [6] = +const char *piModelNames [9] = { "Unknown", "Model A", @@ -211,6 +215,9 @@ const char *piModelNames [6] = "Model B+", "Compute Module", "Model A+", + "ODROID-C1/C1+", + "ODROID-XU3/4", + "ODROID-C2", } ; const char *piRevisionNames [5] = @@ -222,12 +229,13 @@ const char *piRevisionNames [5] = "2", } ; -const char *piMakerNames [4] = +const char *piMakerNames [5] = { "Unknown", "Egoman", "Sony", "Qusda", + "Hardkernel", } ; @@ -271,6 +279,7 @@ static void (*isrFunctions [64])(void) ; // Cope for 3 different board revisions here. static int *pinToGpio ; +static int pin_array_count; // Revision 1, 1.1: @@ -565,6 +574,594 @@ static uint8_t gpioToClkDiv [] = -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63 } ; +// +// For ODROID-C Board +// +#define ODROIDC_GPIO_MASK (0xFFFFFF80) + +#define ODROIDC_PERI_BASE 0xC1100000 +#define GPIO_REG_OFFSET 0x8000 +#define ODROID_GPIO_BASE (ODROIDC_PERI_BASE + GPIO_REG_OFFSET) + +#define GPIO_PIN_BASE 80 +#define GPIOY_PIN_START 80 +#define GPIOY_PIN_END 96 +#define GPIOX_PIN_START 97 +#define GPIOX_PIN_END 118 + +#define GPIOX_FSEL_REG_OFFSET 0x0C +#define GPIOX_OUTP_REG_OFFSET 0x0D +#define GPIOX_INP_REG_OFFSET 0x0E +#define GPIOX_PUPD_REG_OFFSET 0x3E +#define GPIOX_PUEN_REG_OFFSET 0x4C + +#define GPIOY_FSEL_REG_OFFSET 0x0F +#define GPIOY_OUTP_REG_OFFSET 0x10 +#define GPIOY_INP_REG_OFFSET 0x11 +#define GPIOY_PUPD_REG_OFFSET 0x3D +#define GPIOY_PUEN_REG_OFFSET 0x4B + +#define piAinNode0 "/sys/class/saradc/saradc_ch0" +#define piAinNode1 "/sys/class/saradc/saradc_ch1" + +static int adcFds [2] = { + -1, -1, +} ; + +// +// For ODROID-C2 Board +// +#define ODROIDC2_GPIO_MASK (0xFFFFFF00) +#define ODROIDC2_GPIO_BASE 0xC8834000 + +#define C2_GPIO_PIN_BASE 136 +#define C2_GPIOY_PIN_START (C2_GPIO_PIN_BASE + 75) +#define C2_GPIOY_PIN_END (C2_GPIO_PIN_BASE + 91) +#define C2_GPIOX_PIN_START (C2_GPIO_PIN_BASE + 92) +#define C2_GPIOX_PIN_END (C2_GPIO_PIN_BASE + 114) + +#define C2_GPIOX_FSEL_REG_OFFSET 0x118 +#define C2_GPIOX_OUTP_REG_OFFSET 0x119 +#define C2_GPIOX_INP_REG_OFFSET 0x11A +#define C2_GPIOX_PUPD_REG_OFFSET 0x13E +#define C2_GPIOX_PUEN_REG_OFFSET 0x14C + +#define C2_GPIOY_FSEL_REG_OFFSET 0x10F +#define C2_GPIOY_OUTP_REG_OFFSET 0x110 +#define C2_GPIOY_INP_REG_OFFSET 0x111 +#define C2_GPIOY_PUPD_REG_OFFSET 0x13B +#define C2_GPIOY_PUEN_REG_OFFSET 0x149 + +#define C2_piAinNode0 "/sys/class/saradc/ch0" +#define C2_piAinNode1 "/sys/class/saradc/ch1" + +// +// For ODROID-XU3/4 Board +// +#define ODROIDXU_GPIO_MASK (0xFFFFFF00) + +#define ODROIDXU_GPX_BASE 0x13400000 // GPX0,1,2,3 +#define ODROIDXU_GPA_BASE 0x14010000 // GPA0,1,2, GPB0,1,2,3,4 + +#define GPIO_X1_START 16 +#define GPIO_X1_CON_OFFSET 0x0C20 +#define GPIO_X1_DAT_OFFSET 0x0C24 +#define GPIO_X1_PUD_OFFSET 0x0C28 +#define GPIO_X1_END 23 + +#define GPIO_X2_START 24 +#define GPIO_X2_CON_OFFSET 0x0C40 +#define GPIO_X2_DAT_OFFSET 0x0C44 +#define GPIO_X2_PUD_OFFSET 0x0C48 +#define GPIO_X2_END 31 + +#define GPIO_X3_START 32 +#define GPIO_X3_CON_OFFSET 0x0C60 +#define GPIO_X3_DAT_OFFSET 0x0C64 +#define GPIO_X3_PUD_OFFSET 0x0C68 +#define GPIO_X3_END 39 + +#define GPIO_A0_START 171 +#define GPIO_A0_CON_OFFSET 0x0000 +#define GPIO_A0_DAT_OFFSET 0x0004 +#define GPIO_A0_PUD_OFFSET 0x0008 +#define GPIO_A0_END 178 + +#define GPIO_A2_START 185 +#define GPIO_A2_CON_OFFSET 0x0040 +#define GPIO_A2_DAT_OFFSET 0x0044 +#define GPIO_A2_PUD_OFFSET 0x0048 +#define GPIO_A2_END 192 + +#define GPIO_B3_START 207 +#define GPIO_B3_CON_OFFSET 0x00C0 +#define GPIO_B3_DAT_OFFSET 0x00C4 +#define GPIO_B3_PUD_OFFSET 0x00C8 +#define GPIO_B3_END 214 + +static char *piAinNode0_xu; +static char *piAinNode1_xu; + +static int piModel = PI_MODEL_UNKNOWN; + +static int sysFdData [64] = { + -1, -1, -1, -1, -1, -1, -1, -1, // 0...7 + -1, -1, -1, -1, -1, -1, -1, -1, // 8...15 + -1, -1, -1, -1, -1, -1, -1, -1, // 16...23 + -1, -1, -1, -1, -1, -1, -1, -1, // 24...31 + -1, -1, -1, -1, -1, -1, -1, -1, // 32...39 + -1, -1, -1, -1, -1, -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 int sysFdIrqType [64] = { + -1, -1, -1, -1, -1, -1, -1, -1, // 0...7 + -1, -1, -1, -1, -1, -1, -1, -1, // 8...15 + -1, -1, -1, -1, -1, -1, -1, -1, // 16...23 + -1, -1, -1, -1, -1, -1, -1, -1, // 24...31 + -1, -1, -1, -1, -1, -1, -1, -1, // 32...39 + -1, -1, -1, -1, -1, -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 int gpioToPin(int gpio) +{ + int pin; + + if (pinToGpio == NULL) { + (void)wiringPiFailure (WPI_FATAL, "%s: wiringPi is not initialized yet\n", __func__); + return -1; + } + + for (pin = 0; pin < pin_array_count; ++pin) { + if (pinToGpio[pin] == gpio) + return pin; + } + + (void)wiringPiFailure (WPI_FATAL, "%s: could not find the pin of %d gpio\n", __func__, gpio); + return -1; +} + +// +// sysfs FD offset +// +static int gpioFdOffsetXU34(int pin) +{ + int offset = -1; + + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: offset = (pin - GPIO_X1_START) + 0; break; + case GPIO_X2_START...GPIO_X2_END: offset = (pin - GPIO_X2_START) + 8; break; + case GPIO_X3_START...GPIO_X3_END: offset = (pin - GPIO_X3_START) + 16; break; + case GPIO_A0_START...GPIO_A0_END: offset = (pin - GPIO_A0_START) + 24; break; + case GPIO_A2_START...GPIO_A2_END: offset = (pin - GPIO_A2_START) + 32; break; + case GPIO_B3_START...GPIO_B3_END: offset = (pin - GPIO_B3_START) + 40; break; + default : offset = -1; break; + } + return offset; +} + +// +// offset to the GPIO Set regsiter +// +static int gpioToGPSETReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDXU_34) { + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: + return (GPIO_X1_DAT_OFFSET >> 2); + case GPIO_X2_START...GPIO_X2_END: + return (GPIO_X2_DAT_OFFSET >> 2); + case GPIO_X3_START...GPIO_X3_END: + return (GPIO_X3_DAT_OFFSET >> 2); + case GPIO_A0_START...GPIO_A0_END: + return (GPIO_A0_DAT_OFFSET >> 2); + case GPIO_A2_START...GPIO_A2_END: + return (GPIO_A2_DAT_OFFSET >> 2); + case GPIO_B3_START...GPIO_B3_END: + return (GPIO_B3_DAT_OFFSET >> 2); + default: + break; + } + } + else if (piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return C2_GPIOX_OUTP_REG_OFFSET; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return C2_GPIOY_OUTP_REG_OFFSET; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return GPIOX_OUTP_REG_OFFSET; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return GPIOY_OUTP_REG_OFFSET; + } + + return -1; +} + +// +// offset to the GPIO Input regsiter +// +static int gpioToGPLEVReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDXU_34) { + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: + return (GPIO_X1_DAT_OFFSET >> 2); + case GPIO_X2_START...GPIO_X2_END: + return (GPIO_X2_DAT_OFFSET >> 2); + case GPIO_X3_START...GPIO_X3_END: + return (GPIO_X3_DAT_OFFSET >> 2); + case GPIO_A0_START...GPIO_A0_END: + return (GPIO_A0_DAT_OFFSET >> 2); + case GPIO_A2_START...GPIO_A2_END: + return (GPIO_A2_DAT_OFFSET >> 2); + case GPIO_B3_START...GPIO_B3_END: + return (GPIO_B3_DAT_OFFSET >> 2); + default: + break; + } + } + else if (piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return C2_GPIOX_INP_REG_OFFSET; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return C2_GPIOY_INP_REG_OFFSET; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return GPIOX_INP_REG_OFFSET; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return GPIOY_INP_REG_OFFSET; + } + + return -1; +} + +// +// offset to the GPIO Pull up/down enable regsiter +// +static int gpioToPUENReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return C2_GPIOX_PUEN_REG_OFFSET; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return C2_GPIOY_PUEN_REG_OFFSET; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return GPIOX_PUEN_REG_OFFSET; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return GPIOY_PUEN_REG_OFFSET; + } + + return -1; +} + +// +// offset to the GPIO Pull up/down regsiter +// +static int gpioToPUPDReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDXU_34) { + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: + return (GPIO_X1_PUD_OFFSET >> 2); + case GPIO_X2_START...GPIO_X2_END: + return (GPIO_X2_PUD_OFFSET >> 2); + case GPIO_X3_START...GPIO_X3_END: + return (GPIO_X3_PUD_OFFSET >> 2); + case GPIO_A0_START...GPIO_A0_END: + return (GPIO_A0_PUD_OFFSET >> 2); + case GPIO_A2_START...GPIO_A2_END: + return (GPIO_A2_PUD_OFFSET >> 2); + case GPIO_B3_START...GPIO_B3_END: + return (GPIO_B3_PUD_OFFSET >> 2); + default: + break; + } + } + else if (piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return C2_GPIOX_PUPD_REG_OFFSET; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return C2_GPIOY_PUPD_REG_OFFSET; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return GPIOX_PUPD_REG_OFFSET; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return GPIOY_PUPD_REG_OFFSET; + } + + return -1; +} + +// +// offset to the GPIO bit +// +static int gpioToShiftReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDXU_34) { + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: + return (pin - GPIO_X1_START); + case GPIO_X2_START...GPIO_X2_END: + return (pin - GPIO_X2_START); + case GPIO_X3_START...GPIO_X3_END: + return (pin - GPIO_X3_START); + case GPIO_A0_START...GPIO_A0_END: + return (pin - GPIO_A0_START); + case GPIO_A2_START...GPIO_A2_END: + return (pin - GPIO_A2_START); + case GPIO_B3_START...GPIO_B3_END: + return (pin - GPIO_B3_START); + default: + break; + } + } + else if (piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return pin - C2_GPIOX_PIN_START; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return pin - C2_GPIOY_PIN_START; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return pin - GPIOX_PIN_START; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return pin - GPIOY_PIN_START; + } + + return -1; +} + +// +// offset to the GPIO Function register +// +static int gpioToGPFSELReg (int pin) +{ + if(piModel == PI_MODEL_ODROIDXU_34) { + switch(pin) { + case GPIO_X1_START...GPIO_X1_END: + return (GPIO_X1_CON_OFFSET >> 2); + case GPIO_X2_START...GPIO_X2_END: + return (GPIO_X2_CON_OFFSET >> 2); + case GPIO_X3_START...GPIO_X3_END: + return (GPIO_X3_CON_OFFSET >> 2); + case GPIO_A0_START...GPIO_A0_END: + return (GPIO_A0_CON_OFFSET >> 2); + case GPIO_A2_START...GPIO_A2_END: + return (GPIO_A2_CON_OFFSET >> 2); + case GPIO_B3_START...GPIO_B3_END: + return (GPIO_B3_CON_OFFSET >> 2); + default: + break; + } + } + else if (piModel == PI_MODEL_ODROIDC2) { + if(pin >= C2_GPIOX_PIN_START && pin <= C2_GPIOX_PIN_END) + return C2_GPIOX_FSEL_REG_OFFSET; + if(pin >= C2_GPIOY_PIN_START && pin <= C2_GPIOY_PIN_END) + return C2_GPIOY_FSEL_REG_OFFSET; + } + else { + if(pin >= GPIOX_PIN_START && pin <= GPIOX_PIN_END) + return GPIOX_FSEL_REG_OFFSET; + if(pin >= GPIOY_PIN_START && pin <= GPIOY_PIN_END) + return GPIOY_FSEL_REG_OFFSET; + } + + return -1; +} + +// +// pinToGpio: +// Take a Wiring pin (0 through X) and re-map it to the ODROID_GPIO pin +// +static int pinToGpioOdroidC [64] = { + 88, 87, 116, 115, 104, 102, 103, 83, // 0..7 + -1, -1, 117, 118, 107, 106, 105, -1, // 8..16 + -1, -1, -1, -1, -1, 101, 100, 108, // 16..23 + 97, -1, 99, 98, -1, -1, -1, -1, // 24..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 +}; + +// +// physToGpio: +// Take a physical pin (1 through 40) and re-map it to the ODROID_GPIO pin +// +static int physToGpioOdroidC [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + -1, -1, + -1, -1, + 83, -1, + -1, -1, + 88, 87, + 116, -1, + 115, 104, + -1, 102, + 107, -1, + 106, 103, + 105, 117, + -1, 118, // 25, 26 + + -1, -1, + 101, -1, + 100, 99, + 108, -1, + 97, 98, + -1, -1, + -1, -1, // 39, 40 + +// Not used + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, +} ; + +// +// pinToGpio: +// Take a Wiring pin (0 through X) and re-map it to the ODROIDC2_GPIO pin +// +static int pinToGpioOdroidC2_Rev1_1 [64] = { + 247, 238, 239, 237, 236, 233, 231, 249, // 0..7 + -1, -1, 229, 225, 235, 232, 230, -1, // 8..15 + -1, -1, -1, -1, -1, 228, 219, 234, // 16..23 + 214, -1, 224, 218, -1, -1, -1, -1, // 24..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 +}; + + +static int pinToGpioOdroidC2_Rev1_0 [64] = { + 219, 218, 247, -1, 235, 233, 234, 214, // 0..7 + -1, -1, 248, 249, 238, 237, 236, -1, // 8..15 + -1, -1, -1, -1, -1, 232, 231, 239, // 16..23 + 228, -1, 230, 229, -1, -1, -1, -1, // 24..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 +}; + +// +// physToGpio: +// Take a physical pin (1 through 40) and re-map it to the ODROIDC2_GPIO pin +// +static int physToGpioOdroidC2_Rev1_1 [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + -1, -1, + -1, -1, + 249, -1, + -1, -1, + 247, 238, + 239, -1, + 237, 236, + -1, 233, + 235, -1, + 232, 231, + 230, 229, + -1, 225, // 25, 26 + + -1, -1, + 228, -1, + 219, 224, + 234, -1, + 214, 218, + -1, -1, + -1, -1, // 39, 40 + +// Not used + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, +} ; + + +static int physToGpioOdroidC2_Rev1_0 [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + -1, -1, + -1, -1, + 214, -1, + -1, -1, + 219, 218, + 247, -1, + -1, 235, + -1, 233, + 238, -1, + 237, 234, + 236, 248, + -1, 249, // 25, 26 + + -1, -1, + 232, -1, + 231, 230, + 239, -1, + 228, 229, + -1, -1, + -1, -1, // 39, 40 + +// Not used + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, +} ; + +// +// pinToGpio: +// Take a Wiring pin (0 through X) and re-map it to the ODROIDXU_GPIO pin +// +static int pinToGpioOdroidXU [64] = { + 174, 173, // 0 | 1 : GPA0.3(UART_0.CTSN), GPA0.2(UART_0.RTSN) + 21, 22, // 2 | 3 : GPX1.5, GPX1.6 + 19, 23, // 4 | 5 : GPX1.3, GPX1.7 + 24, 18, // 6 | 7 : GPX2.0, GPX1.2 + + 209, 210, // 8 | 9 : GPB3.2(I2C_1.SDA), GPB3.3(I2C_1.SCL) + 190, 25, // 10 | 11 : GPA2.5(SPI_1.CSN), GPX2.1 + 192, 191, // 12 | 13 : GPA2.7(SPI_1.MOSI), GPA2.6(SPI_1.MISO) + 189, 172, // 14 | 15 : GPA2.4(SPI_1.SCLK), GPA0.1(UART_0.TXD) + 171, -1, // 16 | 17 : GPA0.0(UART_0.RXD), + -1, -1, // 18 | 19 + -1, 28, // 20 | 21 : , GPX2.4 + 30, 31, // 22 | 23 : GPX2.6, GPX2.7 + -1, -1, // 24 | 25 PWR_ON(INPUT), ADC_0.AIN0 + 29, 33, // 26 | 27 : GPX2.5, GPX3.1 + -1, -1, // 28 | 29 : REF1.8V OUT, ADC_0.AIN3 + 187, 188, // 30 | 31 : GPA2.2(I2C_5.SDA), GPA2.3(I2C_5.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 +}; + +// +// physToGpio: +// Take a physical pin (1 through 40) and re-map it to the ODROIDXU_GPIO pin +// +static int physToGpioOdroidXU [64] = +{ + -1, // 0 + -1, -1, // 1 | 2 : 3.3V, 5.0V + 209, -1, // 3 | 4 : GPB3.2(I2C_1.SDA), 5.0V + 210, -1, // 5 | 6 : GPB3.3(I2C_1.SCL), GND + 18, 172, // 7 | 8 : GPX1.2, GPA0.1(UART_0.TXD) + -1, 171, // 9 | 10 : GND, GPA0.0(UART_0.RXD) + 174, 173, // 11 | 12 : GPA0.3(UART_0.CTSN), GPA0.2(UART_0.RTSN) + 21, -1, // 13 | 14 : GPX1.5, GND + 22, 19, // 15 | 16 : GPX1.6, GPX1.3 + -1, 23, // 17 | 18 : 3.3V, GPX1.7 + 192, -1, // 19 | 20 : GPA2.7(SPI_1.MOSI), GND + 191, 24, // 21 | 22 : GPA2.6(SPI_1.MISO), GPX2.0 + 189, 190, // 23 | 24 : GPA2.4(SPI_1.SCLK), GPA2.5(SPI_1.CSN) + -1, 25, // 25 | 26 : GND, GPX2.1 + 187, 188, // 27 | 28 : GPA2.2(I2C_5.SDA), GPA2.4(I2C_5.SCL) + 28, -1, // 29 | 30 : GPX2.4, GND + 30, 29, // 31 | 32 : GPX2.6, GPX2.5 + 31, -1, // 33 | 34 : GPX2.7, GND + -1, 33, // 35 | 36 : PWR_ON(INPUT), GPX3.1 + -1, -1, // 37 | 38 : ADC_0.AIN0, 1.8V REF OUT + -1, -1, // 39 | 40 : GND, AADC_0.AIN3 + + // 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 +} ; + /* * Functions @@ -596,6 +1193,42 @@ int wiringPiFailure (int fatal, const char *message, ...) return 0 ; } +const char wpi_mode_str[4][20] = { + "WPI_MODE_PINS", + "WPI_MODE_GPIO", + "WPI_MODE_GPIO_SYS", + "WPI_MODE_PHYS", +}; + +void wiringPiGpioCheck (const char *call_func, int origPin, int pin) +{ + if (wiringPiMode == WPI_MODE_PINS || wiringPiMode == WPI_MODE_PHYS) + { + // maybe pin is not gpio. + if ( pin < 0 ) { + (void)wiringPiFailure (WPI_FATAL, + "\n**************** %s ****************\n" \ + "\nCall Function = %s, wiringPiMode = %s\n" \ + "\nError gpio control (OrigPin = %d, pin = %d)\n\n", + __func__, call_func, wpi_mode_str[wiringPiMode], + origPin, pin); + } + } + else { + int i; + for(i = 0; i < 64; i++) { + if (origPin == pinToGpio[i]) break; + } + if (i == 64) { + (void)wiringPiFailure (WPI_FATAL, + "\n**************** %s ****************\n" \ + "\nCall Function = %s, wiringPiMode = %s\n" \ + "\nCannot found gpio pin! (OrigPin = %d)\n\n", + __func__, call_func, wpi_mode_str[wiringPiMode], + origPin); + } + } +} /* * piBoardRev: @@ -623,6 +1256,15 @@ int wiringPiFailure (int fatal, const char *message, ...) * 0011 - Pi CM, Rev 1.2, 512MB, Sony * 0012 - Model A+ Rev 1.2, 256MB, Sony * + * added : + * 000a - Model ODROID C1/C1+, Rev 1.0, 1024M, Hardkernel + * added : + * 0100 - Model ODROID XU3/4, Rev 1.0, 2048M, Hardkernel + * added : + * 02xx - Model ODROID C2, 2048M, Hardkernel + * Rev 1.0 : /sys/class/odroid/boardrev value is 0 (Dev board) + * Rev 1.1 : /sys/class/odroid/boardrev value is 1 (Mass board) + * * A small thorn is the olde style overvolting - that will add in * 1000000 * @@ -703,10 +1345,26 @@ int piBoardRev (void) if (wiringPiDebug) printf ("piboardRev: last4Chars are: \"%s\"\n", c) ; - if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0)) - boardRev = 1 ; + if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0) || + (strcmp (c, "000a") == 0) || (strcmp (c, "0100") == 0) ) + boardRev = 1; else - boardRev = 2 ; + boardRev = 2; + + if (strncmp (c, "02", 2) == 0) { + int fd = 0; + char buf[2]; + + if ((fd = open ("/sys/class/odroid/boardrev", O_RDONLY)) < 0) { + printf ("ERROR : file not found.(boardrev)\n"); + boardRev = 1; + } + else { + read (fd, buf, sizeof(buf)); + close(fd); + boardRev = atoi(buf) + 1; + } + } if (wiringPiDebug) printf ("piBoardRev: Returning revision: %d\n", boardRev) ; @@ -787,9 +1445,21 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; } else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY ; } else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 256 ; *maker = PI_MAKER_SONY ; } - else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } + else if (strcmp (c, "000a") == 0) { + *model = PI_MODEL_ODROIDC; *rev = PI_VERSION_1; *mem = 1024; *maker = PI_MAKER_HARDKERNEL; + } + else if (strcmp (c, "0100") == 0) { + *model = PI_MODEL_ODROIDXU_34; *rev = PI_VERSION_1; *mem = 2048; *maker = PI_MAKER_HARDKERNEL; + } + else if (strncmp (c, "02", 2) == 0) { + *model = PI_MODEL_ODROIDC2; *mem = 2048; *maker = PI_MAKER_HARDKERNEL; + *rev = piBoardRev (); + } + else { + *model = 0; *rev = 0; *mem = 0; *maker = 0 ; + } + piModel = *model; } - /* @@ -828,6 +1498,14 @@ void setPadDrive (int group, int value) { uint32_t wrVal ; + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if ((group < 0) || (group > 2)) @@ -856,7 +1534,12 @@ int getAlt (int pin) { int fSel, shift, alt ; - pin &= 63 ; + if ( piModel == PI_MODEL_ODROIDC ) + pin &= 0x7F; + else if( piModel == PI_MODEL_ODROIDXU_34 || piModel == PI_MODEL_ODROIDC2 ) + pin &= 0xFF; + else + pin &= 63 ; /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; @@ -865,12 +1548,35 @@ int getAlt (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return 0 ; - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; + if ( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) { + + if(pin < 0) return 2; // ALT + + return (*(gpio + gpioToGPFSELReg(pin)) & (1 << gpioToShiftReg(pin))) ? 0 : 1; + } + else if ( piModel == PI_MODEL_ODROIDXU_34 ) { + + if(pin < 0) return 2; // ALT + + shift = (gpioToShiftReg(pin) * 4); + + if(pin < 100) // GPX0,1,2,3 + fSel = (*(gpio + gpioToGPFSELReg(pin)) & (0xF << shift)); + else // GPA0,1,2, GPB0,1,2,3,4 + fSel = (*(gpio1 + gpioToGPFSELReg(pin)) & (0xF << shift)); + + if(fSel & (0xE << shift)) return 2; + + return (fSel & (0x1 << shift)) ? 1 : 0; + } + else { + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; - alt = (*(gpio + fSel) >> shift) & 7 ; + alt = (*(gpio + fSel) >> shift) & 7 ; - return alt ; + return alt ; + } } @@ -882,6 +1588,14 @@ int getAlt (int pin) void pwmSetMode (int mode) { + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if (mode == PWM_MODE_MS) @@ -901,6 +1615,14 @@ void pwmSetMode (int mode) void pwmSetRange (unsigned int range) { + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; @@ -922,10 +1644,18 @@ void pwmSetClock (int divisor) uint32_t pwm_control ; divisor &= 4095 ; + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if (wiringPiDebug) - printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)); pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL @@ -952,7 +1682,7 @@ void pwmSetClock (int divisor) *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL if (wiringPiDebug) - printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)); } } @@ -967,6 +1697,14 @@ void gpioClockSet (int pin, int freq) { int divi, divr, divf ; + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + pin &= 63 ; /**/ if (wiringPiMode == WPI_MODE_PINS) @@ -1031,13 +1769,23 @@ 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) ; + if ( piModel == PI_MODEL_ODROIDC ) { + // Minimum pin base is 128 + if (pinBase < 128) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 128\n", pinBase) ; + } + else if ( piModel == PI_MODEL_ODROIDXU_34 || piModel == PI_MODEL_ODROIDC2 ) { + // Minimum pin base is 256 + if (pinBase < 256) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 256\n", pinBase) ; + } + else { + // 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) ; @@ -1094,6 +1842,14 @@ void pinModeAlt (int pin, int mode) { int fSel, shift ; + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if ((pin & PI_GPIO_MASK) == 0) // On-board pin { /**/ if (wiringPiMode == WPI_MODE_PINS) @@ -1122,8 +1878,13 @@ void pinMode (int pin, int mode) int fSel, shift, alt ; struct wiringPiNodeStruct *node = wiringPiNodes ; int origPin = pin ; + unsigned int gpio_mask = PI_GPIO_MASK; - if ((pin & PI_GPIO_MASK) == 0) // On-board pin + if ( piModel == PI_MODEL_ODROIDC ) gpio_mask = ODROIDC_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDC2 ) gpio_mask = ODROIDC2_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDXU_34 ) gpio_mask = ODROIDXU_GPIO_MASK; + + if ((pin & gpio_mask) == 0) // On-board pin { /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; @@ -1132,29 +1893,79 @@ void pinMode (int pin, int mode) else if (wiringPiMode != WPI_MODE_GPIO) return ; + wiringPiGpioCheck (__func__, origPin, pin); + softPwmStop (origPin) ; softToneStop (origPin) ; fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == SOFT_PWM_OUTPUT) - softPwmCreate (origPin, 0, 100) ; - else if (mode == SOFT_TONE_OUTPUT) - softToneCreate (origPin) ; + if (mode == INPUT) { + if ( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) + *(gpio + gpioToGPFSELReg(pin)) = (*(gpio + gpioToGPFSELReg(pin)) | (1 << gpioToShiftReg(pin))); + else if ( piModel == PI_MODEL_ODROIDXU_34 ) { + shift = (gpioToShiftReg(pin) * 4); + if(pin < 100) + *(gpio + gpioToGPFSELReg(pin)) &= ~(0xF << shift); + else + *(gpio1 + gpioToGPFSELReg(pin)) &= ~(0xF << shift); + } + else + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)); // Sets bits to zero = input + } + else if (mode == OUTPUT) { + if ( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) + *(gpio + gpioToGPFSELReg(pin)) = (*(gpio + gpioToGPFSELReg(pin)) & ~(1 << gpioToShiftReg(pin))); + else if ( piModel == PI_MODEL_ODROIDXU_34 ) { + shift = (gpioToShiftReg(pin) * 4); + if(pin < 100) { + *(gpio + gpioToGPFSELReg(pin)) &= ~(0xF << shift); + *(gpio + gpioToGPFSELReg(pin)) |= (0x1 << shift); + } + else { + *(gpio1 + gpioToGPFSELReg(pin)) &= ~(0xF << shift); + *(gpio1 + gpioToGPFSELReg(pin)) |= (0x1 << shift); + } + } + else + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift); + } + else if (mode == SOFT_PWM_OUTPUT) { + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) + softPwmCreate (pin, 0, 100); + else + softPwmCreate (origPin, 0, 100); + } + else if (mode == SOFT_TONE_OUTPUT) { + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) + softToneCreate (pin); + else + softToneCreate (origPin); + } else if (mode == PWM_TONE_OUTPUT) { + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) + return; + pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode pwmSetMode (PWM_MODE_MS) ; } else if (mode == PWM_OUTPUT) { + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) + return; + if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin - return ; + return ; // Set pin to PWM mode @@ -1167,8 +1978,13 @@ void pinMode (int pin, int mode) } else if (mode == GPIO_CLOCK) { + if (piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) + return; + if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin - return ; + return ; // Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz @@ -1198,8 +2014,14 @@ void pinMode (int pin, int mode) void pullUpDnControl (int pin, int pud) { struct wiringPiNodeStruct *node = wiringPiNodes ; + unsigned int gpio_mask = PI_GPIO_MASK; + int origPin = pin; + + if ( piModel == PI_MODEL_ODROIDC ) gpio_mask = ODROIDC_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDC2 ) gpio_mask = ODROIDC2_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDXU_34 ) gpio_mask = ODROIDXU_GPIO_MASK; - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + if ((pin & gpio_mask) == 0) // On-Board Pin { /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; @@ -1208,13 +2030,60 @@ void pullUpDnControl (int pin, int pud) else if (wiringPiMode != WPI_MODE_GPIO) return ; - *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; - - *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + wiringPiGpioCheck (__func__, origPin, pin); + + if( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) { + + if(pud) { + // Enable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = (*(gpio + gpioToPUENReg(pin)) | (1 << gpioToShiftReg(pin))); + + if(pud == PUD_UP) + *(gpio + gpioToPUPDReg(pin)) = (*(gpio + gpioToPUPDReg(pin)) | (1 << gpioToShiftReg(pin))); + else + *(gpio + gpioToPUPDReg(pin)) = (*(gpio + gpioToPUPDReg(pin)) & ~(1 << gpioToShiftReg(pin))); + } + else // Disable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = (*(gpio + gpioToPUENReg(pin)) & ~(1 << gpioToShiftReg(pin))); + } + else if ( piModel == PI_MODEL_ODROIDXU_34) { + int shift = 0; + + shift = (gpioToShiftReg(pin) * 2); + + if(pud) { + if(pin < 100) { + *(gpio + gpioToPUPDReg(pin)) &= ~(0x3 << shift); + if(pud == PUD_UP) + *(gpio + gpioToPUPDReg(pin)) |= (0x3 << shift); + else + *(gpio + gpioToPUPDReg(pin)) |= (0x1 << shift); + } + else { + *(gpio1 + gpioToPUPDReg(pin)) &= ~(0x3 << shift); + if(pud == PUD_UP) + *(gpio1 + gpioToPUPDReg(pin)) |= (0x3 << shift); + else + *(gpio1 + gpioToPUPDReg(pin)) |= (0x1 << shift); + } + } + else { + // Disable Pull/Pull-down resister + if(pin < 100) + *(gpio + gpioToPUPDReg(pin)) &= ~(0x3 << shift); + else + *(gpio1 + gpioToPUPDReg(pin)) &= ~(0x3 << shift); + } + } + else { + *(gpio + GPPUD) = pud & 3; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31); delayMicroseconds (5) ; + + *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + } } - else // Extension module + else // Extension module { if ((node = wiringPiFindNode (pin)) != NULL) node->pullUpDnControl (node, pin, pud) ; @@ -1233,16 +2102,24 @@ int digitalRead (int pin) { char c ; struct wiringPiNodeStruct *node = wiringPiNodes ; + unsigned int gpio_mask = PI_GPIO_MASK; + int origPin = pin; + + if ( piModel == PI_MODEL_ODROIDC ) gpio_mask = ODROIDC_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDC2 ) gpio_mask = ODROIDC2_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDXU_34 ) gpio_mask = ODROIDXU_GPIO_MASK; - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + if ((pin & gpio_mask) == 0) // On-Board Pin { /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode { - if (sysFds [pin] == -1) - return LOW ; + int fd_pos = gpioToPin(pin); + + if ( sysFds [fd_pos] == -1) + return LOW ; - lseek (sysFds [pin], 0L, SEEK_SET) ; - read (sysFds [pin], &c, 1) ; + lseek (sysFds [fd_pos], 0L, SEEK_SET) ; + read (sysFds [fd_pos], &c, 1) ; return (c == '0') ? LOW : HIGH ; } else if (wiringPiMode == WPI_MODE_PINS) @@ -1252,10 +2129,26 @@ int digitalRead (int pin) else if (wiringPiMode != WPI_MODE_GPIO) return LOW ; - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; + wiringPiGpioCheck (__func__, origPin, pin); + + if ( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) { + if ((*(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin))) != 0) + return HIGH ; + else + return LOW ; + } + else if ( piModel == PI_MODEL_ODROIDXU_34 ) { + if (pin < 100) + return *(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : LOW; + else + return *(gpio1 + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : LOW; + } + else { + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) + return HIGH ; + else + return LOW ; + } } else { @@ -1275,17 +2168,25 @@ int digitalRead (int pin) void digitalWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; + unsigned int gpio_mask = PI_GPIO_MASK; + int origPin = pin; - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + if ( piModel == PI_MODEL_ODROIDC ) gpio_mask = ODROIDC_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDC2 ) gpio_mask = ODROIDC2_GPIO_MASK; + if ( piModel == PI_MODEL_ODROIDXU_34 ) gpio_mask = ODROIDXU_GPIO_MASK; + + if ((pin & gpio_mask) == 0) // On-Board Pin { /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode { - if (sysFds [pin] != -1) + int fd_pos = gpioToPin(pin); + + if (sysFds [fd_pos] != -1) { - if (value == LOW) - write (sysFds [pin], "0\n", 2) ; - else - write (sysFds [pin], "1\n", 2) ; + if (value == LOW) + write (sysFds [fd_pos], "0\n", 2) ; + else + write (sysFds [fd_pos], "1\n", 2) ; } return ; } @@ -1296,15 +2197,33 @@ void digitalWrite (int pin, int value) else if (wiringPiMode != WPI_MODE_GPIO) return ; - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; - else - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; + wiringPiGpioCheck (__func__, origPin, pin); + + if ( piModel == PI_MODEL_ODROIDC || piModel == PI_MODEL_ODROIDC2 ) { + if (value == LOW) + *(gpio + gpioToGPSETReg(pin)) &= ~(1 << gpioToShiftReg(pin)); + else + *(gpio + gpioToGPSETReg(pin)) |= (1 << gpioToShiftReg(pin)); + } + else if ( piModel == PI_MODEL_ODROIDXU_34 ) { + if (pin < 100) { + if (value == LOW) + *(gpio + gpioToGPLEVReg(pin)) &= ~(1 << gpioToShiftReg(pin)); + else + *(gpio + gpioToGPLEVReg(pin)) |= (1 << gpioToShiftReg(pin)); + } + else { + if (value == LOW) + *(gpio1 + gpioToGPLEVReg(pin)) &= ~(1 << gpioToShiftReg(pin)); + else + *(gpio1 + gpioToGPLEVReg(pin)) |= (1 << gpioToShiftReg(pin)); + } + } } else { if ((node = wiringPiFindNode (pin)) != NULL) - node->digitalWrite (node, pin, value) ; + node->digitalWrite (node, pin, value) ; } } @@ -1318,8 +2237,17 @@ void digitalWrite (int pin, int value) void pwmWrite (int pin, int value) { struct wiringPiNodeStruct *node = wiringPiNodes ; + unsigned int gpio_mask = PI_GPIO_MASK; + + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + if ((pin & gpio_mask) == 0) // On-Board Pin { /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; @@ -1349,6 +2277,19 @@ void pwmWrite (int pin, int value) int analogRead (int pin) { struct wiringPiNodeStruct *node = wiringPiNodes ; + unsigned char value[5] = {0,}; + + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34 ) { + if(pin < 2) { + if (adcFds [pin] == -1) + return 0; + lseek (adcFds [pin], 0L, SEEK_SET); + read (adcFds [pin], &value[0], 4); + return atoi(value); + } + } if ((node = wiringPiFindNode (pin)) == NULL) return 0 ; @@ -1387,6 +2328,14 @@ void pwmToneWrite (int pin, int freq) { int range ; + if ( piModel == PI_MODEL_ODROIDC || + piModel == PI_MODEL_ODROIDC2 || + piModel == PI_MODEL_ODROIDXU_34) { + fprintf (stderr, "%s : Unsupport function on %s model\n", + __func__, piModelNames [piModel]); + exit (EXIT_FAILURE) ; + } + if (freq == 0) pwmWrite (pin, 0) ; // Off else @@ -1410,6 +2359,130 @@ void pwmToneWrite (int pin, int freq) ********************************************************************************* */ +union reg_bitfield { + unsigned int wvalue; + struct { + unsigned int bit0 : 1; + unsigned int bit1 : 1; + unsigned int bit2 : 1; + unsigned int bit3 : 1; + unsigned int bit4 : 1; + unsigned int bit5 : 1; + unsigned int bit6 : 1; + unsigned int bit7 : 1; + unsigned int bit8 : 1; + unsigned int bit9 : 1; + unsigned int bit10 : 1; + unsigned int bit11 : 1; + unsigned int bit12 : 1; + unsigned int bit13 : 1; + unsigned int bit14 : 1; + unsigned int bit15 : 1; + unsigned int bit16 : 1; + unsigned int bit17 : 1; + unsigned int bit18 : 1; + unsigned int bit19 : 1; + unsigned int bit20 : 1; + unsigned int bit21 : 1; + unsigned int bit22 : 1; + unsigned int bit23 : 1; + unsigned int bit24 : 1; + unsigned int bit25 : 1; + unsigned int bit26 : 1; + unsigned int bit27 : 1; + unsigned int bit28 : 1; + unsigned int bit29 : 1; + unsigned int bit30 : 1; + unsigned int bit31 : 1; + } bits; +}; + +void digitalWriteByte_XU(int value) +{ + union reg_bitfield gpx1, gpx2, gpa0; + + /* Read data register */ + gpx1.wvalue = *(gpio + (GPIO_X1_DAT_OFFSET >> 2)); + gpx2.wvalue = *(gpio + (GPIO_X2_DAT_OFFSET >> 2)); + gpa0.wvalue = *(gpio1 + (GPIO_A0_DAT_OFFSET >> 2)); + + /* Wiring PI GPIO0 = XU3/4 GPA0.3 */ + gpa0.bits.bit3 = (value & 0x01); + /* Wiring PI GPIO1 = XU3/4 GPA0.2 */ + gpa0.bits.bit2 = (value & 0x02); + /* Wiring PI GPIO2 = XU3/4 GPX1.5 */ + gpx1.bits.bit5 = (value & 0x04); + /* Wiring PI GPIO3 = XU3/4 GPX1.6 */ + gpx1.bits.bit6 = (value & 0x08); + /* Wiring PI GPIO4 = XU3/4 GPX1.3 */ + gpx1.bits.bit3 = (value & 0x10); + /* Wiring PI GPIO5 = XU3/4 GPX1.7 */ + gpx1.bits.bit7 = (value & 0x20); + /* Wiring PI GPIO6 = XU3/4 GPX2.0 */ + gpx2.bits.bit0 = (value & 0x40); + /* Wiring PI GPIO7 = XU3/4 GPX1.2 */ + gpx1.bits.bit2 = (value & 0x80); + + /* update data register */ + *(gpio + (GPIO_X1_DAT_OFFSET >> 2)) = gpx1.wvalue; + *(gpio + (GPIO_X2_DAT_OFFSET >> 2)) = gpx2.wvalue; + *(gpio1 + (GPIO_A0_DAT_OFFSET >> 2)) = gpa0.wvalue; +} + +void digitalWriteByte_C(int value) +{ + union reg_bitfield gpiox, gpioy; + + gpiox.wvalue = *(gpio + GPIOX_INP_REG_OFFSET); + gpioy.wvalue = *(gpio + GPIOY_INP_REG_OFFSET); + + /* Wiring PI GPIO0 = C1 GPIOY.8 */ + gpioy.bits.bit8 = (value & 0x01); + /* Wiring PI GPIO1 = C1 GPIOY.7 */ + gpioy.bits.bit7 = (value & 0x02); + /* Wiring PI GPIO2 = C1 GPIOX.19 */ + gpiox.bits.bit19 = (value & 0x04); + /* Wiring PI GPIO3 = C1 GPIOX.18 */ + gpiox.bits.bit18 = (value & 0x08); + /* Wiring PI GPIO4 = C1 GPIOX.7 */ + gpiox.bits.bit7 = (value & 0x10); + /* Wiring PI GPIO5 = C1 GPIOX.5 */ + gpiox.bits.bit5 = (value & 0x20); + /* Wiring PI GPIO6 = C1 GPIOX.6 */ + gpiox.bits.bit6 = (value & 0x40); + /* Wiring PI GPIO7 = C1 GPIOY.3 */ + gpioy.bits.bit3 = (value & 0x80); + + *(gpio + GPIOX_OUTP_REG_OFFSET) = gpiox.wvalue; + *(gpio + GPIOY_OUTP_REG_OFFSET) = gpioy.wvalue; +} + +void digitalWriteByte_C2(int value) +{ + union reg_bitfield gpiox; + + gpiox.wvalue = *(gpio + C2_GPIOX_INP_REG_OFFSET); + + /* Wiring PI GPIO0 = C1 GPIOX.19 */ + gpiox.bits.bit19 = (value & 0x01); + /* Wiring PI GPIO1 = C1 GPIOX.10 */ + gpiox.bits.bit10 = (value & 0x02); + /* Wiring PI GPIO2 = C1 GPIOX.11 */ + gpiox.bits.bit11 = (value & 0x04); + /* Wiring PI GPIO3 = C1 GPIOX.9 */ + gpiox.bits.bit9 = (value & 0x08); + /* Wiring PI GPIO4 = C1 GPIOX.8 */ + gpiox.bits.bit8 = (value & 0x10); + /* Wiring PI GPIO5 = C1 GPIOX.5 */ + gpiox.bits.bit5 = (value & 0x20); + /* Wiring PI GPIO6 = C1 GPIOX.3 */ + gpiox.bits.bit3 = (value & 0x40); + /* Wiring PI GPIO7 = C1 GPIOX.21 */ + gpiox.bits.bit21 = (value & 0x80); + + *(gpio + C2_GPIOX_OUTP_REG_OFFSET) = gpiox.wvalue; +} + void digitalWriteByte (int value) { uint32_t pinSet = 0 ; @@ -1421,19 +2494,32 @@ void digitalWriteByte (int value) { for (pin = 0 ; pin < 8 ; ++pin) { - digitalWrite (pin, value & mask) ; + digitalWrite (pinToGpio[pin], value & mask) ; mask <<= 1 ; } return ; } else { + switch(piModel) { + case PI_MODEL_ODROIDC: + digitalWriteByte_C(value); + return; + case PI_MODEL_ODROIDC2: + digitalWriteByte_C2(value); + return; + case PI_MODEL_ODROIDXU_34: + digitalWriteByte_XU(value); + return; + default : + break; + } for (pin = 0 ; pin < 8 ; ++pin) { if ((value & mask) == 0) - pinClr |= (1 << pinToGpio [pin]) ; + pinClr |= (1 << pinToGpio [pin]) ; else - pinSet |= (1 << pinToGpio [pin]) ; + pinSet |= (1 << pinToGpio [pin]) ; mask <<= 1 ; } @@ -1454,27 +2540,23 @@ void digitalWriteByte (int value) ********************************************************************************* */ + int waitForInterrupt (int pin, int mS) { int fd, x ; uint8_t c ; struct pollfd polls ; - /**/ if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; - else if (wiringPiMode == WPI_MODE_PHYS) - pin = physToGpio [pin] ; + if ((fd = sysFds [pin]) == -1) + return -2 ; - if ((fd = sysFds [pin]) == -1) - return -2 ; + // Setup poll structure + polls.fd = fd ; + polls.events = POLLPRI ; // Urgent data! -// Setup poll structure - - polls.fd = fd ; - polls.events = POLLPRI ; // Urgent data! // Wait for it ... - +wait: x = poll (&polls, 1, mS) ; // Do a dummy read to clear the interrupt @@ -1505,9 +2587,9 @@ static void *interruptHandler (void *arg) myPin = pinPass ; pinPass = -1 ; - for (;;) - if (waitForInterrupt (myPin, -1) > 0) - isrFunctions [myPin] () ; + for (;;) + if (waitForInterrupt (myPin, -1) > 0) + isrFunctions [myPin] () ; return NULL ; } @@ -1532,18 +2614,28 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) char c ; int bcmGpioPin ; - 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] ; + bcmGpioPin = pinToGpio [pin & 63] ; else if (wiringPiMode == WPI_MODE_PHYS) - bcmGpioPin = physToGpio [pin] ; + bcmGpioPin = physToGpio [pin & 63] ; else bcmGpioPin = pin ; + if ( piModel == PI_MODEL_ODROIDC ) { + if ((pin < 0) || (pin > 128)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-128 (%d)\n", pin) ; + } + else if ( piModel == PI_MODEL_ODROIDXU_34 || piModel == PI_MODEL_ODROIDC2 ) { + if ((pin < 0) || (pin > 256)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-256 (%d)\n", pin) ; + } + else { + if ((pin < 0) || (pin > 63)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", 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 @@ -1568,16 +2660,16 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) { /**/ 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)) ; + 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)) ; + 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") ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: Can't find gpio program\n") ; } else // Parent, wait wait (NULL) ; @@ -1586,20 +2678,22 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) // 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)) ; - } + if (sysFds [pin] == -1) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; + + if ((sysFds [pin] = open (fName, O_RDWR)) < 0) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; + sysFdIrqType [pin] = mode; + } -// Clear any initial pending interrupt + // Clear any initial pending interrupt - ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ; - for (i = 0 ; i < count ; ++i) - read (sysFds [bcmGpioPin], &c, 1) ; + ioctl (sysFds [pin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i) + read (sysFds [pin], &c, 1) ; - isrFunctions [pin] = function ; + isrFunctions [pin] = function ; pthread_mutex_lock (&pinMutex) ; pinPass = pin ; @@ -1755,53 +2849,138 @@ int wiringPiSetup (void) if (getenv (ENV_CODES) != NULL) wiringPiReturnCodes = TRUE ; - if (geteuid () != 0) - (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ; + // Open the master /dev/memory device + if (access("/dev/gpiomem",0) == 0) { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", strerror (errno)) ; + } + else { + if (geteuid () != 0) + (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ; + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + } if (wiringPiDebug) printf ("wiringPi: wiringPiSetup called\n") ; - boardRev = piBoardRev () ; + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - /**/ if (boardRev == 1) // A, B, Rev 1, 1.1 - { - pinToGpio = pinToGpioR1 ; - physToGpio = physToGpioR1 ; + if ( model == PI_MODEL_ODROIDC ) { + + pinToGpio = pinToGpioOdroidC; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC); + physToGpio = physToGpioOdroidC; + + // GPIO: + + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ODROID_GPIO_BASE) ; + if ((int32_t)gpio == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + + // ADC + // ADC sysfs open (/sys/class/saradc/saradc_ch0, ch1) + adcFds [0] = open (piAinNode0, O_RDONLY) ; + adcFds [1] = open (piAinNode1, O_RDONLY) ; } - else // A, B, Rev 2, B+, CM - { - pinToGpio = pinToGpioR2 ; - physToGpio = physToGpioR2 ; + else if ( model == PI_MODEL_ODROIDC2 ) { + + if(rev == PI_VERSION_1) { + pinToGpio = pinToGpioOdroidC2_Rev1_0; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC2_Rev1_0); + physToGpio = physToGpioOdroidC2_Rev1_0; + } + else { + pinToGpio = pinToGpioOdroidC2_Rev1_1; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC2_Rev1_1); + physToGpio = physToGpioOdroidC2_Rev1_1; + } + + // GPIO: + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ODROIDC2_GPIO_BASE) ; + if ((int32_t)gpio == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + + // ADC + // ADC sysfs open (/sys/class/saradc/saradc_ch0, ch1) + adcFds [0] = open (C2_piAinNode0, O_RDONLY) ; + adcFds [1] = open (C2_piAinNode1, O_RDONLY) ; } + else if ( model == PI_MODEL_ODROIDXU_34 ) { + // Check the kernel version and then set the ADC files + struct utsname uname_buf; + + uname(&uname_buf); + if (strncmp(uname_buf.release, "4.14", 4) == 0) { + piAinNode0_xu = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage3_raw"; + } else if (strncmp(uname_buf.release, "4.9", 3) == 0) { + piAinNode0_xu = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage3_raw"; + } else { // 3.10 kernel + piAinNode0_xu = "/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/12d10000.adc/iio:device0/in_voltage3_raw"; + } + + pinToGpio = pinToGpioOdroidXU; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidXU); + physToGpio = physToGpioOdroidXU; + + // GPIO: + //#define ODROIDXU_GPX_BASE 0x13400000 // GPX0,1,2,3 + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ODROIDXU_GPX_BASE) ; + if ((int32_t)gpio == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + + //#define ODROIDXU_GPA_BASE 0x14010000 // GPA0,1,2, GPB0,1,2,3,4 + gpio1 = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ODROIDXU_GPA_BASE) ; + if ((int32_t)gpio1 == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + + // ADC + // ADC Fds[0] = ("/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw") + // ADC Fds[1] = ("/sys/devices/12d10000.adc/iio:device0/in_voltage3_raw") + adcFds [0] = open (piAinNode0_xu, O_RDONLY) ; + adcFds [1] = open (piAinNode1_xu, O_RDONLY) ; + } + else { + // GPIO: + boardRev = piBoardRev () ; -// Open the master /dev/memory device + /**/ if (boardRev == 1) // A, B, Rev 1, 1.1 + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } + else // A, B, Rev 2, B+, CM + { + pinToGpio = pinToGpioR2 ; + physToGpio = physToGpioR2 ; + } - if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; + if ((int32_t)gpio == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; -// GPIO: + // PWM - gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; - if ((int32_t)gpio == -1) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; + if ((int32_t)pwm == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; -// PWM + // Clock control (needed for PWM) - pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; - if ((int32_t)pwm == -1) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; - -// Clock control (needed for PWM) + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; + if ((int32_t)clk == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; - clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; - if ((int32_t)clk == -1) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; - -// The drive pads + // The drive pads - pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; - if ((int32_t)pads == -1) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; + pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; + if ((int32_t)pads == -1) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; + } #ifdef USE_TIMER // The system timer @@ -1823,7 +3002,6 @@ int wiringPiSetup (void) // If we're running on a compute module, then wiringPi pin numbers don't really many anything... - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; if (model == PI_MODEL_CM) wiringPiMode = WPI_MODE_GPIO ; else @@ -1889,7 +3067,8 @@ int wiringPiSetupPhys (void) int wiringPiSetupSys (void) { int boardRev ; - int pin ; + int model, rev, mem, maker, overVolted ; + int pin, offset; char fName [128] ; if (getenv (ENV_DEBUG) != NULL) @@ -1901,27 +3080,69 @@ int wiringPiSetupSys (void) if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; - boardRev = piBoardRev () ; + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if (boardRev == 1) - { - pinToGpio = pinToGpioR1 ; - physToGpio = physToGpioR1 ; + if ( model == PI_MODEL_ODROIDC ) { + pinToGpio = pinToGpioOdroidC ; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC); + physToGpio = physToGpioOdroidC ; + + // ADC sysfs open (/sys/class/saradc/saradc_ch0, ch1) + + adcFds [0] = open (piAinNode0, O_RDONLY) ; + adcFds [1] = open (piAinNode1, O_RDONLY) ; } - else - { - pinToGpio = pinToGpioR2 ; - physToGpio = physToGpioR2 ; + else if ( model == PI_MODEL_ODROIDC2 ) { + if(rev == PI_VERSION_1) { + pinToGpio = pinToGpioOdroidC2_Rev1_0; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC2_Rev1_0); + physToGpio = physToGpioOdroidC2_Rev1_0; + } + else { + pinToGpio = pinToGpioOdroidC2_Rev1_1; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidC2_Rev1_1); + physToGpio = physToGpioOdroidC2_Rev1_1; + } + + // ADC sysfs open (/sys/class/saradc/saradc_ch0, ch1) + + adcFds [0] = open (C2_piAinNode0, O_RDONLY) ; + adcFds [1] = open (C2_piAinNode1, O_RDONLY) ; + } + else if ( model == PI_MODEL_ODROIDXU_34 ) { + // Check the kernel version and then set the ADC files + struct utsname uname_buf; + + uname(&uname_buf); + if (strncmp(uname_buf.release, "4.14", 4) == 0) { + piAinNode0_xu = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage3_raw"; + } else if (strncmp(uname_buf.release, "4.9", 3) == 0) { + piAinNode0_xu = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage3_raw"; + } else { // 3.10 kernel + piAinNode0_xu = "/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw"; + piAinNode1_xu = "/sys/devices/12d10000.adc/iio:device0/in_voltage3_raw"; + } + + pinToGpio = pinToGpioOdroidXU ; + pin_array_count = ARRAY_SIZE(pinToGpioOdroidXU); + physToGpio = physToGpioOdroidXU ; + + // ADC + // ADC Fds[0] = ("/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw") + // ADC Fds[1] = ("/sys/devices/12d10000.adc/iio:device0/in_voltage3_raw") + adcFds [0] = open (piAinNode0_xu, O_RDONLY) ; + adcFds [1] = open (piAinNode1_xu, O_RDONLY) ; } // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later - - for (pin = 0 ; pin < 64 ; ++pin) - { - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - sysFds [pin] = open (fName, O_RDWR) ; - } + for (pin = 0 ; pin < 64 ; ++pin) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", pinToGpio[pin]) ; + sysFds [pin] = open (fName, O_RDWR) ; + } initialiseEpoch () ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h old mode 100644 new mode 100755 index 42265fc..6346154 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -70,27 +70,31 @@ // Pi model types and version numbers // Intended for the GPIO program Use at your own risk. -#define PI_MODEL_UNKNOWN 0 -#define PI_MODEL_A 1 -#define PI_MODEL_B 2 -#define PI_MODEL_BP 3 -#define PI_MODEL_CM 4 -#define PI_MODEL_AP 5 +#define PI_MODEL_UNKNOWN 0 +#define PI_MODEL_A 1 +#define PI_MODEL_B 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_CM 4 +#define PI_MODEL_AP 5 +#define PI_MODEL_ODROIDC 6 +#define PI_MODEL_ODROIDXU_34 7 +#define PI_MODEL_ODROIDC2 8 #define PI_VERSION_UNKNOWN 0 -#define PI_VERSION_1 1 -#define PI_VERSION_1_1 2 -#define PI_VERSION_1_2 3 -#define PI_VERSION_2 4 - -#define PI_MAKER_UNKNOWN 0 -#define PI_MAKER_EGOMAN 1 -#define PI_MAKER_SONY 2 -#define PI_MAKER_QISDA 3 - -extern const char *piModelNames [6] ; +#define PI_VERSION_1 1 +#define PI_VERSION_1_1 2 +#define PI_VERSION_1_2 3 +#define PI_VERSION_2 4 + +#define PI_MAKER_UNKNOWN 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_SONY 2 +#define PI_MAKER_QISDA 3 +#define PI_MAKER_HARDKERNEL 4 + +extern const char *piModelNames [9] ; extern const char *piRevisionNames [5] ; -extern const char *piMakerNames [4] ; +extern const char *piMakerNames [5] ; // Intended for the GPIO program Use at your own risk. diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c old mode 100644 new mode 100755 index c787bce..2a12116 --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -218,15 +218,23 @@ int wiringPiI2CSetupInterface (const char *device, int devId) int wiringPiI2CSetup (const int devId) { - int rev ; const char *device ; + int model, rev, mem, maker, overVolted ; - rev = piBoardRev () ; + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if (rev == 1) - device = "/dev/i2c-0" ; - else + if ( model == PI_MODEL_ODROIDC || model == PI_MODEL_ODROIDC2 ) device = "/dev/i2c-1" ; + else if ( model == PI_MODEL_ODROIDXU_34 ) + device = "/dev/i2c-4" ; /* update 2016/feb/12 Linux */ + else { + rev = piBoardRev () ; + + if (rev == 1) + device = "/dev/i2c-0" ; + else + device = "/dev/i2c-1" ; + } return wiringPiI2CSetupInterface (device, devId) ; } diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c old mode 100644 new mode 100755 index 215a027..749045c --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -40,6 +40,7 @@ const static char *spiDev0 = "/dev/spidev0.0" ; const static char *spiDev1 = "/dev/spidev0.1" ; +const static char *spiDev0_XU = "/dev/spidev1.0"; const static uint8_t spiMode = 0 ; const static uint8_t spiBPW = 8 ; const static uint16_t spiDelay = 0 ; @@ -95,11 +96,33 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) int wiringPiSPISetup (int channel, int speed) { int fd ; + int model, rev, mem, maker, overVolted ; + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; channel &= 1 ; - if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) - return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; + if (model == PI_MODEL_ODROIDXU_34) { + if (channel) + return wiringPiFailure (WPI_ALMOST, "ODROID-XU3/4 cannot support spi-channel 1.\n") ; + + if ((fd = open (spiDev0_XU, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; + } + else if (model == PI_MODEL_ODROIDC) { + if (channel) + return wiringPiFailure (WPI_ALMOST, "ODROID-C1/C1+ cannot support spi-channel 1.\n") ; + + if ((fd = open (spiDev0, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; + } + else if (model == PI_MODEL_ODROIDC2) { + return wiringPiFailure (WPI_ALMOST, "ODROID-C2 cannot support spi-channel\n") ; + } + else { + if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; + } spiSpeeds [channel] = speed ; spiFds [channel] = fd ;