Files
wiringPi/wiringPi/odroidxu3.c
Deokgyu Yang 6f11fefcff WiringPi: Remove utsname things from each board's file
Signed-off-by: Deokgyu Yang <secugyu@gmail.com>
Change-Id: I3b4be4eac57c31867a1a1b380eef26b0866da903
2020-08-20 18:28:45 +09:00

758 lines
21 KiB
C

/*----------------------------------------------------------------------------*/
//
//
// WiringPi ODROID-XU3/XU4 Board Control file
//
//
/*----------------------------------------------------------------------------*/
#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 "softPwm.h"
#include "softTone.h"
/*----------------------------------------------------------------------------*/
#include "wiringPi.h"
#include "odroidxu3.h"
/*----------------------------------------------------------------------------*/
// wiringPi gpio map define
/*----------------------------------------------------------------------------*/
static const int pinToGpio[64] = {
// wiringPi number to native gpio number
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
};
static const int phyToGpio[64] = {
// physical header pin number to native gpio number
-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
};
/*----------------------------------------------------------------------------*/
//
// Global variable define
//
/*----------------------------------------------------------------------------*/
/* ADC file descriptor */
static int adcFds[2];
/* GPIO mmap control */
static volatile uint32_t *gpio, *gpio1;
/* wiringPi Global library */
static struct libodroid *lib = NULL;
/*----------------------------------------------------------------------------*/
// Function prototype define
/*----------------------------------------------------------------------------*/
static int gpioToGPLEVReg (int pin);
static int gpioToPUPDReg (int pin);
static int gpioToShiftReg (int pin);
static int gpioToGPFSELReg (int pin);
static int gpioToDSReg (int pin);
/*----------------------------------------------------------------------------*/
// wiringPi core function
/*----------------------------------------------------------------------------*/
static int _getModeToGpio (int mode, int pin);
static int _setDrive (int pin, int value);
static int _getDrive (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_odroidxu3 (struct libodroid *libwiring);
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Input regsiter
//
/*----------------------------------------------------------------------------*/
static int gpioToGPLEVReg (int pin)
{
switch (pin) {
case XU3_GPIO_X1_START...XU3_GPIO_X1_END:
return (XU3_GPIO_X1_DAT_OFFSET >> 2);
case XU3_GPIO_X2_START...XU3_GPIO_X2_END:
return (XU3_GPIO_X2_DAT_OFFSET >> 2);
case XU3_GPIO_X3_START...XU3_GPIO_X3_END:
return (XU3_GPIO_X3_DAT_OFFSET >> 2);
case XU3_GPIO_A0_START...XU3_GPIO_A0_END:
return (XU3_GPIO_A0_DAT_OFFSET >> 2);
case XU3_GPIO_A2_START...XU3_GPIO_A2_END:
return (XU3_GPIO_A2_DAT_OFFSET >> 2);
case XU3_GPIO_B3_START...XU3_GPIO_B3_END:
return (XU3_GPIO_B3_DAT_OFFSET >> 2);
default:
break;
}
return -1;
}
/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Pull up/down regsiter
//
/*----------------------------------------------------------------------------*/
static int gpioToPUPDReg (int pin)
{
switch (pin) {
case XU3_GPIO_X1_START...XU3_GPIO_X1_END:
return (XU3_GPIO_X1_PUD_OFFSET >> 2);
case XU3_GPIO_X2_START...XU3_GPIO_X2_END:
return (XU3_GPIO_X2_PUD_OFFSET >> 2);
case XU3_GPIO_X3_START...XU3_GPIO_X3_END:
return (XU3_GPIO_X3_PUD_OFFSET >> 2);
case XU3_GPIO_A0_START...XU3_GPIO_A0_END:
return (XU3_GPIO_A0_PUD_OFFSET >> 2);
case XU3_GPIO_A2_START...XU3_GPIO_A2_END:
return (XU3_GPIO_A2_PUD_OFFSET >> 2);
case XU3_GPIO_B3_START...XU3_GPIO_B3_END:
return (XU3_GPIO_B3_PUD_OFFSET >> 2);
default:
break;
}
return -1;
}
/*----------------------------------------------------------------------------*/
//
// offset to the GPIO bit
//
/*----------------------------------------------------------------------------*/
static int gpioToShiftReg (int pin)
{
switch (pin) {
case XU3_GPIO_X1_START...XU3_GPIO_X1_END:
return (pin - XU3_GPIO_X1_START);
case XU3_GPIO_X2_START...XU3_GPIO_X2_END:
return (pin - XU3_GPIO_X2_START);
case XU3_GPIO_X3_START...XU3_GPIO_X3_END:
return (pin - XU3_GPIO_X3_START);
case XU3_GPIO_A0_START...XU3_GPIO_A0_END:
return (pin - XU3_GPIO_A0_START);
case XU3_GPIO_A2_START...XU3_GPIO_A2_END:
return (pin - XU3_GPIO_A2_START);
case XU3_GPIO_B3_START...XU3_GPIO_B3_END:
return (pin - XU3_GPIO_B3_START);
default:
break;
}
return -1;
}
/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Function register
//
/*----------------------------------------------------------------------------*/
static int gpioToGPFSELReg (int pin)
{
switch (pin) {
case XU3_GPIO_X1_START...XU3_GPIO_X1_END:
return (XU3_GPIO_X1_CON_OFFSET >> 2);
case XU3_GPIO_X2_START...XU3_GPIO_X2_END:
return (XU3_GPIO_X2_CON_OFFSET >> 2);
case XU3_GPIO_X3_START...XU3_GPIO_X3_END:
return (XU3_GPIO_X3_CON_OFFSET >> 2);
case XU3_GPIO_A0_START...XU3_GPIO_A0_END:
return (XU3_GPIO_A0_CON_OFFSET >> 2);
case XU3_GPIO_A2_START...XU3_GPIO_A2_END:
return (XU3_GPIO_A2_CON_OFFSET >> 2);
case XU3_GPIO_B3_START...XU3_GPIO_B3_END:
return (XU3_GPIO_B3_CON_OFFSET >> 2);
default:
break;
}
return -1;
}
/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Drive Strength register
//
/*----------------------------------------------------------------------------*/
static int gpioToDSReg (int pin)
{
switch (pin) {
case XU3_GPIO_X1_START...XU3_GPIO_X1_END:
return (XU3_GPIO_X1_DRV_OFFSET >> 2);
case XU3_GPIO_X2_START...XU3_GPIO_X2_END:
return (XU3_GPIO_X2_DRV_OFFSET >> 2);
case XU3_GPIO_X3_START...XU3_GPIO_X3_END:
return (XU3_GPIO_X3_DRV_OFFSET >> 2);
case XU3_GPIO_A0_START...XU3_GPIO_A0_END:
return (XU3_GPIO_A0_DRV_OFFSET >> 2);
case XU3_GPIO_A2_START...XU3_GPIO_A2_END:
return (XU3_GPIO_A2_DRV_OFFSET >> 2);
case XU3_GPIO_B3_START...XU3_GPIO_B3_END:
return (XU3_GPIO_B3_DRV_OFFSET >> 2);
default:
break;
}
return -1;
}
/*----------------------------------------------------------------------------*/
static int _getModeToGpio (int mode, int pin)
{
switch (mode) {
/* Native gpio number */
case MODE_GPIO:
return pin;
/* Native gpio number for sysfs */
case MODE_GPIO_SYS:
return lib->sysFds[pin] != -1 ? pin : -1;
/* wiringPi number */
case MODE_PINS:
return pin < 64 ? pinToGpio[pin] : -1;
/* header pin number */
case MODE_PHYS:
return pin < 64 ? phyToGpio[pin] : -1;
default :
break;
}
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
return -1;
}
/*----------------------------------------------------------------------------*/
static int _setDrive (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) << 1;
if (pin < 100) {
*(gpio + ds) &= ~(0b11 << shift);
*(gpio + ds) |= (value << shift);
} else {
*(gpio1 + ds) &= ~(0b11 << shift);
*(gpio1 + ds) |= (value << shift);
}
return 0;
}
/*----------------------------------------------------------------------------*/
static int _getDrive (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) << 1;
if (pin < 100)
return (*(gpio + ds) >> shift) & 0b11;
else
return (*(gpio1 + 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) << 2;
switch (mode) {
case INPUT:
if(pin < 100) {
*(gpio + fsel) &= ~(0xF << shift);
} else {
*(gpio1 + fsel) &= ~(0xF << shift);
}
_pullUpDnControl(origPin, PUD_OFF);
break;
case OUTPUT:
if(pin < 100) {
*(gpio + fsel) &= ~(0xF << shift);
*(gpio + fsel) |= (0x1 << shift);
} else {
*(gpio1 + fsel) &= ~(0xF << shift);
*(gpio1 + fsel) |= (0x1 << shift);
}
break;
case INPUT_PULLUP:
if(pin < 100) {
*(gpio + fsel) &= ~(0xF << shift);
} else {
*(gpio1 + fsel) &= ~(0xF << shift);
}
_pullUpDnControl(origPin, PUD_UP);
break;
case INPUT_PULLDOWN:
if(pin < 100) {
*(gpio + fsel) &= ~(0xF << shift);
} else {
*(gpio1 + fsel) &= ~(0xF << shift);
}
_pullUpDnControl(origPin, PUD_DOWN);
break;
case SOFT_PWM_OUTPUT:
softPwmCreate (origPin, 0, 100);
break;
case SOFT_TONE_OUTPUT:
softToneCreate (origPin);
break;
default:
msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode);
return -1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
static int _getAlt (int pin)
{
int fsel, shift, mode;
if (lib->mode == MODE_GPIO_SYS)
return -1;
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
return -1;
fsel = gpioToGPFSELReg(pin);
shift = gpioToShiftReg(pin) << 2;
if (pin < 100) // GPX0,1,2,3
mode = (*(gpio + fsel) >> shift) & 0xF;
else // GPA0,1,2, GPB0,1,2,3,4
mode = (*(gpio1 + fsel) >> shift) & 0xF;
// If mode is bigger than 8 including EXT_INT(0xF), it returns ALT7
return mode <= 8 ? mode : 8;
}
/*----------------------------------------------------------------------------*/
static int _getPUPD (int pin)
{
int pupd, shift, pull;
if (lib->mode == MODE_GPIO_SYS)
return -1;
if ((pin = _getModeToGpio(lib->mode, pin)) < 0)
return -1;
pupd = gpioToPUPDReg(pin);
shift = gpioToShiftReg(pin) << 1;
if (pin < 100)
pull = (*(gpio + pupd) >> shift) & 0x3;
else
pull = (*(gpio1 + pupd) >> shift) & 0x3;
// Pull up when 0x3, down when 0x1
return pull == 0 ? 0 : (pull == 0x3 ? 1 : 2);
}
/*----------------------------------------------------------------------------*/
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) << 1;
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);
}
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 (pin < 100)
return *(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : LOW;
else
return *(gpio1 + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : 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 (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));
}
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) {
#if defined(ARDUINO)
/* To work with physical analog channel numbering */
case 0: case 25:
pin = 0;
break;
case 3: case 29:
pin = 1;
break;
#else
case 0: case 25:
pin = 0;
break;
case 1: case 29:
pin = 1;
break;
#endif
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 gpx1, gpx2, gpa0;
if (lib->mode == MODE_GPIO_SYS) {
return -1;
}
/* Read data register */
gpx1.wvalue = *(gpio + (XU3_GPIO_X1_DAT_OFFSET >> 2));
gpx2.wvalue = *(gpio + (XU3_GPIO_X2_DAT_OFFSET >> 2));
gpa0.wvalue = *(gpio1 + (XU3_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 + (XU3_GPIO_X1_DAT_OFFSET >> 2)) = gpx1.wvalue;
*(gpio + (XU3_GPIO_X2_DAT_OFFSET >> 2)) = gpx2.wvalue;
*(gpio1 + (XU3_GPIO_A0_DAT_OFFSET >> 2)) = gpa0.wvalue;
return 0;
}
/*----------------------------------------------------------------------------*/
static unsigned int _digitalReadByte (void)
{
union reg_bitfield gpx1, gpx2, gpa0;
unsigned int value = 0;
if (lib->mode == MODE_GPIO_SYS) {
return -1;
}
/* Read data register */
gpx1.wvalue = *(gpio + (XU3_GPIO_X1_DAT_OFFSET >> 2));
gpx2.wvalue = *(gpio + (XU3_GPIO_X2_DAT_OFFSET >> 2));
gpa0.wvalue = *(gpio1 + (XU3_GPIO_A0_DAT_OFFSET >> 2));
/* Wiring PI GPIO0 = XU3/4 GPA0.3 */
if (gpa0.bits.bit3)
value |= 0x01;
/* Wiring PI GPIO1 = XU3/4 GPA0.2 */
if (gpa0.bits.bit2)
value |= 0x02;
/* Wiring PI GPIO2 = XU3/4 GPX1.5 */
if (gpx1.bits.bit5)
value |= 0x04;
/* Wiring PI GPIO3 = XU3/4 GPX1.6 */
if (gpx1.bits.bit6)
value |= 0x08;
/* Wiring PI GPIO4 = XU3/4 GPX1.3 */
if (gpx1.bits.bit3)
value |= 0x10;
/* Wiring PI GPIO5 = XU3/4 GPX1.7 */
if (gpx1.bits.bit7)
value |= 0x20;
/* Wiring PI GPIO6 = XU3/4 GPX2.0 */
if (gpx2.bits.bit0)
value |= 0x40;
/* Wiring PI GPIO7 = XU3/4 GPX1.2 */
if (gpx1.bits.bit2)
value |= 0x80;
return value;
}
/*----------------------------------------------------------------------------*/
static void init_gpio_mmap (void)
{
int fd = -1;
void *mapped[2];
/* 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));
setUsingGpiomem(TRUE);
} 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 ODROIDXU_GPX_BASE 0x13400000 // GPX0,1,2,3
mapped[0] = mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, XU3_GPX_BASE);
//#define ODROIDXU_GPA_BASE 0x14010000 // GPA0,1,2, GPB0,1,2,3,4
mapped[1] = mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, XU3_GPA_BASE);
if (mapped[0] == MAP_FAILED || mapped[1] == MAP_FAILED) {
msg(MSG_ERR, "wiringPiSetup: mmap (GPIO) failed: %s \n", strerror (errno));
} else {
gpio = (uint32_t *) mapped[0];
gpio1 = (uint32_t *) mapped[1];
}
}
}
/*----------------------------------------------------------------------------*/
static void init_adc_fds (void)
{
const char *AIN0_NODE, *AIN1_NODE;
if ((kernelVersion->major == 4 && kernelVersion->minor == 14) ||
kernelVersion->major == 5) {
AIN0_NODE = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage0_raw";
AIN1_NODE = "/sys/devices/platform/soc/12d10000.adc/iio:device0/in_voltage3_raw";
} else if (kernelVersion->major == 4 && kernelVersion->minor == 9) {
AIN0_NODE = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage0_raw";
AIN1_NODE = "/sys/devices/platform/soc:/12d10000.adc:/iio:device0/in_voltage3_raw";
} else { // 3.10 kernel
AIN0_NODE = "/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw";
AIN1_NODE = "/sys/devices/12d10000.adc/iio:device0/in_voltage3_raw";
}
adcFds[0] = open(AIN0_NODE, O_RDONLY);
adcFds[1] = open(AIN1_NODE, O_RDONLY);
}
/*----------------------------------------------------------------------------*/
void init_odroidxu3 (struct libodroid *libwiring)
{
init_gpio_mmap();
init_adc_fds();
/* wiringPi Core function initialize */
libwiring->getModeToGpio = _getModeToGpio;
libwiring->setDrive = _setDrive;
libwiring->getDrive = _getDrive;
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 = XU3_GPIO_PIN_BASE;
/* global variable setup */
lib = libwiring;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/