Skip to content

Commit

Permalink
cpu/native: add Linux GPIO implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
benpicco committed Oct 14, 2019
1 parent 2c0ed1d commit bdcb8bd
Show file tree
Hide file tree
Showing 7 changed files with 463 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cpu/native/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ifneq (,$(filter periph_gpio,$(USEMODULE)))
# Hardware GPIO access is only available on Linux hosts
ifeq ($(OS),Linux)
USEMODULE += periph_gpio_linux
endif
endif
5 changes: 5 additions & 0 deletions cpu/native/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_hwrng
FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_pwm

# Hardware GPIO access is only available on Linux hosts
ifeq ($(OS),Linux)
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
endif
74 changes: 74 additions & 0 deletions cpu/native/include/gpiodev_linux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2019 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
*/

/**
* @defgroup drivers_gpio_linux Linux User Mode GPIO Driver
* @ingroup cpu_native
* @brief Implementation of GPIO access from Linux User Space
*
* This module allows to connect a RIOT application that runs on a Linux host to
* the physical GPIO pins of that host. To do so, the application has to be
* compiled for the native board in a Linux environment.
*
* GPIO support is automatically included if either a module requiring the
* `PERIPH_GPIO` feature is added to the application or if it is explicitly
* listed as `FEATURES_REQUIRED` in the application's Makefile.
*
* At runtime, the process has to be connected to a specific GPIO bank on the host
* machine. GPIO banks are exposed as `/dev/gpiochipN` character files, where N
* is the bank ID to which several GPIO pins are connected.
*
* Example:
*
* ```
* $ ./riot_native_app --gpio=/dev/gpiochip0 --gpio=/dev/gpiochip1
* ```
*
* This will add `/dev/gpiochip0` and `/dev/gpiochip1` as PORT(0) and PORT(1) in RIOT.
* The first pin can be used with PIN(0,0) as `gpio_t`, the second one on the first
* port would be PIN(0,1) and so on.
*
* Please refer to your board's documentation for the mapping of the pins.
*
* @{
*
* @file
* @brief Implementation of GPIO access from Linux User Space
*
* @author Benjamin Valentin <benpicco@googlemail.com>
*/

#ifndef GPIODEV_LINUX_H
#define GPIODEV_LINUX_H

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief register `/dev/gpiochip*` device to be used for GPIO
*
* @param[in] device The gpiochip device to open.
*
* @return 0 on success, error otherwise
*/
int gpio_linux_setup(const char* device);

/**
* @brief shutdown GPIO subsystem
*
* This closes all GPIO fds.
*/
void gpio_linux_teardown(void);

#ifdef __cplusplus
}
#endif

#endif /* GPIODEV_LINUX_H */
/** @} */
54 changes: 54 additions & 0 deletions cpu/native/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,60 @@ extern "C" {
#define CPUID_LEN (4U)
#endif

/* GPIO configuration only if the module is available (=Linux) */
#if defined(MODULE_PERIPH_GPIO_LINUX) || defined(DOXYGEN)
#include <linux/gpio.h>

/**
* @name GPIO Configuration
*/

/**
* @brief The offset between Port and Pin
*/
#define GPIO_PORT_SHIFT (24)

/**
* @brief Define a custom GPIO_PIN macro for native
*/
#define GPIO_PIN(port, pin) (gpio_t)((port << GPIO_PORT_SHIFT) | pin)

#define HAVE_GPIO_MODE_T
#ifndef GPIOHANDLE_REQUEST_PULL_DOWN
#define GPIOHANDLE_REQUEST_PULL_DOWN (0xFF)
#endif
#ifndef GPIOHANDLE_REQUEST_PULL_UP
#define GPIOHANDLE_REQUEST_PULL_UP (0xFF)
#endif

/**
* @brief Available pin modes
*
* Generally, a pin can be configured to be input or output. In output mode, a
* pin can further be put into push-pull or open drain configuration. Though
* this is supported by most platforms, this is not always the case, so driver
* implementations may return an error code if a mode is not supported.
*/
typedef enum {
GPIO_IN = GPIOHANDLE_REQUEST_INPUT,
GPIO_IN_PD = GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_PULL_DOWN,
GPIO_IN_PU = GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_PULL_UP,
GPIO_OUT = GPIOHANDLE_REQUEST_OUTPUT,
GPIO_OD = GPIOHANDLE_REQUEST_OPEN_DRAIN,
GPIO_OD_PU = GPIOHANDLE_REQUEST_OPEN_DRAIN | GPIOHANDLE_REQUEST_PULL_UP
} gpio_mode_t;

#define HAVE_GPIO_FLANK_T
typedef enum {
GPIO_FALLING = GPIOEVENT_EVENT_FALLING_EDGE, /**< emit interrupt on falling flank */
GPIO_RISING = GPIOEVENT_EVENT_RISING_EDGE, /**< emit interrupt on rising flank */
GPIO_BOTH = GPIO_FALLING | GPIO_RISING /**< emit interrupt on both flanks */
} gpio_flank_t;

/** @} */

#endif /* MODULE_PERIPH_GPIO_LINUX | DOXYGEN */

/**
* @brief Prevent shared timer functions from being used
*/
Expand Down
5 changes: 5 additions & 0 deletions cpu/native/periph/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "periph/gpio.h"

#ifndef MODULE_GPIO_NATIVE

int gpio_init(gpio_t pin, gpio_mode_t mode) {
(void) pin;
(void) mode;
Expand Down Expand Up @@ -51,4 +53,7 @@ void gpio_write(gpio_t pin, int value) {
(void) pin;
(void) value;
}

#endif /* !MODULE_GPIO_NATIVE */

/** @} */
Loading

0 comments on commit bdcb8bd

Please sign in to comment.