diff --git a/wiringPi/Makefile b/wiringPi/Makefile old mode 100644 new mode 100755 index e1868b9..ecf9b75 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -27,6 +27,9 @@ PREFIX?=/local LDCONFIG?=ldconfig +# BRAND_NAME = Pi +BRAND_NAME = Odroid + ifneq ($V,1) Q ?= @ endif @@ -45,7 +48,7 @@ LIBS = -lm -lpthread -lrt -lcrypt ############################################################################### -SRC = wiringPi.c \ +SRC = wiring${BRAND_NAME}.c \ wiringSerial.c wiringShift.c \ piHiPri.c piThread.c \ wiringPiSPI.c wiringPiI2C.c \ @@ -62,6 +65,14 @@ SRC = wiringPi.c \ pseudoPins.c \ wpiExtensions.c +ifeq ($(BRAND_NAME), Odroid) + DEFS += -D BOARD_ODROID + SRC += odroidc1.c \ + odroidc2.c \ + odroidxu3.c \ + odroidn1.c +endif + HEADERS = $(shell ls *.h) OBJ = $(SRC:.c=.o) @@ -140,7 +151,16 @@ depend: # DO NOT DELETE -wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h +ifeq ($(BRAND_NAME), Odroid) + wiringOdroid.o: softPwm.h softTone.h wiringPi.h wiringOdroid.h ../version.h + odroidc1.c : wiringPi.h wiringOdroid.h odroidc1.h + odroidc2.c : wiringPi.h wiringOdroid.h odroidc2.h + odroidxu3.c : wiringPi.h wiringOdroid.h odroidxu3.h + odroidn1.c : wiringPi.h wiringOdroid.h odroidn1.h +else + wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h +endif + wiringSerial.o: wiringSerial.h wiringShift.o: wiringPi.h wiringShift.h piHiPri.o: wiringPi.h diff --git a/wiringPi/odroid_template.c b/wiringPi/odroid_template.c new file mode 100755 index 0000000..8fd82f5 --- /dev/null +++ b/wiringPi/odroid_template.c @@ -0,0 +1,266 @@ +/*----------------------------------------------------------------------------*/ +// +// +// WiringPi ODROID-??? Board Control file (??? Platform) +// +// +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "wiringOdroid.h" +#include "odroid???.h" + +/*----------------------------------------------------------------------------*/ +// wiringPi gpio map define +/*----------------------------------------------------------------------------*/ +static const int pinToGpio[64] = { + // wiringPi number to native gpio number + ???, ???, // 0 | 1 : + ???, -1, // 2 | 3 : + ???, ???, // 4 | 5 : + ???, ???, // 6 | 7 : + -1, -1, // 8 | 9 : + ???, ???, // 10 | 11 : + ???, ???, // 12 | 13 : + ???, -1, // 14 | 15 : + -1, -1, // 16 | 17 : + -1, -1, // 18 | 19 : + -1, ???, // 20 | 21 : + ???, ???, // 22 | 23 : + ???, -1, // 24 | 25 : + ???, ???, // 26 | 27 : + -1, -1, // 28 | 29 : + -1, -1, // 30 | 31 : + // Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 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 : + -1, -1, // 3 | 4 : + -1, -1, // 5 | 6 : + ???, -1, // 7 | 8 : + -1, -1, // 9 | 10 : + ???,???, // 11 | 12 : + ???, -1, // 13 | 14 : + -1, ???, // 15 | 16 : + -1, ???, // 17 | 18 : + ???, -1, // 19 | 20 : + ???,???, // 21 | 22 : + ???,???, // 23 | 24 : + -1, ???, // 25 | 26 : + -1, -1, // 27 | 28 : + ???, -1, // 29 | 30 : + ???,???, // 31 | 32 : + ???, -1, // 33 | 34 : + ???,???, // 35 | 36 : + -1, -1, // 37 | 38 : + -1, -1, // 39 | 40 : + // 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 char *adcFds[2]; + +/* GPIO mmap control */ +static volatile uint32_t *gpio; + +/* wiringPi Global library */ +static struct libodroid *lib = NULL; + +/*----------------------------------------------------------------------------*/ +// Function prototype define +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin); +static int gpioToGPLEVReg (int pin); +static int gpioToPUENReg (int pin); +static int gpioToPUPDReg (int pin); +static int gpioToShiftReg (int pin); +static int gpioToGPFSELReg (int pin); + +/*----------------------------------------------------------------------------*/ +// wiringPi core function +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin); +static void pinMode (int pin, int mode); +static int getAlt (int pin); +static void pullUpDnControl (int pin, int pud); +static int digitalRead (int pin); +static void digitalWrite (int pin, int value); +static int analogRead (int pin); +static void digitalWriteByte(const int value); +static unsigned int digitalReadByte (void); + +/*----------------------------------------------------------------------------*/ +// board init function +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void); +static void init_adc_fds (void); + + void init_odroid??? (struct libodroid *libwiring); + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Set regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Input regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPLEVReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down enable regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUENReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUPDReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO bit +// +/*----------------------------------------------------------------------------*/ +static int gpioToShiftReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Function register +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPFSELReg (int pin) +{ + return -1; +} +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void pinMode (int pin, int mode) +{ +} + +/*----------------------------------------------------------------------------*/ +static int getAlt (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void pullUpDnControl (int pin, int pud) +{ +} + +/*----------------------------------------------------------------------------*/ +static int digitalRead (int pin) +{ +} + +/*----------------------------------------------------------------------------*/ +static void digitalWrite (int pin, int value) +{ +} + +/*----------------------------------------------------------------------------*/ +static int analogRead (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void digitalWriteByte (const int value) +{ +} + +/*----------------------------------------------------------------------------*/ +static unsigned int digitalReadByte (void) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void) +{ +} + +/*----------------------------------------------------------------------------*/ +static void init_adc_fds (void) +{ +} + +/*----------------------------------------------------------------------------*/ +void init_odroid??? (struct libodroid *libwiring) +{ + init_gpio_mmap(); + + init_adc_fds(); + + /* wiringPi Core function initialize */ + libwiring->getModeToGpio = getModeToGpio; + libwiring->pinMode = pinMode; + libwiring->getAlt = getAlt; + libwiring->pullUpDnControl = pullUpDnControl; + libwiring->digitalRead = digitalRead; + libwiring->digitalWrite = digitalWrite; + libwiring->analogRead = analogRead; + libwiring->digitalWriteByte = digitalWriteByte; + libwiring->digitalReadByte = digitalReadByte; + + /* global variable setup */ + lib = libwiring; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroid_template.h b/wiringPi/odroid_template.h new file mode 100755 index 0000000..b6b7f16 --- /dev/null +++ b/wiringPi/odroid_template.h @@ -0,0 +1,24 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi ODROID-??? Board Header file + + */ +/*----------------------------------------------------------------------------*/ +#ifndef __ODROID_???_H__ +#define __ODROID_???_H__ + +/*----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + +extern void init_odroid??? (struct libodroid *libwiring); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +#endif /* __ODROID_???_H__ */ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidc1.c b/wiringPi/odroidc1.c new file mode 100755 index 0000000..fdb868a --- /dev/null +++ b/wiringPi/odroidc1.c @@ -0,0 +1,521 @@ +/*----------------------------------------------------------------------------*/ +// +// +// WiringPi ODROID-C0/C1/C1+ Board Control file (AMLogic 32Bits Platform) +// +// +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "wiringOdroid.h" +#include "odroidc1.h" + +/*----------------------------------------------------------------------------*/ +// wiringPi gpio map define +/*----------------------------------------------------------------------------*/ +static const int pinToGpio[64] = { + // wiringPi number to native gpio number + 88, 87, // 0 | 1 : GPIOY.8, GPIOY.7 + 116, 115, // 2 | 3 : GPIOX.19, GPIOX.18 + 104, 102, // 4 | 5 : GPIOX.7, GPIOX.5 + 103, 83, // 6 | 7 : GPIOX.6, GPIOY.3 + -1, -1, // 8 | 9 : GPIODV.24(I2CA_SDA), GPIODV.25(I2CA_SCL) + 117, 118, // 10 | 11 : GPIOX.20(SPI_CE0), GPIOX.21(SPI_CE1) + 107, 106, // 12 | 13 : GPIOX.10(SPI_MOSI), GPIOX.9(SPI_MISO) + 105, -1, // 14 | 15 : GPIOX.8(SPI_SCLK), GPIOX.16(UART_TX_B) + -1, -1, // 16 | 17 : GPIOX.17(UART_RX_B), + -1, -1, // 18 | 19 : + -1, 101, // 20 | 21 : , GPIOX.4 + 100, 108, // 22 | 23 : GPIOX.3, GPIOX.11 + 97, -1, // 24 | 25 : GPIOX.0, ADC.AIN1 + 99, 98, // 26 | 27 : GPIOX.2, GPIOX.1 + -1, -1, // 28 | 29 : REF1.8V OUT, ADC.AIN0 + -1, -1, // 30 | 31 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_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 + -1, -1, // 3 | 4 : GPIODV.24(I2CA_SDA), 5.0V + -1, -1, // 5 | 6 : GPIODV.25(I2CA_SCL), GND + 83, -1, // 7 | 8 : GPIOY.3, GPIOX.16(UART_TX_B) + -1, -1, // 9 | 10 : GND, GPIOX.17(UART_RX_B) + 88, 87, // 11 | 12 : GPIOY.8, GPIOY.7 + 116, -1, // 13 | 14 : GPIOX.19, GND + 115, 104, // 15 | 16 : GPIOX.18, GPIOX.7 + -1, 102, // 17 | 18 : 3.3V, GPIOX.5 + 107, -1, // 19 | 20 : GPIOX.10(SPI_MOSI), GND + 106, 103, // 21 | 22 : GPIOX.9(SPI_MISO), GPIOX.6 + 105, 117, // 23 | 24 : GPIOX.8(SPI_SCLK), GPIOX.20(SPI_CE0) + -1, 118, // 25 | 26 : GND, GPIOX.21(SPI_CE1) + -1, -1, // 27 | 28 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_SCL) + 101, -1, // 29 | 30 : GPIOX.4, GND + 100, 99, // 31 | 32 : GPIOX.3, GPIOX.2 + 108, -1, // 33 | 34 : GPIOX.11, GND + 97, 98, // 35 | 36 : GPIOX.0, GPIOX.1 + -1, -1, // 37 | 38 : ADC.AIN1, 1.8V REF OUT + -1, -1, // 39 | 40 : GND, ADC.AIN0 + + // 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 char *adcFds[2]; + +/* GPIO mmap control */ +static volatile uint32_t *gpio; + +/* wiringPi Global library */ +static struct libodroid *lib = NULL; + +/*----------------------------------------------------------------------------*/ +// Function prototype define +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin); +static int gpioToGPLEVReg (int pin); +static int gpioToPUENReg (int pin); +static int gpioToPUPDReg (int pin); +static int gpioToShiftReg (int pin); +static int gpioToGPFSELReg (int pin); + +/*----------------------------------------------------------------------------*/ +// wiringPi core function +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin); +static void pinMode (int pin, int mode); +static int getAlt (int pin); +static void pullUpDnControl (int pin, int pud); +static int digitalRead (int pin); +static void digitalWrite (int pin, int value); +static int analogRead (int pin); +static void digitalWriteByte(const int value); +static unsigned int digitalReadByte (void); + +/*----------------------------------------------------------------------------*/ +// board init function +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void); +static void init_adc_fds (void); + + void init_odroidn1 (struct libodroid *libwiring); + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Set regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin) +{ + 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 (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 (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 (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 (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 (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; +} +/*----------------------------------------------------------------------------*/ +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 void pinMode (int pin, int mode) +{ + int fsel, shift, origPin = pin; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + softPwmStop (origPin); + softToneStop (origPin); + + fsel = gpioToGPFSELReg(pin); + shift = gpioToShiftReg (pin); + + switch (mode) { + case INPUT: + *(gpio + fsel) = (*(gpio + fsel) | (1 << shift)); + break; + case OUTPUT: + *(gpio + fsel) = (*(gpio + fsel) & ~(1 << shift)); + break; + case SOFT_PWM_OUTPUT: + softPwmCreate (pin, 0, 100); + break; + case SOFT_TONE_OUTPUT: + softToneCreate (pin); + break; + default: + msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode); + break; + } +} + +/*----------------------------------------------------------------------------*/ +static int getAlt (int pin) +{ + int fsel, shift; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 2; + + shift = gpioToShiftReg(pin); + + return (*(gpio + gpioToGPFSELReg(pin)) & (1 << shift)) ? 0 : 1; +} + +/*----------------------------------------------------------------------------*/ +static void pullUpDnControl (int pin, int pud) +{ + int shift = 0; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + shift = gpioToShiftReg(pin); + + if (pud) { + // Enable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = + (*(gpio + gpioToPUENReg(pin)) | (1 << shift)); + + if (pud == PUD_UP) + *(gpio + gpioToPUPDReg(pin)) = + (*(gpio + gpioToPUPDReg(pin)) | (1 << shift)); + else + *(gpio + gpioToPUPDReg(pin)) = + (*(gpio + gpioToPUPDReg(pin)) & ~(1 << shift)); + } else // Disable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = + (*(gpio + gpioToPUENReg(pin)) & ~(1 << shift)); +} + +/*----------------------------------------------------------------------------*/ +static int digitalRead (int pin) +{ + char c ; + + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] == -1) + return LOW ; + + lseek (lib->sysFds[pin], 0L, SEEK_SET); + read (lib->sysFds[pin], &c, 1); + + return (c == '0') ? LOW : HIGH; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 0; + + if ((*(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin))) != 0) + return HIGH ; + else + return LOW ; +} + +/*----------------------------------------------------------------------------*/ +static void digitalWrite (int pin, int value) +{ + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] != -1) { + if (value == LOW) + write (lib->sysFds[pin], "0\n", 2); + else + write (lib->sysFds[pin], "1\n", 2); + } + return; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + if (value == LOW) + *(gpio + gpioToGPSETReg(pin)) &= ~(1 << gpioToShiftReg(pin)); + else + *(gpio + gpioToGPSETReg(pin)) |= (1 << gpioToShiftReg(pin)); +} + +/*----------------------------------------------------------------------------*/ +static int analogRead (int pin) +{ + unsigned char value[5] = {0,}; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + /* wiringPi ADC number = pin 25, pin 29 */ + switch (pin) { + case 0: case 25: + pin = 0; + break; + case 1: case 29: + pin = 1; + break; + default: + return 0; + } + if (adcFds [pin] == -1) + return 0; + + lseek (adcFds [pin], 0L, SEEK_SET); + read (adcFds [pin], &value[0], 4); + + return atoi(value); +} + +/*----------------------------------------------------------------------------*/ +static void digitalWriteByte (const 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; +} + +/*----------------------------------------------------------------------------*/ +static unsigned int digitalReadByte (void) +{ + union reg_bitfield gpiox, gpioy; + unsigned int value = 0; + + gpiox.wvalue = *(gpio + GPIOX_INP_REG_OFFSET); + gpioy.wvalue = *(gpio + GPIOY_INP_REG_OFFSET); + + /* Wiring PI GPIO0 = C1 GPIOY.8 */ + if (gpioy.bits.bit8) + value |= 0x01; + /* Wiring PI GPIO1 = C1 GPIOY.7 */ + if (gpioy.bits.bit7) + value |= 0x02; + /* Wiring PI GPIO2 = C1 GPIOX.19 */ + if (gpiox.bits.bit19) + value |= 0x04; + /* Wiring PI GPIO3 = C1 GPIOX.18 */ + if (gpiox.bits.bit18) + value |= 0x08; + /* Wiring PI GPIO4 = C1 GPIOX.7 */ + if (gpiox.bits.bit7) + value |= 0x10; + /* Wiring PI GPIO5 = C1 GPIOX.5 */ + if (gpiox.bits.bit5) + value |= 0x20; + /* Wiring PI GPIO6 = C1 GPIOX.6 */ + if (gpiox.bits.bit6) + value |= 0x40; + /* Wiring PI GPIO7 = C1 GPIOY.3 */ + if (gpioy.bits.bit3) + value |= 0x80; + + return value; +} + +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void) +{ + int fd; + + /* GPIO mmap setup */ + if (access("/dev/gpiomem",0) == 0) { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", + strerror (errno)) ; + } else { + if (geteuid () != 0) + return msg (MSG_ERR, + "wiringPiSetup: Must be root. (Did you forget sudo?)\n"); + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/mem: %s\n", + strerror (errno)) ; + } + //#define ODROIDXU_GPX_BASE 0xC1108000 + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, ODROIDC1_GPIO_BASE) ; + + if ((int32_t)gpio == -1) + return msg (MSG_ERR, + "wiringPiSetup: mmap (GPIO) failed: %s\n", + strerror (errno)); +} + +/*----------------------------------------------------------------------------*/ +static void init_adc_fds (void) +{ + const char *AIN0_NODE, *AIN1_NODE; + + /* ADC node setup */ + AIN0_NODE = "/sys/class/saradc/saradc_ch0"; + AIN1_NODE = "/sys/class/saradc/saradc_ch1"; + + adcFds[0] = open(AIN0_NODE, O_RDONLY); + adcFds[1] = open(AIN1_NODE, O_RDONLY); +} + +/*----------------------------------------------------------------------------*/ +void init_odroidc1 (struct libodroid *libwiring) +{ + init_gpio_mmap(); + + init_adc_fds(); + + /* wiringPi Core function initialize */ + libwiring->getModeToGpio = getModeToGpio; + libwiring->pinMode = pinMode; + libwiring->getAlt = getAlt; + libwiring->pullUpDnControl = pullUpDnControl; + libwiring->digitalRead = digitalRead; + libwiring->digitalWrite = digitalWrite; + libwiring->analogRead = analogRead; + libwiring->digitalWriteByte = digitalWriteByte; + libwiring->digitalReadByte = digitalReadByte; + + /* global variable setup */ + lib = libwiring; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidc1.h b/wiringPi/odroidc1.h new file mode 100755 index 0000000..972f86b --- /dev/null +++ b/wiringPi/odroidc1.h @@ -0,0 +1,45 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi ODROID-C0/C1/C1+ Board Header file + + */ +/*----------------------------------------------------------------------------*/ +#ifndef __ODROID_C1_H__ +#define __ODROID_C1_H__ + +/*----------------------------------------------------------------------------*/ +#define ODROIDC_GPIO_MASK (0xFFFFFF80) +#define ODROIDC1_GPIO_BASE 0xC1108000 + +#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 + +#ifdef __cplusplus +extern "C" { +#endif + +extern void init_odroidc1 (struct libodroid *libwiring); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +#endif /* __ODROID_C1_H__ */ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidc2.c b/wiringPi/odroidc2.c new file mode 100755 index 0000000..96548a7 --- /dev/null +++ b/wiringPi/odroidc2.c @@ -0,0 +1,551 @@ +/*----------------------------------------------------------------------------*/ +// +// +// WiringPi ODROID-C2 Board Control file (AMLogic 64Bits Platform) +// +// +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "wiringOdroid.h" +#include "odroidc2.h" + +/*----------------------------------------------------------------------------*/ +// wiringPi gpio map define +/*----------------------------------------------------------------------------*/ +static const int pinToGpio_rev1[64] = { + // wiringPi number to native gpio number + 219, 218, // 0 | 1 : GPIOY.8, GPIOY.7 + 247, -1, // 2 | 3 : GPIOX.19, + 235, 233, // 4 | 5 : GPIOX.7, GPIOX.5 + 234, 214, // 6 | 7 : GPIOX.6, GPIOY.3 + -1, -1, // 8 | 9 : GPIODV.24(I2CA_SDA), GPIODV.25(I2CA_SCL) + 248, 249, // 10 | 11 : GPIOX.20, GPIOX.21 + 238, 237, // 12 | 13 : GPIOX.10, GPIOX.9 + 236, -1, // 14 | 15 : GPIOX.8, + -1, -1, // 16 | 17 : + -1, -1, // 18 | 19 : + -1, 232, // 20 | 21 : , GPIOX.4 + 231, 239, // 22 | 23 : GPIOX.3, GPIOX.11 + 228, -1, // 24 | 25 : GPIOX.0, ADC.AIN1 + 230, 229, // 26 | 27 : GPIOX.2, GPIOX.1 + -1, -1, // 28 | 29 : REF1.8V OUT, ADC.AIN0 + -1, -1, // 30 | 31 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_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_rev1[64] = { + // physical header pin number to native gpio number + -1, // 0 + -1, -1, // 1 | 2 : 3.3V, 5.0V + -1, -1, // 3 | 4 : GPIODV.24(I2CA_SDA), 5.0V + -1, -1, // 5 | 6 : GPIODV.25(I2CA_SCL), GND + 214, -1, // 7 | 8 : GPIOY.3, GPIOX.16(UART_TX_B) + -1, -1, // 9 | 10 : GND, GPIOX.17(UART_RX_B) + 219,218, // 11 | 12 : GPIOY.8, GPIOY.7 + 247, -1, // 13 | 14 : GPIOX.19, GND + -1, 235, // 15 | 16 : GPIOX.18, GPIOX.7 + -1, 233, // 17 | 18 : 3.3V, GPIOX.5 + 238, -1, // 19 | 20 : GPIOX.10(SPI_MOSI), GND + 237,234, // 21 | 22 : GPIOX.9(SPI_MISO), GPIOX.6 + 236,248, // 23 | 24 : GPIOX.8(SPI_SCLK), GPIOX.20(SPI_CE0) + -1, 249, // 25 | 26 : GND, GPIOX.21(SPI_CE1) + -1, -1, // 27 | 28 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_SCL) + 232, -1, // 29 | 30 : GPIOX.4, GND + 231,230, // 31 | 32 : GPIOX.3, GPIOX.2 + 239, -1, // 33 | 34 : GPIOX.11, GND + 228,229, // 35 | 36 : GPIOX.0, GPIOX.1 + -1, -1, // 37 | 38 : ADC.AIN1, 1.8V REF OUT + -1, -1, // 39 | 40 : GND, ADC.AIN0 + // 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 +}; + +/*----------------------------------------------------------------------------*/ +static const int pinToGpio_rev2[64] = { + // wiringPi number to native gpio number + 247, 238, // 0 | 1 : GPIOX.19, GPIOX.10 + 239, 237, // 2 | 3 : GPIOX.11, GPIOX.9 + 236, 233, // 4 | 5 : GPIOX.8, GPIOX.5 + 231, 249, // 6 | 7 : GPIOX.3, GPIOX.21 + -1, -1, // 8 | 9 : GPIODV.24(I2CA_SDA), GPIODV.25(I2CA_SCL) + 229, 225, // 10 | 11 : GPIOX.1, GPIOY.14 + 235, 232, // 12 | 13 : GPIOX.7(PWM1), GPIOX.4 + 230, -1, // 14 | 15 : GPIOX.2, GPIOX.12(UART_TX_B) + -1, -1, // 16 | 17 : GPIOX.13(UART_RX_B), + -1, -1, // 18 | 19 : + -1, 228, // 20 | 21 : , GPIOX.0 + 219, 234, // 22 | 23 : GPIOY.8, GPIOX.6(PWM0) + 214, -1, // 24 | 25 : GPIOY.3, ADC.AIN1 + 224, 218, // 26 | 27 : GPIOY.13, GPIOY.7 + -1, -1, // 28 | 29 : REF1.8V OUT, ADC.AIN0 + -1, -1, // 30 | 31 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_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_rev2[64] = { + // physical header pin number to native gpio number + -1, // 0 + -1, -1, // 1 | 2 : 3.3V, 5.0V + -1, -1, // 3 | 4 : GPIODV.24(I2CA_SDA), 5.0V + -1, -1, // 5 | 6 : GPIODV.25(I2CA_SCL), GND + 249, -1, // 7 | 8 : GPIOX.21, GPIOX.12(UART_TX_B) + -1, -1, // 9 | 10 : GND, GPIOX.13(UART_RX_B) + 247,238, // 11 | 12 : GPIOX.19, GPIOX.10 + 239, -1, // 13 | 14 : GPIOX.11, GND + 237,236, // 15 | 16 : GPIOX.9, GPIOX.8 + -1, 233, // 17 | 18 : 3.3V, GPIOX.5 + 235, -1, // 19 | 20 : GPIOX.7(PWM1), GND + 232,231, // 21 | 22 : GPIOX.4, GPIOX.3 + 230,229, // 23 | 24 : GPIOX.2, GPIOX.1 + -1, 225, // 25 | 26 : GND, GPIOY.14 + -1, -1, // 27 | 28 : GPIODV.26(I2CB_SDA), GPIODV.27(I2CB_SCL) + 228, -1, // 29 | 30 : GPIOX.0, GND + 219,224, // 31 | 32 : GPIOY.8, GPIOY.13 + 234, -1, // 33 | 34 : GPIOX.6(PWM0), GND + 214,218, // 35 | 36 : GPIOY.3, GPIOY.7 + -1, -1, // 37 | 38 : ADC.AIN1, 1.8V REF OUT + -1, -1, // 39 | 40 : GND, ADC.AIN0 + // Not used + -1, -1, -1, -1, -1, -1, -1, -1, // 41...48 + -1, -1, -1, -1, -1, -1, -1, -1, // 49...56 + -1, -1, -1, -1, -1, -1, -1 // 57...63 +}; + +/*----------------------------------------------------------------------------*/ +// +// Global variable define +// +/*----------------------------------------------------------------------------*/ +// wiringPi Pinmap control arrary +/*----------------------------------------------------------------------------*/ +const int *pinToGpio, *phyToGpio; + +/* ADC file descriptor */ +static char *adcFds[2]; + +/* GPIO mmap control */ +static volatile uint32_t *gpio, *gpio1; + +/* wiringPi Global library */ +static struct libodroid *lib = NULL; + +/*----------------------------------------------------------------------------*/ +// Function prototype define +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin); +static int gpioToGPLEVReg (int pin); +static int gpioToPUENReg (int pin); +static int gpioToPUPDReg (int pin); +static int gpioToShiftReg (int pin); +static int gpioToGPFSELReg (int pin); + +/*----------------------------------------------------------------------------*/ +// wiringPi core function +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin); +static void pinMode (int pin, int mode); +static int getAlt (int pin); +static void pullUpDnControl (int pin, int pud); +static int digitalRead (int pin); +static void digitalWrite (int pin, int value); +static int analogRead (int pin); +static void digitalWriteByte(const int value); +static unsigned int digitalReadByte (void); + +/*----------------------------------------------------------------------------*/ +// board init function +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void); +static void init_adc_fds (void); + + void init_odroidc2 (struct libodroid *libwiring); + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Set regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin) +{ + 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; + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Input regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPLEVReg (int pin) +{ + 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; + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down enable regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUENReg (int pin) +{ + 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; + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUPDReg (int pin) +{ + 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; + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO bit +// +/*----------------------------------------------------------------------------*/ +static int gpioToShiftReg (int pin) +{ + 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; + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Function register +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPFSELReg (int pin) +{ + 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; + 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 void pinMode (int pin, int mode) +{ + int fsel, shift, origPin = pin; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + softPwmStop (origPin); + softToneStop (origPin); + + fsel = gpioToGPFSELReg(pin); + shift = gpioToShiftReg (pin); + + switch (mode) { + case INPUT: + *(gpio + fsel) = (*(gpio + fsel) | (1 << shift)); + break; + case OUTPUT: + *(gpio + fsel) = (*(gpio + fsel) & ~(1 << shift)); + break; + case SOFT_PWM_OUTPUT: + softPwmCreate (pin, 0, 100); + break; + case SOFT_TONE_OUTPUT: + softToneCreate (pin); + break; + default: + msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode); + break; + } +} + +/*----------------------------------------------------------------------------*/ +static int getAlt (int pin) +{ + int fsel, shift; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 2; + + shift = gpioToShiftReg(pin); + + return (*(gpio + gpioToGPFSELReg(pin)) & (1 << shift)) ? 0 : 1; +} + +/*----------------------------------------------------------------------------*/ +static void pullUpDnControl (int pin, int pud) +{ + int shift = 0; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + shift = gpioToShiftReg(pin); + + if (pud) { + // Enable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = + (*(gpio + gpioToPUENReg(pin)) | (1 << shift)); + + if (pud == PUD_UP) + *(gpio + gpioToPUPDReg(pin)) = + (*(gpio + gpioToPUPDReg(pin)) | (1 << shift)); + else + *(gpio + gpioToPUPDReg(pin)) = + (*(gpio + gpioToPUPDReg(pin)) & ~(1 << shift)); + } else // Disable Pull/Pull-down resister + *(gpio + gpioToPUENReg(pin)) = + (*(gpio + gpioToPUENReg(pin)) & ~(1 << shift)); +} + +/*----------------------------------------------------------------------------*/ +static int digitalRead (int pin) +{ + char c ; + + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] == -1) + return LOW ; + + lseek (lib->sysFds[pin], 0L, SEEK_SET); + read (lib->sysFds[pin], &c, 1); + + return (c == '0') ? LOW : HIGH; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 0; + + if ((*(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin))) != 0) + return HIGH ; + else + return LOW ; +} + +/*----------------------------------------------------------------------------*/ +static void digitalWrite (int pin, int value) +{ + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] != -1) { + if (value == LOW) + write (lib->sysFds[pin], "0\n", 2); + else + write (lib->sysFds[pin], "1\n", 2); + } + return; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + if (value == LOW) + *(gpio + gpioToGPSETReg(pin)) &= ~(1 << gpioToShiftReg(pin)); + else + *(gpio + gpioToGPSETReg(pin)) |= (1 << gpioToShiftReg(pin)); +} + +/*----------------------------------------------------------------------------*/ +static int analogRead (int pin) +{ + unsigned char value[5] = {0,}; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + /* wiringPi ADC number = pin 25, pin 29 */ + switch (pin) { + case 0: case 25: + pin = 0; + break; + case 1: case 29: + pin = 1; + break; + default: + return 0; + } + if (adcFds [pin] == -1) + return 0; + + lseek (adcFds [pin], 0L, SEEK_SET); + read (adcFds [pin], &value[0], 4); + + return atoi(value); +} + +/*----------------------------------------------------------------------------*/ +static void digitalWriteByte (const 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; +} + +/*----------------------------------------------------------------------------*/ +static unsigned int digitalReadByte (void) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void) +{ + int fd; + + /* GPIO mmap setup */ + if (access("/dev/gpiomem",0) == 0) { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", + strerror (errno)) ; + } else { + if (geteuid () != 0) + return msg (MSG_ERR, + "wiringPiSetup: Must be root. (Did you forget sudo?)\n"); + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/mem: %s\n", + strerror (errno)) ; + } + //#define ODROIDC2_GPIO_BASE 0xC8834000 + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, ODROIDC2_GPIO_BASE) ; + + if ((int32_t)gpio == -1) + return msg (MSG_ERR, + "wiringPiSetup: mmap (GPIO) failed: %s\n", + strerror (errno)); +} + +/*----------------------------------------------------------------------------*/ +static void init_adc_fds (void) +{ + const char *AIN0_NODE, *AIN1_NODE; + + /* ADC node setup */ + AIN0_NODE = "/sys/class/saradc/ch0"; + AIN1_NODE = "/sys/class/saradc/ch1"; + + adcFds[0] = open(AIN0_NODE, O_RDONLY); + adcFds[1] = open(AIN1_NODE, O_RDONLY); +} + +/*----------------------------------------------------------------------------*/ +void init_odroidc2 (struct libodroid *libwiring) +{ + init_gpio_mmap(); + + init_adc_fds(); + + if (libwiring->rev == 1) { + pinToGpio = pinToGpio_rev1; + phyToGpio = phyToGpio_rev1; + } else { + pinToGpio = pinToGpio_rev2; + phyToGpio = phyToGpio_rev2; + } + + /* wiringPi Core function initialize */ + libwiring->getModeToGpio = getModeToGpio; + libwiring->pinMode = pinMode; + libwiring->getAlt = getAlt; + libwiring->pullUpDnControl = pullUpDnControl; + libwiring->digitalRead = digitalRead; + libwiring->digitalWrite = digitalWrite; + libwiring->analogRead = analogRead; + libwiring->digitalWriteByte = digitalWriteByte; + libwiring->digitalReadByte = digitalReadByte; + + /* global variable setup */ + lib = libwiring; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidc2.h b/wiringPi/odroidc2.h new file mode 100755 index 0000000..4c17e72 --- /dev/null +++ b/wiringPi/odroidc2.h @@ -0,0 +1,46 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi ODROID-C2 Board Header file + + */ +/*----------------------------------------------------------------------------*/ +#ifndef __ODROID_C2_H__ +#define __ODROID_C2_H__ + +/*----------------------------------------------------------------------------*/ +#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 + +#ifdef __cplusplus +extern "C" { +#endif + +extern void init_odroidc2 (struct libodroid *libwiring); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +#endif /* __ODROID_C2_H__ */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidn1.c b/wiringPi/odroidn1.c new file mode 100755 index 0000000..c04d84b --- /dev/null +++ b/wiringPi/odroidn1.c @@ -0,0 +1,270 @@ +/*----------------------------------------------------------------------------*/ +// +// +// WiringPi ODROID-N1 Board Control file (ROCKCHIP 64Bits Platform) +// +// +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "wiringOdroid.h" +#include "odroidn1.h" + +/*----------------------------------------------------------------------------*/ +// wiringPi gpio map define +/*----------------------------------------------------------------------------*/ +static const int pinToGpio[64] = { +#if 0 + // wiringPi number to native gpio number + ???, ???, // 0 | 1 : + ???, -1, // 2 | 3 : + ???, ???, // 4 | 5 : + ???, ???, // 6 | 7 : + -1, -1, // 8 | 9 : + ???, ???, // 10 | 11 : + ???, ???, // 12 | 13 : + ???, -1, // 14 | 15 : + -1, -1, // 16 | 17 : + -1, -1, // 18 | 19 : + -1, ???, // 20 | 21 : + ???, ???, // 22 | 23 : + ???, -1, // 24 | 25 : + ???, ???, // 26 | 27 : + -1, -1, // 28 | 29 : + -1, -1, // 30 | 31 : +#endif + // 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] = { +#if 0 + // physical header pin number to native gpio number + -1, // 0 + -1, -1, // 1 | 2 : + -1, -1, // 3 | 4 : + -1, -1, // 5 | 6 : + ???, -1, // 7 | 8 : + -1, -1, // 9 | 10 : + ???,???, // 11 | 12 : + ???, -1, // 13 | 14 : + -1, ???, // 15 | 16 : + -1, ???, // 17 | 18 : + ???, -1, // 19 | 20 : + ???,???, // 21 | 22 : + ???,???, // 23 | 24 : + -1, ???, // 25 | 26 : + -1, -1, // 27 | 28 : + ???, -1, // 29 | 30 : + ???,???, // 31 | 32 : + ???, -1, // 33 | 34 : + ???,???, // 35 | 36 : + -1, -1, // 37 | 38 : + -1, -1, // 39 | 40 : +#endif + // 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 char *adcFds[2]; + +/* GPIO mmap control */ +static volatile uint32_t *gpio, *gpio1; + +/* wiringPi Global library */ +static struct libodroid *lib = NULL; + +/*----------------------------------------------------------------------------*/ +// Function prototype define +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin); +static int gpioToGPLEVReg (int pin); +static int gpioToPUENReg (int pin); +static int gpioToPUPDReg (int pin); +static int gpioToShiftReg (int pin); +static int gpioToGPFSELReg (int pin); + +/*----------------------------------------------------------------------------*/ +// wiringPi core function +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin); +static void pinMode (int pin, int mode); +static int getAlt (int pin); +static void pullUpDnControl (int pin, int pud); +static int digitalRead (int pin); +static void digitalWrite (int pin, int value); +static int analogRead (int pin); +static void digitalWriteByte(const int value); +static unsigned int digitalReadByte (void); + +/*----------------------------------------------------------------------------*/ +// board init function +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void); +static void init_adc_fds (void); + + void init_odroidn1 (struct libodroid *libwiring); + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Set regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Input regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPLEVReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down enable regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUENReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUPDReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO bit +// +/*----------------------------------------------------------------------------*/ +static int gpioToShiftReg (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Function register +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPFSELReg (int pin) +{ + return -1; +} +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void pinMode (int pin, int mode) +{ +} + +/*----------------------------------------------------------------------------*/ +static int getAlt (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void pullUpDnControl (int pin, int pud) +{ +} + +/*----------------------------------------------------------------------------*/ +static int digitalRead (int pin) +{ +} + +/*----------------------------------------------------------------------------*/ +static void digitalWrite (int pin, int value) +{ +} + +/*----------------------------------------------------------------------------*/ +static int analogRead (int pin) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void digitalWriteByte (const int value) +{ +} + +/*----------------------------------------------------------------------------*/ +static unsigned int digitalReadByte (void) +{ + return -1; +} + +/*----------------------------------------------------------------------------*/ +static void init_gpio_mmap (void) +{ +} + +/*----------------------------------------------------------------------------*/ +static void init_adc_fds (void) +{ +} + +/*----------------------------------------------------------------------------*/ +void init_odroidn1 (struct libodroid *libwiring) +{ + init_gpio_mmap(); + + init_adc_fds(); + + /* wiringPi Core function initialize */ + libwiring->getModeToGpio = getModeToGpio; + libwiring->pinMode = pinMode; + libwiring->getAlt = getAlt; + libwiring->pullUpDnControl = pullUpDnControl; + libwiring->digitalRead = digitalRead; + libwiring->digitalWrite = digitalWrite; + libwiring->analogRead = analogRead; + libwiring->digitalWriteByte = digitalWriteByte; + libwiring->digitalReadByte = digitalReadByte; + + /* global variable setup */ + lib = libwiring; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidn1.h b/wiringPi/odroidn1.h new file mode 100755 index 0000000..c477f78 --- /dev/null +++ b/wiringPi/odroidn1.h @@ -0,0 +1,24 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi ODROID-N1 Board Header file + + */ +/*----------------------------------------------------------------------------*/ +#ifndef __ODROID_N1_H__ +#define __ODROID_N1_H__ + +/*----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + +extern void init_odroidn1 (struct libodroid *libwiring); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +#endif /* __ODROID_N1_H__ */ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidxu3.c b/wiringPi/odroidxu3.c new file mode 100755 index 0000000..6cdcccd --- /dev/null +++ b/wiringPi/odroidxu3.c @@ -0,0 +1,632 @@ +/*----------------------------------------------------------------------------*/ +// +// +// WiringPi ODROID-XU3/XU4 Board Control file +// +// +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "wiringOdroid.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 char *adcFds[2]; + +/* GPIO mmap control */ +static volatile uint32_t *gpio, *gpio1; + +/* wiringPi Global library */ +static struct libodroid *lib = NULL; + +/*----------------------------------------------------------------------------*/ +// Function prototype define +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin); +static int gpioToGPLEVReg (int pin); +static int gpioToPUENReg (int pin); +static int gpioToPUPDReg (int pin); +static int gpioToShiftReg (int pin); +static int gpioToGPFSELReg (int pin); + +/*----------------------------------------------------------------------------*/ +// wiringPi core function +/*----------------------------------------------------------------------------*/ +static int getModeToGpio (int mode, int pin); +static void pinMode (int pin, int mode); +static int getAlt (int pin); +static void pullUpDnControl (int pin, int pud); +static int digitalRead (int pin); +static void digitalWrite (int pin, int value); +static int analogRead (int pin); +static void digitalWriteByte(const 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 Set regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPSETReg (int pin) +{ + 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; + } + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Input regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPLEVReg (int pin) +{ + 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; + } + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down enable regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUENReg (int pin) +{ + msg(MSG_WARN, "%s : unused function in xu3/4. pin = %d\n", + __func__, pin); + return 0; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Pull up/down regsiter +// +/*----------------------------------------------------------------------------*/ +static int gpioToPUPDReg (int pin) +{ + 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; + } + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO bit +// +/*----------------------------------------------------------------------------*/ +static int gpioToShiftReg (int pin) +{ + 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; + } + return -1; +} + +/*----------------------------------------------------------------------------*/ +// +// offset to the GPIO Function register +// +/*----------------------------------------------------------------------------*/ +static int gpioToGPFSELReg (int pin) +{ + 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; + } + 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 void pinMode (int pin, int mode) +{ + int fsel, shift, origPin = pin; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + 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); + 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 SOFT_PWM_OUTPUT: + softPwmCreate (pin, 0, 100); + break; + case SOFT_TONE_OUTPUT: + softToneCreate (pin); + break; + default: + msg(MSG_WARN, "%s : Unknown Mode %d\n", __func__, mode); + break; + } +} + +/*----------------------------------------------------------------------------*/ +static int getAlt (int pin) +{ + int fsel, shift; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 2; + + shift = gpioToShiftReg(pin) << 2; + + 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; +} + +/*----------------------------------------------------------------------------*/ +static void pullUpDnControl (int pin, int pud) +{ + int shift = 0; + + if (lib->mode == MODE_GPIO_SYS) + return; + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + 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); + } +} + +/*----------------------------------------------------------------------------*/ +static int digitalRead (int pin) +{ + char c ; + + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] == -1) + return LOW ; + + lseek (lib->sysFds[pin], 0L, SEEK_SET); + read (lib->sysFds[pin], &c, 1); + + return (c == '0') ? LOW : HIGH; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return 0; + + if (pin < 100) + return *(gpio + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : LOW; + else + return *(gpio1 + gpioToGPLEVReg(pin)) & (1 << gpioToShiftReg(pin)) ? HIGH : LOW; +} + +/*----------------------------------------------------------------------------*/ +static void digitalWrite (int pin, int value) +{ + if (lib->mode == MODE_GPIO_SYS) { + if (lib->sysFds[pin] != -1) { + if (value == LOW) + write (lib->sysFds[pin], "0\n", 2); + else + write (lib->sysFds[pin], "1\n", 2); + } + return; + } + + if ((pin = getModeToGpio(lib->mode, pin)) < 0) + return; + + 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)); + } +} + +/*----------------------------------------------------------------------------*/ +static int analogRead (int pin) +{ + unsigned char value[5] = {0,}; + + if (lib->mode == MODE_GPIO_SYS) + return 0; + + /* wiringPi ADC number = pin 25, pin 29 */ + switch (pin) { + case 0: case 25: + pin = 0; + break; + case 1: case 29: + pin = 1; + break; + default: + return 0; + } + if (adcFds [pin] == -1) + return 0; + + lseek (adcFds [pin], 0L, SEEK_SET); + read (adcFds [pin], &value[0], 4); + + return atoi(value); +} + +/*----------------------------------------------------------------------------*/ +static void digitalWriteByte (const int value) +{ + union reg_bitfield gpx1, gpx2, gpa0; + + if (lib->mode == MODE_GPIO_SYS) { + return; + } + /* 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; +} + +/*----------------------------------------------------------------------------*/ +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 + (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 */ + 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; + + /* GPIO mmap setup */ + if (access("/dev/gpiomem",0) == 0) { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", + strerror (errno)) ; + } else { + if (geteuid () != 0) + return msg (MSG_ERR, + "wiringPiSetup: Must be root. (Did you forget sudo?)\n"); + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return msg (MSG_ERR, + "wiringPiSetup: Unable to open /dev/mem: %s\n", + strerror (errno)) ; + } + //#define ODROIDXU_GPX_BASE 0x13400000 // GPX0,1,2,3 + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, ODROIDXU3_GPX_BASE) ; + //#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, ODROIDXU3_GPA_BASE) ; + if (((int32_t)gpio == -1) || ((int32_t)gpio1 == -1)) + return msg (MSG_ERR, + "wiringPiSetup: mmap (GPIO) failed: %s\n", + strerror (errno)); +} + +/*----------------------------------------------------------------------------*/ +static void init_adc_fds (void) +{ + const char *AIN0_NODE, *AIN1_NODE; + struct utsname uname_buf; + + /* ADC node setup */ + uname(&uname_buf); + if (strncmp(uname_buf.release, "4.14", 4) == 0) { + 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 (strncmp(uname_buf.release, "4.9", 3) == 0) { + 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->pinMode = pinMode; + libwiring->getAlt = getAlt; + libwiring->pullUpDnControl = pullUpDnControl; + libwiring->digitalRead = digitalRead; + libwiring->digitalWrite = digitalWrite; + libwiring->analogRead = analogRead; + libwiring->digitalWriteByte = digitalWriteByte; + libwiring->digitalReadByte = digitalReadByte; + + /* global variable setup */ + lib = libwiring; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/odroidxu3.h b/wiringPi/odroidxu3.h new file mode 100755 index 0000000..9ab31af --- /dev/null +++ b/wiringPi/odroidxu3.h @@ -0,0 +1,68 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi ODROID-XU3/XU4 Board Header file + + */ +/*----------------------------------------------------------------------------*/ +#ifndef __ODROID_XU3_H__ +#define __ODROID_XU3_H__ + +/*----------------------------------------------------------------------------*/ +#define ODROIDXU3_GPIO_MASK (0xFFFFFF00) + +// GPX0,1,2,3 +#define ODROIDXU3_GPX_BASE 0x13400000 + +#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 + +// GPA0,1,2, GPB0,1,2,3,4 +#define ODROIDXU3_GPA_BASE 0x14010000 + +#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 + +#ifdef __cplusplus +extern "C" { +#endif + +extern void init_odroidxu3 (struct libodroid *libwiring); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +#endif /* __ODROID_XU3_H__ */ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/wiringOdroid.c b/wiringPi/wiringOdroid.c new file mode 100755 index 0000000..1e5f902 --- /dev/null +++ b/wiringPi/wiringOdroid.c @@ -0,0 +1,890 @@ +/*----------------------------------------------------------------------------*/ +/* + + WiringPi Library for ODROIDs + + */ +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#include "softPwm.h" +#include "softTone.h" + +/*----------------------------------------------------------------------------*/ +#include "wiringPi.h" +#include "../version.h" + +#include "wiringOdroid.h" + +#include "odroidc1.h" +#include "odroidc2.h" +#include "odroidxu3.h" +#include "odroidn1.h" + +/*----------------------------------------------------------------------------*/ +// Const string define +/*----------------------------------------------------------------------------*/ +const char *piModelNames [16] = +{ + "Unknown", + "ODROID-C1/C1+", + "ODROID-C2", + "ODROID-XU3/4", + "ODROID-N1", +} ; + +const char *piRevisionNames [16] = +{ + "00", + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", +} ; + +const char *piMakerNames [16] = +{ + "Unknown", // 0 + "AMLogic", // 1 + "SAMSUNG", // 2 + "ROCKCHIP", // 3 + "INTEL", // 4 + "AMD", // 5 + "Unknown06", // 6 + "Unknown07", // 7 + "Unknown08", // 8 + "Unknown09", // 9 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; + +const int piMemorySize [8] = +{ + 256, // 0 + 512, // 1 + 1024, // 2 + 2048, // 3 + 4096, // 4 + 8192, // 5 + 0, // 6 + 0, // 7 +} ; + +/*----------------------------------------------------------------------------*/ +// Misc +static volatile int pinPass = -1 ; +static pthread_mutex_t pinMutex ; + +// Debugging & Return codes +int wiringPiDebug = FALSE ; +int wiringPiReturnCodes = FALSE ; + +// ODROID Wiring Library +struct libodroid libwiring; + +/*----------------------------------------------------------------------------*/ +// +// ODROID System Message function +// +/*----------------------------------------------------------------------------*/ +int msg (int type, const char *message, ...) +{ + va_list argp; + char buffer [1024]; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp); + va_end (argp) ; + + fprintf (stderr, "%s:%s", type == MSG_WARN ? "warn" : "err", buffer) ; + + if (type != MSG_WARN) + exit (EXIT_FAILURE) ; + return 0 ; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +// +// Unsupport Function list on ODROIDs +// +/*----------------------------------------------------------------------------*/ +static void piGpioLayoutOops (const char *why) { return; } + void setPadDrive (int group, int value) { return; } + void pwmSetMode (int mode) { return; } + void pwmSetRange (unsigned int range) { return; } + void pwmSetClock (int divisor) { return; } + void gpioClockSet (int pin, int freq) { return; } + + /* core unsupport function */ + void pinModeAlt (int pin, int mode) { return; } + void pwmWrite (int pin, int value) { return; } + void analogWrite (int pin, int value) { return; } + void pwmToneWrite (int pin, int freq) { return; } + void digitalWriteByte2 (const int value) { return; } + unsigned int digitalReadByte2 (void) { return -1; } +/*----------------------------------------------------------------------------*/ +// Extend wiringPi with other pin-based devices and keep track of +// them in this structure +/*----------------------------------------------------------------------------*/ +struct wiringPiNodeStruct *wiringPiNodes = NULL ; + +struct wiringPiNodeStruct *wiringPiFindNode (int pin) { return NULL; } + +static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } +static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } +static unsigned int digitalRead8Dummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return 0 ; } +static void digitalWrite8Dummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } +static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } +static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } + +struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) +{ + int pin ; + struct wiringPiNodeStruct *node ; + + // Minimum pin base is 64 + if (pinBase < 64) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ; + + // Check all pins in-case there is overlap: + for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin) + if (wiringPiFindNode (pin) != NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ; + + node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros + if (node == NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ; + + node->pinBase = pinBase ; + node->pinMax = pinBase + numPins - 1 ; + node->pinMode = pinModeDummy ; + node->pullUpDnControl = pullUpDnControlDummy ; + node->digitalRead = digitalReadDummy ; + //node->digitalRead8 = digitalRead8Dummy ; + node->digitalWrite = digitalWriteDummy ; + //node->digitalWrite8 = digitalWrite8Dummy ; + node->pwmWrite = pwmWriteDummy ; + node->analogRead = analogReadDummy ; + node->analogWrite = analogWriteDummy ; + node->next = wiringPiNodes ; + wiringPiNodes = node ; + + return node ; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* + * wiringPiFailure: + * Fail. Or not. + */ +/*----------------------------------------------------------------------------*/ +int wiringPiFailure (int fatal, const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + if (!fatal && wiringPiReturnCodes) + return -1 ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + fprintf (stderr, "%s", buffer); + exit (EXIT_FAILURE); + + return 0 ; +} + +/*----------------------------------------------------------------------------*/ +int piGpioLayout (void) +{ + FILE *cpuFd ; + char line [120] ; + char *c ; + static int gpioLayout = -1 ; + + if (gpioLayout != -1) + return gpioLayout; + + gpioLayout = 1; + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + wiringPiFailure (WPI_FATAL, "Unable to open /proc/cpuinfo") ; + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Hardware", 8) == 0) + break ; + + if (strncmp (line, "Hardware", 8) != 0) + wiringPiFailure (WPI_FATAL, "No \"Hardware\" line") ; + + if (wiringPiDebug) + printf ("piGpioLayout: Hardware: %s\n", line) ; + + if (!(strstr (line, "ODROID"))) + wiringPiFailure (WPI_FATAL, "** This board is not ODROID. **") ; + + rewind (cpuFd) ; + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + fclose (cpuFd) ; + + if (strncmp (line, "Revision", 8) != 0) + wiringPiFailure (WPI_FATAL, "No \"Revision\" line") ; + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (wiringPiDebug) + printf ("piGpioLayout: Revision string: %s\n", line) ; + + // Scan to the first character of the revision number + for (c = line ; *c ; ++c) + if (*c == ':') + break ; + + if (*c != ':') + wiringPiFailure (WPI_FATAL, "Bogus \"Revision\" line (no colon)") ; + + // Chomp spaces + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + wiringPiFailure (WPI_FATAL, "Bogus \"Revision\" line (no hex digit at start of revision)") ; + + // Make sure its long enough + if (strlen (c) < 4) + wiringPiFailure (WPI_FATAL, "Bogus revision line (too small)") ; + + // Isolate last 4 characters: (in-case of overvolting or new encoding scheme) + c = c + strlen (c) - 4 ; + + if (wiringPiDebug) + printf ("piGpioLayout: last4Chars are: \"%s\"\n", c) ; + + if ((strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0) || + (strcmp (c, "000a") == 0) || (strcmp (c, "0100") == 0) ) + gpioLayout = 1; + else + gpioLayout = 2; + + if (strcmp (c, "000a") == 0) { + libwiring.model = MODEL_ODROID_C1; + libwiring.maker = MAKER_AMLOGIC; + libwiring.mem = 2; + libwiring.rev = 1; + } else if (strcmp (c, "0100") == 0) { + libwiring.model = MODEL_ODROID_XU3; + libwiring.maker = MAKER_SAMSUNG; + libwiring.mem = 3; + libwiring.rev = 1; + } else if (strncmp (c, "02", 2) == 0) { + libwiring.model = MODEL_ODROID_C2; + libwiring.maker = MAKER_AMLOGIC; + libwiring.mem = 3; + { + int fd = 0; + char buf[2]; + + if ((fd = open ("/sys/class/odroid/boardrev", O_RDONLY)) < 0) { + printf ("ERROR : file not found.(boardrev)\n"); + libwiring.rev = 1; + } else { + (void)read (fd, buf, sizeof(buf)); + close(fd); + libwiring.rev = atoi(buf) + 1; + } + } + } else if (strcmp (c, "0300") == 0) { + libwiring.model = MODEL_ODROID_N1; + libwiring.maker = MAKER_ROCKCHIP; + libwiring.mem = 4; + libwiring.rev = 1; + } else { + libwiring.model = MODEL_UNKNOWN; + libwiring.maker = MAKER_UNKNOWN; + libwiring.mem = 0; + libwiring.rev = 0; + } + + if (wiringPiDebug) + printf ("BoardRev: Returning revision: %d\n", libwiring.rev) ; + + return libwiring.rev; +} + +/*----------------------------------------------------------------------------*/ +int piBoardRev (void) +{ + return piGpioLayout (); +} + +/*----------------------------------------------------------------------------*/ +/* + * piBoardId: + * Return the real details of the board we have. + * + * 000a - Model ODROID C0/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) + * 0300 - Model ODROID N1, 4096M, Hardkernel + */ +/*----------------------------------------------------------------------------*/ +void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) +{ + // Call this first to make sure all's OK. Don't care about the result. + (void)piGpioLayout () ; + + *model = libwiring.model; + *maker = libwiring.maker; + *rev = libwiring.rev; + *mem = libwiring.mem; + *warranty = 1; +} + +/*----------------------------------------------------------------------------*/ +/* + * wpiPinToGpio: + * Translate a wiringPi Pin number to native GPIO pin number. + * Provided for external support. + */ +/*----------------------------------------------------------------------------*/ +int wpiPinToGpio (int wpiPin) +{ + if (libwiring.getModeToGpio) + return libwiring.getModeToGpio(WPI_MODE_PINS, wpiPin); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +/* + * physPinToGpio: + * Translate a physical Pin number to native GPIO pin number. + * Provided for external support. + */ +/*----------------------------------------------------------------------------*/ +int physPinToGpio (int physPin) +{ + if (libwiring.getModeToGpio) + return libwiring.getModeToGpio(WPI_MODE_PHYS, physPin); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +/* + * getAlt: + * Returns the ALT bits for a given port. Only really of-use + * for the gpio readall command (I think) + */ +/*----------------------------------------------------------------------------*/ +int getAlt (int pin) +{ + if (libwiring.getAlt) + return libwiring.getAlt(pin); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +/* + * Core Functions + */ +/*----------------------------------------------------------------------------*/ +void pinMode (int pin, int mode) +{ + if (libwiring.pinMode) + return libwiring.pinMode(pin, mode); + +} + +/*----------------------------------------------------------------------------*/ +void pullUpDnControl (int pin, int pud) +{ + if (libwiring.pullUpDnControl) + return libwiring.pullUpDnControl(pin, pud); +} + +/*----------------------------------------------------------------------------*/ +int digitalRead (int pin) +{ + if (libwiring.digitalRead) + return libwiring.digitalRead(pin); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +void digitalWrite (int pin, int value) +{ + if (libwiring.digitalWrite) + return libwiring.digitalWrite(pin, value); +} + +/*----------------------------------------------------------------------------*/ +int analogRead (int pin) +{ + if (libwiring.analogRead) + return libwiring.analogRead(pin); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +void digitalWriteByte (const int value) +{ + if (libwiring.digitalWriteByte) + return libwiring.digitalWriteByte(value); +} + +/*----------------------------------------------------------------------------*/ +unsigned int digitalReadByte (void) +{ + if (libwiring.digitalReadByte) + return libwiring.digitalReadByte(); + + return -1; +} + +/*----------------------------------------------------------------------------*/ +int waitForInterrupt (int pin, int mS) +{ + int fd, x; + uint8_t c; + struct pollfd polls; + + if (libwiring.getModeToGpio) + pin = libwiring.getModeToGpio(libwiring.mode, pin); + else + return -2; + + if ((fd = libwiring.sysFds[pin]) == -1) + return -2; + + // Setup poll structure + polls.fd = fd ; + polls.events = POLLPRI | POLLERR ; + + // Wait for it ... + x = poll (&polls, 1, mS) ; + + // If no error, do a dummy read to clear the interrupt + // A one character read appars to be enough. + if (x > 0) { + lseek (fd, 0, SEEK_SET) ; // Rewind + (void)read (fd, &c, 1) ; // Read & clear + } + return x ; +} + +/*----------------------------------------------------------------------------*/ +static void *interruptHandler (UNU void *arg) +{ + int myPin ; + + (void)piHiPri (55) ; // Only effective if we run as root + + myPin = pinPass ; + pinPass = -1 ; + + for (;;) + if (waitForInterrupt (myPin, -1) > 0) + libwiring.isrFunctions [myPin] () ; + + return NULL ; +} + +/*----------------------------------------------------------------------------*/ +int wiringPiISR (int pin, int mode, void (*function)(void)) +{ + pthread_t threadId; + const char *modeS; + char fName [64]; + char pinS [8]; + pid_t pid; + int count, i; + char c; + int GpioPin; + + if (libwiring.mode == WPI_MODE_UNINITIALISED) + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: wiringPi has not been initialised. " \ + "Unable to continue.\n") ; + + if (libwiring.getModeToGpio) + GpioPin = libwiring.getModeToGpio(libwiring.mode, pin); + else + return wiringPiFailure ( + WPI_FATAL, + "%s: getModeToGpio function not initialize!\n", + __func__); + + // Now export the pin and set the right edge + // We're going to use the gpio program to do this, so it assumes + // a full installation of wiringPi. It's a bit 'clunky', but it + // is a way that will work when we're running in "Sys" mode, as + // a non-root user. (without sudo) + if (mode != INT_EDGE_SETUP) + { + if (mode == INT_EDGE_FALLING) + modeS = "falling" ; + else if (mode == INT_EDGE_RISING) + modeS = "rising" ; + else + modeS = "both" ; + + sprintf (pinS, "%d", GpioPin) ; + + if ((pid = fork ()) < 0) // Fail + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: fork failed: %s\n", + strerror (errno)); + + // Child, exec + if (pid == 0) { + if (access ("/usr/local/bin/gpio", X_OK) == 0) { + execl ("/usr/local/bin/gpio", "gpio", "edge", + pinS, modeS, (char *)NULL) ; + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: execl failed: %s\n", + strerror (errno)); + } else if (access ("/usr/bin/gpio", X_OK) == 0) { + execl ("/usr/bin/gpio", "gpio", "edge", + pinS, modeS, (char *)NULL) ; + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: execl failed: %s\n", + strerror (errno)); + } else + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: Can't find gpio program\n"); + } + else // Parent, wait + wait (NULL) ; + } + + // Now pre-open the /sys/class node - but it may already be open if + // we are in Sys mode... + if (libwiring.sysFds [GpioPin] == -1) { + sprintf (fName, "/sys/class/gpio/gpio%d/value", GpioPin) ; + if ((libwiring.sysFds [GpioPin] = open (fName, O_RDWR)) < 0) + return wiringPiFailure ( + WPI_FATAL, + "wiringPiISR: unable to open %s: %s\n", + fName, strerror (errno)) ; + } + + // Clear any initial pending interrupt + ioctl (libwiring.sysFds [GpioPin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i) + (void)read (libwiring.sysFds [GpioPin], &c, 1) ; + + libwiring.isrFunctions [GpioPin] = function ; + + pthread_mutex_lock (&pinMutex) ; + pinPass = GpioPin ; + pthread_create (&threadId, NULL, interruptHandler, NULL) ; + while (pinPass != -1) + delay (1) ; + pthread_mutex_unlock (&pinMutex) ; + + return 0 ; +} + +/*----------------------------------------------------------------------------*/ +static void initialiseEpoch (void) +{ +#ifdef OLD_WAY + struct timeval tv; + + gettimeofday (&tv, NULL) ; + libwiring.epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + + (uint64_t)(tv.tv_usec / 1000) ; + libwiring.epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + + (uint64_t)(tv.tv_usec) ; +#else + struct timespec ts; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; + libwiring.epochMilli = (uint64_t)ts.tv_sec * (uint64_t)1000 + + (uint64_t)(ts.tv_nsec / 1000000L) ; + libwiring.epochMicro = (uint64_t)ts.tv_sec * (uint64_t)1000000 + + (uint64_t)(ts.tv_nsec / 1000L) ; +#endif +} + +/*----------------------------------------------------------------------------*/ +void delay (unsigned int howLong) +{ + struct timespec sleeper, dummy; + + sleeper.tv_sec = (time_t)(howLong / 1000) ; + sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ; + + nanosleep (&sleeper, &dummy) ; +} + +/*----------------------------------------------------------------------------*/ +void delayMicrosecondsHard (unsigned int howLong) +{ + struct timeval tNow, tLong, tEnd; + + gettimeofday (&tNow, NULL) ; + tLong.tv_sec = howLong / 1000000 ; + tLong.tv_usec = howLong % 1000000 ; + timeradd (&tNow, &tLong, &tEnd) ; + + while (timercmp (&tNow, &tEnd, <)) + gettimeofday (&tNow, NULL) ; +} + +/*----------------------------------------------------------------------------*/ +void delayMicroseconds (unsigned int howLong) +{ + struct timespec sleeper; + unsigned int uSecs = howLong % 1000000; + unsigned int wSecs = howLong / 1000000; + + if (howLong == 0) + return ; + else if (howLong < 100) + delayMicrosecondsHard (howLong); + else { + sleeper.tv_sec = wSecs; + sleeper.tv_nsec = (long)(uSecs * 1000L); + nanosleep (&sleeper, NULL); + } +} + +/*----------------------------------------------------------------------------*/ +unsigned int millis (void) +{ + uint64_t now; + +#ifdef OLD_WAY + struct timeval tv; + + gettimeofday (&tv, NULL); + now = (uint64_t)tv.tv_sec * (uint64_t)1000 + + (uint64_t)(tv.tv_usec / 1000); +#else + struct timespec ts; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts); + now = (uint64_t)ts.tv_sec * (uint64_t)1000 + + (uint64_t)(ts.tv_nsec / 1000000L); +#endif + return (uint32_t)(now - libwiring.epochMilli); +} + +/*----------------------------------------------------------------------------*/ +unsigned int micros (void) +{ + uint64_t now; +#ifdef OLD_WAY + struct timeval tv; + + gettimeofday (&tv, NULL); + now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + + (uint64_t)tv.tv_usec; +#else + struct timespec ts; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; + now = (uint64_t)ts.tv_sec * (uint64_t)1000000 + + (uint64_t)(ts.tv_nsec / 1000); +#endif + return (uint32_t)(now - libwiring.epochMicro); +} + +/*----------------------------------------------------------------------------*/ +void wiringPiVersion (int *major, int *minor) +{ + *major = VERSION_MAJOR ; + *minor = VERSION_MINOR ; +} + +/*----------------------------------------------------------------------------*/ +int wiringPiSetup (void) +{ + int i; + static int alreadyDoneThis = FALSE; + + if (alreadyDoneThis) + return 0; + + alreadyDoneThis = TRUE; + + // libwiring init + memset(&libwiring, 0x00, sizeof(struct libodroid)); + // sysFds init + for(i = 0; i < 256; i++) + libwiring.sysFds[i] = -1; + // init wiringPi mode + libwiring.mode = WPI_MODE_UNINITIALISED; + + if (getenv (ENV_DEBUG) != NULL) + wiringPiDebug = TRUE; + + if (getenv (ENV_CODES) != NULL) + wiringPiReturnCodes = TRUE; + + (void)piGpioLayout(); + + if (wiringPiDebug) { + printf ("wiringPi: wiringPiSetup called\n") ; + printf ("Model Name : %s\n", piModelNames[libwiring.model]); + printf ("Model Maker : %s\n", piMakerNames[libwiring.maker]); + printf ("Model MEM : %d\n", libwiring.mem); + printf ("Model REV : %d\n", libwiring.rev); + } + + switch (libwiring.model) { + case MODEL_ODROID_C1: + case MODEL_ODROID_C2: + case MODEL_ODROID_XU3: + init_odroidxu3(&libwiring); + break; + case MODEL_ODROID_N1: + init_odroidn1(&libwiring); + break; + default: + return wiringPiFailure (WPI_ALMOST, + "wiringPiSetup: Unknown model\n"); + } + + initialiseEpoch (); + + libwiring.mode = WPI_MODE_PINS; + return 0; +} + +/*----------------------------------------------------------------------------*/ +/* + * wiringPiSetupGpio: + * Must be called once at the start of your program execution. + * + * GPIO setup: Initialises the system into GPIO Pin mode and uses the + * memory mapped hardware directly. + */ +/*----------------------------------------------------------------------------*/ +int wiringPiSetupGpio (void) +{ + (void)wiringPiSetup (); + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupGpio called\n") ; + + libwiring.mode = WPI_MODE_GPIO; + return 0 ; +} + +/*----------------------------------------------------------------------------*/ +/* + * wiringPiSetupPhys: + * Must be called once at the start of your program execution. + * + * Phys setup: Initialises the system into Physical Pin mode and uses the + * memory mapped hardware directly. + */ +/*----------------------------------------------------------------------------*/ +int wiringPiSetupPhys (void) +{ + (void)wiringPiSetup () ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupPhys called\n") ; + + libwiring.mode = WPI_MODE_PHYS ; + return 0 ; +} + +/*----------------------------------------------------------------------------*/ +/* + * wiringPiSetupSys: + * Must be called once at the start of your program execution. + * + * Initialisation (again), however this time we are using the /sys/class/gpio + * interface to the GPIO systems - slightly slower, but always usable as + * a non-root user, assuming the devices are already exported and setup correctly. + */ +/*----------------------------------------------------------------------------*/ +int wiringPiSetupSys (void) +{ + int pin ; + char fName [128] ; + + (void)wiringPiSetup(); + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupSys called\n"); + + // 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 < 256 ; ++pin) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin); + libwiring.sysFds [pin] = open (fName, O_RDWR); + } + + initialiseEpoch (); + + libwiring.mode = WPI_MODE_GPIO_SYS; + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/wiringOdroid.h b/wiringPi/wiringOdroid.h new file mode 100755 index 0000000..48c2885 --- /dev/null +++ b/wiringPi/wiringOdroid.h @@ -0,0 +1,168 @@ +/* + * wiringPi.h: + * Arduino like Wiring library for the Raspberry Pi. + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * 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 . + *********************************************************************** + */ +/*----------------------------------------------------------------------------*/ +#ifndef __WIRING_ODROID_H__ +#define __WIRING_ODROID_H__ + +/*----------------------------------------------------------------------------*/ +#include +#include +#include +#include + +/*----------------------------------------------------------------------------*/ +#define ENV_DEBUG "WIRINGPI_DEBUG" +#define ENV_CODES "WIRINGPI_CODES" +#define ENV_GPIOMEM "WIRINGPI_GPIOMEM" + +#define MODEL_UNKNOWN 0 +#define MODEL_ODROID_C1 1 +#define MODEL_ODROID_C2 2 +#define MODEL_ODROID_XU3 3 +#define MODEL_ODROID_N1 4 + +#define MAKER_UNKNOWN 0 +#define MAKER_AMLOGIC 1 +#define MAKER_SAMSUNG 2 +#define MAKER_ROCKCHIP 3 + +#define MODE_PINS 0 +#define MODE_GPIO 1 +#define MODE_GPIO_SYS 2 +#define MODE_PHYS 3 +#define MODE_PIFACE 4 +#define MODE_UNINITIALISED -1 + +// Pin modes +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 +#define GPIO_CLOCK 3 +#define SOFT_PWM_OUTPUT 4 +#define SOFT_TONE_OUTPUT 5 +#define PWM_TONE_OUTPUT 6 + +#define LOW 0 +#define HIGH 1 + +// Pull up/down/none +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +/*----------------------------------------------------------------------------*/ +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +/*----------------------------------------------------------------------------*/ +/* Debuf message display function */ +/*----------------------------------------------------------------------------*/ +#define MSG_ERR -1 +#define MSG_WARN -2 + +/*----------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------------------------*/ +// Export function define +/*----------------------------------------------------------------------------*/ +extern int msg (int type, const char *message, ...); + +#ifdef __cplusplus +} +#endif + +/*----------------------------------------------------------------------------*/ +struct libodroid +{ + /* H/W model info */ + int model, rev, mem, maker; + + /* wiringPi init Mode */ + int mode; + + /* wiringPi core func */ + int (*getModeToGpio) (int mode, int pin); + void (*pinMode) (int pin, int mode); + int (*getAlt) (int pin); + void (*pullUpDnControl) (int pin, int pud); + int (*digitalRead) (int pin); + void (*digitalWrite) (int pin, int value); + int (*analogRead) (int pin); + void (*digitalWriteByte) (const int value); + unsigned int (*digitalReadByte) (void); + + /* ISR Function pointer */ + void (*isrFunctions[256])(void); + + /* GPIO sysfs file discripter */ + int sysFds[256]; + + // Time for easy calculations + uint64_t epochMilli, epochMicro ; +}; + +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; +}; + +/*----------------------------------------------------------------------------*/ +#endif /* __WIRING_ODROID_H__ */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c old mode 100644 new mode 100755 index b0ee5d3..6cd216e --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -216,6 +216,32 @@ int wiringPiI2CSetupInterface (const char *device, int devId) * Open the I2C device, and regsiter the target device ********************************************************************************* */ +#if defined(BOARD_ODROID) + +#include "wiringOdroid.h" + +int wiringPiI2CSetup (const int devId) +{ + int model, rev, mem, maker, overVolted ; + const char *device = NULL; + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + switch(model) { + case MODEL_ODROID_C1: case MODEL_ODROID_C2: + device = "/dev/i2c-1"; + break; + case MODEL_ODROID_XU3: + device = "/dev/i2c-4"; + break; + case MODEL_ODROID_N1: + break; + } + + return wiringPiI2CSetupInterface (device, devId) ; +} + +#else int wiringPiI2CSetup (const int devId) { @@ -231,3 +257,5 @@ int wiringPiI2CSetup (const int devId) return wiringPiI2CSetupInterface (device, devId) ; } + +#endif // #defined(BOARD_ODROID) diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c old mode 100644 new mode 100755 index 022b99f..5feed2f --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -97,6 +97,61 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ********************************************************************************* */ +#if defined(BOARD_ODROID) + +#include "wiringOdroid.h" + +int wiringPiSPISetupMode (int channel, int speed, int mode) +{ + int fd ; + int model, rev, mem, maker, overVolted ; + const char *device ; + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + mode &= 3 ; // Mode is 0, 1, 2 or 3 + channel &= 1 ; // Channel is 0 or 1 + + if (channel || model == MODEL_ODROID_C2) { + return wiringPiFailure (WPI_ALMOST, + "Can't support spi device. check model or spi channel.\n"); + } + + switch(model) { + case MODEL_ODROID_C1: + device = "/dev/spidev0.0"; + break; + case MODEL_ODROID_XU3: + device = "/dev/spidev1.0"; + break; + case MODEL_ODROID_N1: + break; + } + + if ((fd = open (device, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, + "Unable to open SPI device: %s\n", strerror (errno)); + + spiSpeeds [channel] = speed ; + spiFds [channel] = fd ; + + // Set SPI parameters. + if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0) + return wiringPiFailure (WPI_ALMOST, + "SPI Mode Change failure: %s\n", strerror (errno)) ; + + if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) + return wiringPiFailure (WPI_ALMOST, + "SPI BPW Change failure: %s\n", strerror (errno)) ; + + if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) + return wiringPiFailure (WPI_ALMOST, + "SPI Speed Change failure: %s\n", strerror (errno)) ; + return fd ; +} + +#else + int wiringPiSPISetupMode (int channel, int speed, int mode) { int fd ; @@ -124,6 +179,7 @@ int wiringPiSPISetupMode (int channel, int speed, int mode) return fd ; } +#endif // #defined(BOARD_ODROID) /* * wiringPiSPISetup: