//------------------------------------------------------------------------------------------------------------ // // ODROID-C1 GPIO Status Check Application. // // Compile : gcc -o // Run : sudo ./ // //------------------------------------------------------------------------------------------------------------ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //------------------------------------------------------------------------------ // // Global handle Define // //------------------------------------------------------------------------------ // MMAP Address for GPIO #define GPIO_REG_MAP 0xC1108000 #define GPIO_AO_REG_MAP 0xC8100000 #define BLOCK_SIZE (4*1024) static volatile unsigned int *gpio; static volatile unsigned int *gpio_ao; static volatile unsigned int *ao_in; //------------------------------------------------------------------------------ // refer kernel/arch/arm/mach-meson8b/include/mach/gpio.h #define GPIOAO_PIN_START 0 #define GPIOAO_PIN_END 13 #define GPIOAO_FSEL_REG_OFFSET 0x09 #define GPIOAO_OUTP_REG_OFFSET 0x09 #define GPIOAO_INP_REG_OFFSET 0x0A #define GPIOAO_PUPD_REG_OFFSET 0x0B #define GPIOAO_PUEN_REG_OFFSET 0x0B //------------------------------------------------------------------------------ #define GPIODV_PIN_START 50 #define GPIODV_PIN_END 79 #define GPIODV_FSEL_REG_OFFSET 0x12 #define GPIODV_OUTP_REG_OFFSET 0x13 #define GPIODV_INP_REG_OFFSET 0x14 #define GPIODV_PUPD_REG_OFFSET 0x3A #define GPIODV_PUEN_REG_OFFSET 0x48 //------------------------------------------------------------------------------ #define GPIOY_PIN_START 80 #define GPIOY_PIN_END 96 #define GPIOY_FSEL_REG_OFFSET 0x0F #define GPIOY_OUTP_REG_OFFSET 0x10 #define GPIOY_INP_REG_OFFSET 0x11 #define GPIOY_PUPD_REG_OFFSET 0x3D #define GPIOY_PUEN_REG_OFFSET 0x4B //------------------------------------------------------------------------------ #define 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 MUX_REG0 0x5 // MUX_AO Block #define MUX_REG1 0x2D #define MUX_REG2 0x2E #define MUX_REG3 0x2F #define MUX_REG4 0x30 #define MUX_REG5 0x31 #define MUX_REG6 0x32 #define MUX_REG7 0x33 #define MUX_REG8 0x34 #define MUX_REG9 0x35 //------------------------------------------------------------------------------ #define BIT(x) (1 << x) //------------------------------------------------------------------------------ const char MODE_STR[8][5] = { " - ", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "IN", "OUT", }; //------------------------------------------------------------------------------ const char PUPD_STR[3][5] = { " - ", "P/U", "P/D", }; //------------------------------------------------------------------------------ struct header_info { int gpio; char name[10]; }; //------------------------------------------------------------------------------ const struct header_info header_J2[40] = { { -1, "3.3V" }, { -1, "5.0V" }, { 74, "I2CA_SDA" }, { -1, "5.0V" }, { 75, "I2CA_SCL" }, { -1, "GND" }, { 83, "GPIOY.3" }, { 113, "GPIOX.16" }, { -1, "GND" }, { 114, "GPIOX.17" }, { 88, "GPIOY.8" }, { 87, "GPIOY.7" }, { 116, "GPIOX.19" }, { -1, "GND" }, { 115, "GPIOX.18" }, { 104, "GPIOX.7" }, { -1, "3.3V" }, { 102, "GPIOX.5" }, { 107, "GPIOX.10" }, { -1, "GND" }, { 106, "GPIOX.9" }, { 103, "GPIOX.6" }, { 105, "GPIOX.8" }, { 117, "GPIOX.20" }, { -1, "GND" }, { 118, "GPIOX.21" }, { 76, "I2CB_SDA" }, { 77, "I2CB_SCL" }, { 101, "GPIOX.4" }, { -1, "GND" }, { 100, "GPIOX.3" }, { 99, "GPIOX.2" }, { 108, "GPIOX.11" }, { -1, "GND" }, { 97, "GPIOX.0" }, { 98, "GPIOX.1" }, { -1, "ADC.AIN0" }, { -1, "1.8V REF" }, { -1, "GND" }, { -1, "ADC.AIN1" }, }; //------------------------------------------------------------------------------ const struct header_info header_J7[7] = { { -1, "GND" }, { 6, "GPIOAO.6" }, { -1, "5.0V" }, { 8, "GPIOAO.8" }, { 10, "GPIOAO.10" }, { 9, "GPIOAO.9" }, { 11, "GPIOAO.11" }, }; //------------------------------------------------------------------------------------------------------------ int get_mode_gpiox (int pin) { switch(pin) { case 0: if (*(gpio + MUX_REG8) & BIT(5)) return 1; if (*(gpio + MUX_REG5) & BIT(14)) return 2; break; case 1: if (*(gpio + MUX_REG8) & BIT(4)) return 1; if (*(gpio + MUX_REG5) & BIT(13)) return 2; break; case 2: if (*(gpio + MUX_REG8) & BIT(3)) return 1; if (*(gpio + MUX_REG5) & BIT(13)) return 2; break; case 3: if (*(gpio + MUX_REG8) & BIT(2)) return 1; if (*(gpio + MUX_REG5) & BIT(13)) return 2; break; case 4: if ((*(gpio + MUX_REG5) & BIT(29)) && (*(gpio + MUX_REG5) & BIT(12))) return 1; if (*(gpio + MUX_REG3) & BIT(30)) return 2; if (*(gpio + MUX_REG4) & BIT(17)) return 3; break; case 5: if ((*(gpio + MUX_REG5) & BIT(28)) && (*(gpio + MUX_REG5) & BIT(12))) return 1; if (*(gpio + MUX_REG3) & BIT(29)) return 2; if (*(gpio + MUX_REG4) & BIT(16)) return 3; break; case 6: if ((*(gpio + MUX_REG5) & BIT(28)) && (*(gpio + MUX_REG5) & BIT(12))) return 1; if (*(gpio + MUX_REG3) & BIT(27)) return 2; if (*(gpio + MUX_REG4) & BIT(15)) return 3; if (*(gpio + MUX_REG5) & BIT(9)) return 4; break; case 7: if ((*(gpio + MUX_REG5) & BIT(28)) && (*(gpio + MUX_REG5) & BIT(12))) return 1; if (*(gpio + MUX_REG3) & BIT(27)) return 2; if (*(gpio + MUX_REG4) & BIT(14)) return 3; if (*(gpio + MUX_REG5) & BIT(8)) return 4; break; case 8: if (*(gpio + MUX_REG8) & BIT(1)) return 1; if (*(gpio + MUX_REG5) & BIT(11)) return 2; if (*(gpio + MUX_REG6) & BIT(19)) return 3; if (*(gpio + MUX_REG4) & BIT(22)) return 4; if (*(gpio + MUX_REG3) & BIT(6)) return 5; break; case 9: if (*(gpio + MUX_REG8) & BIT(0)) return 1; if (*(gpio + MUX_REG5) & BIT(10)) return 2; if (*(gpio + MUX_REG6) & BIT(18)) return 3; if (*(gpio + MUX_REG4) & BIT(24)) return 4; if (*(gpio + MUX_REG3) & BIT(6)) return 5; break; case 10: if (*(gpio + MUX_REG3) & BIT(22)) return 1; if ((*(gpio + MUX_REG7) & BIT(31)) && (*(gpio + MUX_REG9) & BIT(19))) return 2; if (*(gpio + MUX_REG6) & BIT(17)) return 3; if (*(gpio + MUX_REG4) & BIT(23)) return 4; if (*(gpio + MUX_REG3) & BIT(8)) return 5; break; case 11: if (*(gpio + MUX_REG3) & BIT(20)) return 1; if (*(gpio + MUX_REG7) & BIT(30)) return 2; if (*(gpio + MUX_REG2) & BIT(3)) return 5; break; case 16: if (*(gpio + MUX_REG4) & BIT(9)) return 1; if (*(gpio + MUX_REG4) & BIT(21)) return 4; if (*(gpio + MUX_REG4) & BIT(5)) return 5; break; case 17: if (*(gpio + MUX_REG4) & BIT(8)) return 1; if (*(gpio + MUX_REG4) & BIT(20)) return 4; if (*(gpio + MUX_REG4) & BIT(4)) return 5; break; case 18: if (*(gpio + MUX_REG4) & BIT(7)) return 1; if (*(gpio + MUX_REG4) & BIT(19)) return 4; break; case 19: if (*(gpio + MUX_REG4) & BIT(6)) return 1; if (*(gpio + MUX_REG4) & BIT(18)) return 4; break; case 20: if (*(gpio + MUX_REG6) & BIT(16)) return 3; if (*(gpio + MUX_REG4) & BIT(25)) return 4; if (*(gpio + MUX_REG3) & BIT(9)) return 5; break; case 21: break; default : return 0; } return *(gpio + GPIOX_FSEL_REG_OFFSET) & BIT(pin) ? 6 : 7; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioy (int pin) { switch(pin) { case 0: if (*(gpio + MUX_REG3) & BIT(2)) return 1; break; case 1: if (*(gpio + MUX_REG3) & BIT(1)) return 1; break; case 3: if (*(gpio + MUX_REG1) & BIT(7)) return 2; if (*(gpio + MUX_REG3) & BIT(18)) return 3; break; case 6: if (*(gpio + MUX_REG3) & BIT(5)) return 1; break; case 7: if (*(gpio + MUX_REG3) & BIT(5)) return 1; break; case 8: if (*(gpio + MUX_REG3) & BIT(0)) return 1; break; case 9: if (*(gpio + MUX_REG3) & BIT(4)) return 1; break; case 10: if (*(gpio + MUX_REG3) & BIT(5)) return 1; break; case 11: if (*(gpio + MUX_REG3) & BIT(5)) return 1; break; case 12: if (*(gpio + MUX_REG3) & BIT(5)) return 1; break; case 13: if (*(gpio + MUX_REG3) & BIT(5)) return 1; if (*(gpio + MUX_REG5) & BIT(7)) return 3; break; case 14: if (*(gpio + MUX_REG3) & BIT(5)) return 1; if (*(gpio + MUX_REG5) & BIT(6)) return 3; break; default : return 0; } return *(gpio + GPIOY_FSEL_REG_OFFSET) & BIT(pin) ? 6 : 7; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpiodv (int pin) { switch(pin) { case 24: if (*(gpio + MUX_REG6) & BIT(23)) return 4; if (*(gpio + MUX_REG9) & BIT(31)) return 5; break; case 25: if (*(gpio + MUX_REG6) & BIT(22)) return 4; if (*(gpio + MUX_REG9) & BIT(30)) return 5; break; case 26: if (*(gpio + MUX_REG6) & BIT(21)) return 4; if (*(gpio + MUX_REG9) & BIT(29)) return 5; break; case 27: if (*(gpio + MUX_REG6) & BIT(20)) return 4; if (*(gpio + MUX_REG9) & BIT(28)) return 5; break; default : return 0; } return *(gpio + GPIODV_FSEL_REG_OFFSET) & BIT(pin) ? 6 : 7; } //------------------------------------------------------------------------------------------------------------ int get_mode_gpioao (int pin) { switch(pin) { case 0: if (*(gpio_ao + MUX_REG0) & BIT(12)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(26)) return 3; break; case 1: if (*(gpio_ao + MUX_REG0) & BIT(11)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(25)) return 3; break; case 2: if (*(gpio_ao + MUX_REG0) & BIT(10)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(8)) return 3; break; case 3: if (*(gpio_ao + MUX_REG0) & BIT(9)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(22)) return 2; if (*(gpio_ao + MUX_REG0) & BIT(7)) return 3; break; case 4: if (*(gpio_ao + MUX_REG0) & BIT(6)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(2)) return 2; if (*(gpio_ao + MUX_REG0) & BIT(24)) return 3; break; case 5: if (*(gpio_ao + MUX_REG0) & BIT(5)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(1)) return 2; if (*(gpio_ao + MUX_REG0) & BIT(23)) return 3; break; case 6: if (*(gpio_ao + MUX_REG0) & BIT(18)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(16)) return 4; if (*(gpio + MUX_REG1) & BIT(13)) return 5; break; case 7: if (*(gpio_ao + MUX_REG0) & BIT(0)) return 1; if (*(gpio_ao + MUX_REG0) & BIT(21)) return 2; break; case 8: if (*(gpio_ao + MUX_REG0) & BIT(30)) return 2; return 1; case 9: if (*(gpio_ao + MUX_REG0) & BIT(29)) return 2; if (*(gpio + MUX_REG1) & BIT(15)) return 5; return 1; case 10: if (*(gpio_ao + MUX_REG0) & BIT(28)) return 2; if (*(gpio + MUX_REG1) & BIT(14)) return 5; return 1; case 11: if (*(gpio_ao + MUX_REG0) & BIT(27)) return 2; return 1; case 12: if (*(gpio_ao + MUX_REG0) & BIT(17)) return 1; break; case 13: if (*(gpio_ao + MUX_REG0) & BIT(31)) return 1; break; default : return 0; } return *(gpio_ao + GPIOAO_FSEL_REG_OFFSET) & BIT(pin) ? 6 : 7; } //------------------------------------------------------------------------------------------------------------ int get_mode (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: return get_mode_gpiox(pin - GPIOX_PIN_START); case GPIOY_PIN_START...GPIOY_PIN_END: return get_mode_gpioy(pin - GPIOY_PIN_START); case GPIODV_PIN_START...GPIODV_PIN_END: return get_mode_gpiodv(pin - GPIODV_PIN_START); case GPIOAO_PIN_START...GPIOAO_PIN_END: return get_mode_gpioao(pin - GPIOAO_PIN_START); default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ int get_pupd (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: if (*(gpio + GPIOX_PUEN_REG_OFFSET) & BIT(pin - GPIOX_PIN_START)) { return *(gpio + GPIOX_PUPD_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 2; } break; case GPIOY_PIN_START...GPIOY_PIN_END: if (*(gpio + GPIOY_PUEN_REG_OFFSET) & BIT(pin - GPIOY_PIN_START)) { return *(gpio + GPIOY_PUPD_REG_OFFSET) & BIT(pin - GPIOY_PIN_START) ? 1 : 2; } break; case GPIODV_PIN_START...GPIODV_PIN_END: if (*(gpio + GPIODV_PUEN_REG_OFFSET) & BIT(pin - GPIODV_PIN_START)) { return *(gpio + GPIODV_PUPD_REG_OFFSET) & BIT(pin - GPIODV_PIN_START) ? 1 : 2; } break; case GPIOAO_PIN_START...GPIOAO_PIN_END: if (*(gpio_ao + GPIOAO_PUEN_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START)) { return *(gpio_ao + GPIOAO_PUPD_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START + 16) ? 1 : 2; } break; default : break; } return 0; // PU/PD disable } //------------------------------------------------------------------------------------------------------------ int get_status (int pin) { switch (pin) { case GPIOX_PIN_START...GPIOX_PIN_END: return *(gpio + GPIOX_INP_REG_OFFSET) & BIT(pin - GPIOX_PIN_START) ? 1 : 0; case GPIOY_PIN_START...GPIOY_PIN_END: return *(gpio + GPIOY_INP_REG_OFFSET) & BIT(pin - GPIOY_PIN_START) ? 1 : 0; case GPIODV_PIN_START...GPIODV_PIN_END: return *(gpio + GPIODV_INP_REG_OFFSET) & BIT(pin - GPIODV_PIN_START) ? 1 : 0; case GPIOAO_PIN_START...GPIOAO_PIN_END: return *(gpio_ao + GPIOAO_INP_REG_OFFSET) & BIT(pin - GPIOAO_PIN_START) ? 1 : 0; default : break; } return 0; } //------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------ // // system init // //------------------------------------------------------------------------------------------------------------ int system_init(void) { int fd; if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) { fprintf(stderr, "/dev/mem open error!\n"); fflush(stdout); return -1; } gpio = (unsigned int *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_REG_MAP); gpio_ao = (unsigned int *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_AO_REG_MAP); if((unsigned int)gpio == -1 || (unsigned int)gpio_ao == -1) { fprintf(stderr, "mmap error!\n"); fflush(stdout); return -1; } return 0; } //------------------------------------------------------------------------------------------------------------ // // Start Program // //------------------------------------------------------------------------------------------------------------ int main (int argc, char *argv[]) { int i; if (system_init() < 0) { fprintf (stderr, "%s: System Init failed\n", __func__); fflush(stdout); return -1; } printf("+------+----------+------+---+-------+--- J2 ---+-------+---+------+----------+------+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical | PU/PD | V | Mode | Name | GPIO |\n"); printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); for (i = 0; i < 40; i += 2) { if (header_J2[i].gpio != -1) { printf("| %3d | %8s | %4s | %d | %4s | %2d |", header_J2[i].gpio, header_J2[i].name, MODE_STR[get_mode(header_J2[i].gpio)], get_status(header_J2[i].gpio), PUPD_STR[get_pupd(header_J2[i].gpio)], i + 1); } else { printf("| - | %8s | - | - | - | %2d |", header_J2[i].name, i + 1); } if (header_J2[i+1].gpio != -1) { printf("| %2d | %4s | %d | %4s | %8s | %3d |\n", i + 2, PUPD_STR[get_pupd(header_J2[i+1].gpio)], get_status(header_J2[i+1].gpio), MODE_STR[get_mode(header_J2[i+1].gpio)], header_J2[i+1].name, header_J2[i+1].gpio); } else { printf("| %2d | - | - | - | %8s | - |\n", i + 2, header_J2[i+1].name); } } printf("+------+----------+------+---+-------+----++----+-------+---+------+----------+------+\n"); printf("+------+-----------+------+---+-------+--- J7 ---+\n"); printf("| GPIO | Name | Mode | V | PU/PD | Physical |\n"); printf("+------+-----------+------+---+-------+----------+\n"); for(i = 0; i < 7; i ++) { if (header_J7[i].gpio != -1) { printf("| %3d | %9s | %4s | %d | %4s | %2d |\n", header_J7[i].gpio, header_J7[i].name, MODE_STR[get_mode(header_J7[i].gpio)], get_status(header_J7[i].gpio), PUPD_STR[get_pupd(header_J7[i].gpio)], i + 1); } else { printf("| - | %9s | - | - | - | %2d |\n", header_J7[i].name, i + 1); } } printf("+------+-----------+------+---+-------+----------+\n"); fflush(stdout); return 0 ; } //------------------------------------------------------------------------------------------------------------