Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/gpio_exp: map GPIO expanders onto gpio_t #9190

Closed
wants to merge 18 commits into from

Conversation

ZetaR60
Copy link
Contributor

@ZetaR60 ZetaR60 commented May 25, 2018

This PR makes handling of GPIO expanders invisible to code using the GPIO pin API (periph/gpio.h). This is accomplished by reserving part of the range of values of gpio_t. When a call to the GPIO API uses a pin that falls within this range, it is parsed into a device ID that is looked up in the GPIO expansion registery and the call is redirected to the corresponding device.

Mostly done, but still a bit WIP.

@ZetaR60 ZetaR60 mentioned this pull request May 25, 2018
24 tasks
@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 25, 2018

I did a brief survey of how each system that defines gpio.c handles gpio_t, and the following systems look to be easy to add mapping support (in the same way as the atmega_common example):

  • atmega_common
  • cc26x0
  • efm32
  • ezr32wg
  • lm4f120
  • lpc2387
  • mips_pic32_common
  • nrf5x_common
  • stm32f1

The following systems can be made compatible by raising the size of gpio_t to 16bit / 32bit (or changing how gpio_t is handled):

  • kinetis
  • lpc1768
  • msp430fxyz

These systems use all of a 32bit gpio_t, and would require modifications to how gpio_t is used (unless gpio_t is raised to 64bits):

  • cc2538
  • sam0_common
  • sam3
  • stm32_common

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 27, 2018

Rebased to solve conflict. I have added two test routines: one for runtime and one for compile time. Neither require an actual GPIO expander (since the system will redirect to any set of functions if you tell it that it is a "driver"). I think the tests are complete enough to remove the explicit dependency on #9054 (edited my first post to remove dependency note).

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 27, 2018

Travis:

cpu/atmega_common/periph/gpio.c:120: style (variableScope): The scope of the variable 'exp_entry' can be reduced.
...etc

Uhm, no it can't?

@jnohlgard
Copy link
Member

Re cppcheck: You can move the exp_entry declaration inside the if block

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 27, 2018

Thanks @gebart. I had thought that variable declaration in blocks other than the outer function block was not guaranteed by the standard (other than in for loops), but a search says otherwise.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 28, 2018

Sorry for the large number of fixups. This PR is now tested and working properly on mega-xplained.

There may be an issue with the method of tests/driver_gpio_exp_coll, because some CPUs have a GPIO_PIN definition that uses a cast, which is not supported in preprocessor conditions. I may be able to work around it by defining a macro for (gpio_t), but I will have to do some experimenting.

[liveuser@localhost-live driver_gpio_exp]$ make BOARD=mega-xplained test
./tests/01-run.py
/home/liveuser/Desktop/RIOT_gpio_exp/dist/tools/pyterm/pyterm -p "/dev/ttyACM0" -b "9600"
No handlers could be found for logger "root"
2018-05-27 20:42:42,810 - INFO # Connect to serial port /dev/ttyACM0
Welcome to pyterm!
Type '/exit' to exit.
2018-05-27 20:42:43,814 - INFO # 

2018-05-27 20:42:46,713 - INFO # main(): This is RIOT! (Version: 2018.07-devel-386-gdf718-localhost-live-RIOT_gpio_exp)
2018-05-27 20:42:46,780 - INFO # gpio_exp test routine
2018-05-27 20:42:46,783 - INFO # Running gpio.h functions on pin 1
2018-05-27 20:42:46,812 - INFO # init on dev 0xbeef with pin 1
2018-05-27 20:42:46,879 - INFO # init_int on dev 0xbeef with pin 1
2018-05-27 20:42:46,880 - INFO # irq on dev 0xbeef with pin 1
2018-05-27 20:42:46,912 - INFO # irq on dev 0xbeef with pin 1
2018-05-27 20:42:46,980 - INFO # read on dev 0xbeef with pin 1
2018-05-27 20:42:46,982 - INFO # write on dev 0xbeef with pin 1
2018-05-27 20:42:47,013 - INFO # write on dev 0xbeef with pin 1
2018-05-27 20:42:47,078 - INFO # read on dev 0xbeef with pin 1
2018-05-27 20:42:47,081 - INFO # write on dev 0xbeef with pin 1
2018-05-27 20:42:47,112 - INFO # write on dev 0xbeef with pin 1
2018-05-27 20:42:47,178 - INFO # Running gpio.h functions on pin 2
2018-05-27 20:42:47,180 - INFO # init on dev 0xbeef with pin 2
2018-05-27 20:42:47,214 - INFO # init_int on dev 0xbeef with pin 2
2018-05-27 20:42:47,278 - INFO # irq on dev 0xbeef with pin 2
2018-05-27 20:42:47,279 - INFO # irq on dev 0xbeef with pin 2
2018-05-27 20:42:47,281 - INFO # read on dev 0xbeef with pin 2
2018-05-27 20:42:47,314 - INFO # write on dev 0xbeef with pin 2
2018-05-27 20:42:47,379 - INFO # write on dev 0xbeef with pin 2
2018-05-27 20:42:47,380 - INFO # read on dev 0xbeef with pin 2
2018-05-27 20:42:47,413 - INFO # write on dev 0xbeef with pin 2
2018-05-27 20:42:47,480 - INFO # write on dev 0xbeef with pin 2
2018-05-27 20:42:47,483 - INFO # Running gpio.h functions on pin 4
2018-05-27 20:42:47,514 - INFO # init on dev 0xbeef with pin 4
2018-05-27 20:42:47,580 - INFO # init_int on dev 0xbeef with pin 4
2018-05-27 20:42:47,583 - INFO # irq on dev 0xbeef with pin 4
2018-05-27 20:42:47,614 - INFO # irq on dev 0xbeef with pin 4
2018-05-27 20:42:47,681 - INFO # read on dev 0xbeef with pin 4
2018-05-27 20:42:47,683 - INFO # write on dev 0xbeef with pin 4
2018-05-27 20:42:47,713 - INFO # write on dev 0xbeef with pin 4
2018-05-27 20:42:47,780 - INFO # read on dev 0xbeef with pin 4
2018-05-27 20:42:47,783 - INFO # write on dev 0xbeef with pin 4
2018-05-27 20:42:47,813 - INFO # write on dev 0xbeef with pin 4
2018-05-27 20:42:47,879 - INFO # Running gpio.h functions on pin 8
2018-05-27 20:42:47,880 - INFO # init on dev 0xbeef with pin 8
2018-05-27 20:42:47,913 - INFO # init_int on dev 0xbeef with pin 8
2018-05-27 20:42:47,979 - INFO # irq on dev 0xbeef with pin 8
2018-05-27 20:42:47,982 - INFO # irq on dev 0xbeef with pin 8
2018-05-27 20:42:48,013 - INFO # read on dev 0xbeef with pin 8
2018-05-27 20:42:48,079 - INFO # write on dev 0xbeef with pin 8
2018-05-27 20:42:48,080 - INFO # write on dev 0xbeef with pin 8
2018-05-27 20:42:48,113 - INFO # read on dev 0xbeef with pin 8
2018-05-27 20:42:48,179 - INFO # write on dev 0xbeef with pin 8
2018-05-27 20:42:48,181 - INFO # write on dev 0xbeef with pin 8
2018-05-27 20:42:48,212 - INFO # Running gpio.h functions on pin 16
2018-05-27 20:42:48,280 - INFO # init on dev 0xbeef with pin 16
2018-05-27 20:42:48,283 - INFO # init_int on dev 0xbeef with pin 16
2018-05-27 20:42:48,312 - INFO # irq on dev 0xbeef with pin 16
2018-05-27 20:42:48,380 - INFO # irq on dev 0xbeef with pin 16
2018-05-27 20:42:48,382 - INFO # read on dev 0xbeef with pin 16
2018-05-27 20:42:48,412 - INFO # write on dev 0xbeef with pin 16
2018-05-27 20:42:48,480 - INFO # write on dev 0xbeef with pin 16
2018-05-27 20:42:48,482 - INFO # read on dev 0xbeef with pin 16
2018-05-27 20:42:48,512 - INFO # write on dev 0xbeef with pin 16
2018-05-27 20:42:48,578 - INFO # write on dev 0xbeef with pin 16
2018-05-27 20:42:48,580 - INFO # Running gpio.h functions on pin 32
2018-05-27 20:42:48,613 - INFO # init on dev 0xbeef with pin 32
2018-05-27 20:42:48,679 - INFO # init_int on dev 0xbeef with pin 32
2018-05-27 20:42:48,680 - INFO # irq on dev 0xbeef with pin 32
2018-05-27 20:42:48,713 - INFO # irq on dev 0xbeef with pin 32
2018-05-27 20:42:48,779 - INFO # read on dev 0xbeef with pin 32
2018-05-27 20:42:48,782 - INFO # write on dev 0xbeef with pin 32
2018-05-27 20:42:48,812 - INFO # write on dev 0xbeef with pin 32
2018-05-27 20:42:48,879 - INFO # read on dev 0xbeef with pin 32
2018-05-27 20:42:48,882 - INFO # write on dev 0xbeef with pin 32
2018-05-27 20:42:48,913 - INFO # write on dev 0xbeef with pin 32
2018-05-27 20:42:48,980 - INFO # Running gpio.h functions on pin 64
2018-05-27 20:42:48,982 - INFO # init on dev 0xbeef with pin 64
2018-05-27 20:42:49,013 - INFO # init_int on dev 0xbeef with pin 64
2018-05-27 20:42:49,079 - INFO # irq on dev 0xbeef with pin 64
2018-05-27 20:42:49,080 - INFO # irq on dev 0xbeef with pin 64
2018-05-27 20:42:49,113 - INFO # read on dev 0xbeef with pin 64
2018-05-27 20:42:49,179 - INFO # write on dev 0xbeef with pin 64
2018-05-27 20:42:49,182 - INFO # write on dev 0xbeef with pin 64
2018-05-27 20:42:49,213 - INFO # read on dev 0xbeef with pin 64
2018-05-27 20:42:49,279 - INFO # write on dev 0xbeef with pin 64
2018-05-27 20:42:49,282 - INFO # write on dev 0xbeef with pin 64
2018-05-27 20:42:49,313 - INFO # Running gpio.h functions on pin 128
2018-05-27 20:42:49,379 - INFO # init on dev 0xbeef with pin 128
2018-05-27 20:42:49,380 - INFO # init_int on dev 0xbeef with pin 128
2018-05-27 20:42:49,413 - INFO # irq on dev 0xbeef with pin 128
2018-05-27 20:42:49,481 - INFO # irq on dev 0xbeef with pin 128
2018-05-27 20:42:49,483 - INFO # read on dev 0xbeef with pin 128
2018-05-27 20:42:49,513 - INFO # write on dev 0xbeef with pin 128
2018-05-27 20:42:49,579 - INFO # write on dev 0xbeef with pin 128
2018-05-27 20:42:49,579 - INFO # read on dev 0xbeef with pin 128
2018-05-27 20:42:49,613 - INFO # write on dev 0xbeef with pin 128
2018-05-27 20:42:49,680 - INFO # write on dev 0xbeef with pin 128
2018-05-27 20:42:49,682 - INFO # Running notsup functions
2018-05-27 20:42:49,713 - INFO # (they should not print output)
2018-05-27 20:42:49,779 - INFO # Running notsup gpio.h functions on pin 0
2018-05-27 20:42:49,812 - INFO # Running notsup gpio.h functions on pin 1
2018-05-27 20:42:49,880 - INFO # Running notsup gpio.h functions on pin 2
2018-05-27 20:42:49,883 - INFO # Running notsup gpio.h functions on pin 3
2018-05-27 20:42:49,979 - INFO # Running notsup gpio.h functions on pin 4
2018-05-27 20:42:49,983 - INFO # Running notsup gpio.h functions on pin 5
2018-05-27 20:42:50,013 - INFO # Running notsup gpio.h functions on pin 6
2018-05-27 20:42:50,080 - INFO # Running notsup gpio.h functions on pin 7
2018-05-27 20:42:50,113 - INFO # Checking that all pins in range have init error using notsup
2018-05-27 20:42:50,214 - INFO # (lack of init error implies improper redirection)
2018-05-27 20:42:50,214 - INFO # [SUCCESS]

[liveuser@localhost-live driver_gpio_exp]$ echo $?
0
Installed compiler toolchains 
-----------------------------
             native gcc: missing
      arm-none-eabi-gcc: missing
                avr-gcc: avr-gcc (Fedora 7.2.0-1.fc27) 7.2.0
       mips-mti-elf-gcc: missing
             msp430-gcc: missing
   riscv-none-embed-gcc: missing
                  clang: missing

Installed compiler libs
-----------------------
   arm-none-eabi-newlib: missing
    mips-mti-elf-newlib: missing
riscv-none-embed-newlib: missing
               avr-libc: "2.0.0" ("20150208")

Installed development tools
---------------------------
                  cmake: cmake version 3.11.0
               cppcheck: missing
                doxygen: missing
                 flake8: missing
                    git: git version 2.14.2
             coccinelle: missing

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 2, 2018

tests/driver_gpio_exp_coll now does its testing using the compiler using static_assert, rather than the preprocessor. It can understand the enum port definitions (no more hard-coding), casts, sizeof, etc.

This PR now requires #9279

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 5, 2018

#9279 has been merged: the dependency has been satisfied.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 9, 2018

Rebased on trunk to bring in new CPU (fe310) and resolved conflicts. All CPUs with conventional GPIO definitions have support added, but some have collisions. None of the CPUs with odd GPIO definitions have been added yet. The compile time collision detection in driver_gpio_exp_coll is confirmed to be working properly and is detecting collisions in a couple of the CPUs. Example output when detecting a collision:

user@computer:~/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/tests/driver_gpio_exp_coll$ make BOARD=bluepill
/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/makefiles/toolchain/gnu.inc.mk:17: objcopy not found. Hex file will not be created.
Launching build container using image "riot/riotbuild:latest".
docker run --rm -t -u "$(id -u)" \
    -v '/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker:/data/riotbuild/riotbase' \
    -v '/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/cpu:/data/riotbuild/riotcpu' \
    -v '/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/boards:/data/riotbuild/riotboard' \
    -v '/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/makefiles:/data/riotbuild/riotmake' \
    -v '/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker:/data/riotbuild/riotproject' \
    -v /etc/localtime:/etc/localtime:ro \
    -e 'RIOTBASE=/data/riotbuild/riotbase' \
    -e 'CCACHE_BASEDIR=/data/riotbuild/riotbase' \
    -e 'RIOTCPU=/data/riotbuild/riotcpu' \
    -e 'RIOTBOARD=/data/riotbuild/riotboard' \
    -e 'RIOTMAKE=/data/riotbuild/riotmake' \
    -e 'RIOTPROJECT=/data/riotbuild/riotproject' \
    -e 'BOARD=bluepill' \
    -w '/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/' \
    'riot/riotbuild:latest' make  'BOARD=bluepill'
Building application "tests_driver_gpio_exp_coll" for "bluepill" with MCU "stm32f1".

In file included from /data/riotbuild/riotproject/tests/driver_gpio_exp_coll/main.c:20:0:
/data/riotbuild/riotbase/core/include/assert.h:122:49: error: division by zero [-Werror=div-by-zero]
     enum { static_assert_failed_on_div_by_0 = 1 / (!!(cond)) }
                                                 ^
/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/main.c:302:1: note: in expansion of macro 'static_assert'
 static_assert(COLL_RES, "[driver_gpio_exp_coll] Collision in GPIO_EXP_PIN");
 ^~~~~~~~~~~~~
/data/riotbuild/riotbase/core/include/assert.h:122:12: error: enumerator value for 'static_assert_failed_on_div_by_0' is not an integer constant
     enum { static_assert_failed_on_div_by_0 = 1 / (!!(cond)) }
            ^
/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/main.c:302:1: note: in expansion of macro 'static_assert'
 static_assert(COLL_RES, "[driver_gpio_exp_coll] Collision in GPIO_EXP_PIN");
 ^~~~~~~~~~~~~
cc1: all warnings being treated as errors
/data/riotbuild/riotbase/Makefile.base:83: recipe for target '/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/bin/bluepill/application_tests_driver_gpio_exp_coll/main.o' failed
make[1]: *** [/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/bin/bluepill/application_tests_driver_gpio_exp_coll/main.o] Error 1
/data/riotbuild/riotbase/Makefile.include:359: recipe for target '/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/bin/bluepill/application_tests_driver_gpio_exp_coll.a' failed
make: *** [/data/riotbuild/riotproject/tests/driver_gpio_exp_coll/bin/bluepill/application_tests_driver_gpio_exp_coll.a] Error 2
/home/user/Desktop/files/projects/acutam/firmware/RIOT_gpio_exp_docker/makefiles/docker.inc.mk:90: recipe for target '..in-docker-container' failed
make: *** [..in-docker-container] Error 2

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 10, 2018

This PR is ready for review: All targets with gpio support now have gpio_exp support. All collisions have been resolved with no modification to how gpios were previously used. Compile tests on all non-blacklisted targets show no errors, and a runtime test on mega-xplained passes.

@kYc0o
Copy link
Contributor

kYc0o commented Jun 11, 2018

Thanks for your contribution! I think it can be reviewed soon. Can you squash so it's in a clean status?

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 11, 2018

Squashed.

@ZetaR60 ZetaR60 added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jun 14, 2018
@ZetaR60 ZetaR60 added this to the Release 2018.07 milestone Jul 2, 2018
@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jul 2, 2018

Rebased on trunk and conflicts solved.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jul 7, 2018

I have make the intercept code in cpu/*/periph/gpio.c much simpler. I have also merged the various CPU support commits into one cpu/* commit.

@vincent-d
Copy link
Member

I share concerns with @kYc0o regarding the 'overhead' of this PR, but more in term of maintainability for cpu code. I also understand and see the need of this feature.

I think that periph API are intended to remain as simple and light as possible and implement only cpu-specific code. Then I would see such a feature in a layer above periph_gpio, but the drawback would be to update every code using gpio... Another solution would be to switch periph API to a descriptor / function pointer -based API, but this topic is wider and has already been discussed a lot without reaching consensus I think.

I think @kaspar030 opinion might also be valuable here.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jul 13, 2018

An alternative to the macro based intercept might be to rename all GPIO functions in cpu/*/periph/gpio.c to a low-level name (e.g. gpio_init becomes gpio_init_ll), and then implement a GPIO function call as an inline like this:

inline int gpio_init(gpio_t pin, gpio_mode_t mode)
{
#ifdef MODULE_GPIO_EXP
    /* intercept code here */
#endif

    return gpio_init_ll(pin, mode);
}

This would of course involve renaming all of the GPIO implementations, but it would avoid confusion over the nature of the macro, and it would avoid the overhead of building function pointers into the GPIO interface.

@kaspar030
Copy link
Contributor

I'm with @kYc0o and @vincent-d, having to modify all cpu implementations is too much.

Another solution would be to switch periph API to a descriptor / function pointer -based API, but this topic is wider and has already been discussed a lot without reaching consensus I think.

An alternative to the macro based intercept might be to rename all GPIO functions in cpu/*/periph/gpio.c to a low-level name (e.g. gpio_init becomes gpio_init_ll), and then implement a GPIO function call as an inline like this:

There where even multiple prototypes with different tradeoffs.
For gpio, the current API optimizes very well (when using LTO), and we didn't (yet) come up with something that doesn't add significant overhead.

For this PR, I suggest concentrating on the actual expander API first and tackle integration later.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jul 14, 2018

I think @kYc0o mentioned that he performed a review of the entire PR, not just the intercept code. Can you confirm kYc0o?

There was an issue with tests/driver_gpio_exp_coll default failing unknown CPUs. I can fix that now by changing unknown CPUs to default to only a partial test, which can run on any CPU.

Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The architecture needs some work.

/**
* @brief Macro for intercepting and redirecting gpio_init calls
*/
#define GPIO_INTERCEPT_INIT(pin, mode) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long macros are against RIOT's coding conventions. Please try another way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to non-macro in drivers/include/periph/gpio.h.

@@ -127,6 +129,8 @@ static inline int8_t _int_num(gpio_t pin)

int gpio_init(gpio_t pin, gpio_mode_t mode)
{
GPIO_INTERCEPT_INIT(pin, mode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to add code to every single implementation needs to be avoided. Please find another way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The intercepts are now implemented by splitting the GPIO functions into a low-level version.

* @{
*
* @file
* @brief GPIO expansion default registry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite like that gpio_exp comes with its own registry. Is this actually necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Expanders are addressed by a number that is used with GPIO_EXP_PIN(foo_dev, bar_pin). The number foo_dev cannot be known until linking the binary, because the board may have more than one GPIO expander, so foo_dev cannot be a macro or enum set by the driver. Also, order is important, so automatically building the registry with a linked list cannot be relied on, because changes to code may change the order of device numbers. This leaves a manually defined array as the remaining satisfactory choice, which would be set up as part of the board includes by the developer porting the board.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I think I was using the word "registry" too loosely here. It is not a registry in the sense of e.g. SAUL. I will change the name of the file to gpio_exp_conf.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be clearer now.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jul 14, 2018

The latest changes addresses some of the major concerns expressed so far:

  • Use of macros
  • Insertion of code into cpu/*/periph/gpio.c
  • Lack of clarity of API call interception

@stale
Copy link

stale bot commented Aug 10, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Aug 10, 2019
@stale stale bot closed this Sep 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers State: stale State: The issue / PR has no activity for >185 days Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants