Khadas Docs

Amazing Khadas, always amazes you!

User Tools

Site Tools


Sidebar

products:sbc:vim1s:applications:gpio:irq

VIM1S GPIO Interrupts

Introduction

The page leads you to use GPIO interrupts with the GPIO number test program on Khadas SBC.

Here we use GPIOH_6 on VIM3 as an example.

Hardware Connection

Connect the physical pins PIN20 and PIN15 by using a DuPont line.

System Configuration

Get GPIOH_6 number

Refer to 40-Pin Header, the GPIO number you get is 433.

Export GPIO

$ echo 433 | sudo tee /sys/class/gpio/export

Please use gpio readall to check the status of GPIOH_6, if it is not shown as a normal GPIO, you need to remove uart3 from overlays in file /boot/env.txt.
Check the Device Tree Overlay for more details.

Demo Source Code

Get demo source code

gpio_interrupts.c
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2022 Wesion Technology Co., Ltd.
 *
 * Author: Yan <yan-wyb@foxmail.com> 
 *
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
 
#define SYSFS_GPIO_DIR  "/sys/class/gpio"
#define MAX_BUF     255
 
int gpio_export(unsigned int gpio){
 
    int fd, len;
    char buf[MAX_BUF];
 
    fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
 
    if (fd < 0) {
        fprintf(stderr, "Can't export GPIO %d pin: %s\n", gpio, strerror(errno));
        return fd;
    }
 
    len = snprintf(buf, sizeof(buf), "%d", gpio);
    write(fd, buf, len);
    close(fd);
 
    return 0;
}
 
int gpio_unexport(unsigned int gpio){
 
    int fd, len;
    char buf[MAX_BUF];
 
    fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
 
    if (fd < 0) {
        fprintf(stderr, "Can't unexport GPIO %d pin: %s\n", gpio, strerror(errno));
        return fd;
    }
 
    len = snprintf(buf, sizeof(buf), "%d", gpio);
    write(fd, buf, len);
    close(fd);
 
    return 0;
}
 
int gpio_set_edge(unsigned int gpio, char *edge){
 
    int fd, len;
    char buf[MAX_BUF];
 
    len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
 
    fd = open(buf, O_WRONLY);
 
    if (fd < 0) {
        fprintf(stderr, "Can't set GPIO %d pin edge: %s\n", gpio, strerror(errno));
        return fd;
    }
 
    write(fd, edge, strlen(edge)+1);
    close(fd);
 
    return 0;
}
 
int gpio_set_pull(unsigned int gpio, char *pull){
 
    int fd, len;
    char buf[MAX_BUF];
 
    len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/pull", gpio);
 
    fd = open(buf, O_WRONLY);
 
    if (fd < 0) {
        fprintf(stderr, "Can't set GPIO %d pin pull: %s\n", gpio, strerror(errno));
        return fd;
    }
 
    write(fd, pull, strlen(pull)+1);
    close(fd);
 
    return 0;
}
 
int main(int argc, char *argv[])
{
    struct pollfd fdset[2];
    int fd, ret, gpio;
    char buf[MAX_BUF];
 
    if (argc < 3 || argc > 4)   {
        fprintf(stdout, "usage : sudo sysfs_irq_test <gpio> <edge> [pull]\n");
        fflush(stdout);
        return  -1;
    }
 
    gpio = atoi(argv[1]);
    if (gpio_export(gpio))  {
        fprintf(stdout, "error : export %d\n", gpio);
        fflush(stdout);
        return  -1;
    }
 
    if (gpio_set_edge(gpio, argv[2])) {
        fprintf(stdout, "error : edge %s\n", argv[2]);
        fflush(stdout);
        return  -1;
    }
 
    if (argv[3] && gpio_set_pull(gpio, argv[3])) {
        fprintf(stdout, "error : pull %s\n", argv[3]);
        fflush(stdout);
        return  -1;
    }
 
    snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
    fd = open(buf, O_RDWR);
    if (fd < 0)
        goto out;
 
    while (1) {
        memset(fdset, 0, sizeof(fdset));
        fdset[0].fd = STDIN_FILENO;
        fdset[0].events = POLLIN;
        fdset[1].fd = fd;
        fdset[1].events = POLLPRI;
        ret = poll(fdset, 2, 3*1000);
 
        if (ret < 0) {
            perror("poll");
            break;
        }
 
        fprintf(stderr, ".");
 
        if (fdset[1].revents & POLLPRI) {
            char c;
            (void)read (fd, &c, 1) ;
            lseek (fd, 0, SEEK_SET) ;
            fprintf(stderr, "\nGPIO %d interrupt occurred!\n", gpio);
        }
 
        if (fdset[0].revents & POLLIN)
            break;
 
        fflush(stdout);
    }
 
    close(fd);
out:
    if (gpio_unexport(gpio))    {
        fprintf(stdout, "error : unexport %d\n", gpio);
        fflush(stdout);
    }
 
    return 0;
 }

Compile the source code

$ gcc -o gpio_interrupts gpio_interrupts.c

Demonstrate

The test code running format is as follows:

$ sudo ./gpio_interrupts <edge> [pull]

Run test:

$ sudo ./gpio_interrupts rising down
.
GPIO 433 interrupt occurred!
..
GPIO 433 interrupt occurred!
.
GPIO 433 interrupt occurred!
.
GPIO 433 interrupt occurred!
2022/06/29 09:38

VIM1S Getting Started

Setting up your VIM1S

To get started with your Khadas VIM1S you’ll need the following accessories:

Connecting a Display

Your VIM1S has an HDMI port which you can connect directly to a monitor with an HDMI cable.

Supply the Power

Your VIM1S is compatible with various types of power supplies, and these are the minimum specifications for the best performance and stability.

After connecting a 5V/2A power source to the USB-C port, your VIM1S will boot up. You will see the Khadas Logo appear on your display, and the white LED will flash in a regular pattern, the borad will boot into OOWOW by default if you haven't installed any OS into the eMMC.

Installing the Operating System

Once you boot into OOWOW, you can follow the OOWOW wizard to install the OS you preferred.

See Also

2022/07/17 21:31
Last modified: 2022/09/19 04:58 by nick