Skip to content

Instantly share code, notes, and snippets.

@Niols
Last active January 30, 2017 15:24
Show Gist options
  • Save Niols/8dadf5a11c8d953bb2a87eced9e3400e to your computer and use it in GitHub Desktop.
Save Niols/8dadf5a11c8d953bb2a87eced9e3400e to your computer and use it in GitHub Desktop.
Shell functions to control the C.H.I.P GPIO pins
#!/bin/sh
## This shell script aims to help you in controlling the XIO-P0 to
## XIO-P7 expander GPIO pins [2] of the C.H.I.P. [1]. It should work
## with any Debian Policy-compliant shell [3]. It is advised to use it
## with the `-e' flag [4].
##
## [1]: To know more about C.H.I.P.: https://getchip.com/
##
## [2]: To know more about the pins of your C.H.I.P.:
## https://docs.getchip.com/chip.html#pin-headers
##
## [3]: See "Debian Policy, 10.4 Scripts":
## https://www.debian.org/doc/debian-policy/ch-files.html#s-scripts
##
## [4]: See "POSIX, Shell & Utilities, 2. Shell Command Language,
## 14. Special Built-In Utilities" about the "set" utility:
## http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
##
##
## "THE BEER-WARE LICENSE" (Revision 42):
##
## Niols <niols@niols.fr> wrote this file. As long as you retain this
## notice you can do whatever you want with this stuff. If we meet
## some day, and you think this stuff is worth it, you can buy me a
## beer in return.
readonly GPIO_CLASS=/sys/class/gpio
readonly GPIO_LABEL_FILE=$(grep -l pcf8574a "$GPIO_CLASS"/*/*label | head -n 1)
readonly GPIO_BASE_FILE=$(dirname "$GPIO_LABEL_FILE")/base
readonly GPIO_BASE=$(cat "$GPIO_BASE_FILE")
readonly GPIO_RC_TRUE=0
readonly GPIO_RC_FALSE=1
readonly GPIO_RC_FORBIDDEN=4
readonly GPIO_RC_UNEXPECTED=8
readonly GPIO_RC_INVALID_PIN=16
readonly GPIO_RC_INVALID_DIRECTION=32
readonly GPIO_RC_INVALID_VALUE=64
_gpio_pin () {
local pin=$1
[ "$pin" -ge 0 -a "$pin" -lt 8 ] \
|| return "$GPIO_RC_INVALID_PIN"
echo $((GPIO_BASE + pin))
}
gpio_export () {
## Tells to the system that the given pin must be exported. This
## is necessary before any other action.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
echo "$pin" > "$GPIO_CLASS"/export
}
gpio_unexport () {
## Tells to the system that the given pin can be un-exported. The
## pin wont be usable anymore before a new export.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
echo "$pin" > "$GPIO_CLASS"/unexport
}
_gpio_is_exported () {
[ -d "$GPIO_CLASS"/gpio"$1" ]
}
gpio_is_exported () {
## Tests whether or not the given pin is exported.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
##
## Return code:
## - GPIO_RC_TRUE :: if the given pin is exported
## - GPIO_RC_FALSE :: if the given pin isn't exported
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
_gpio_is_exported "$pin"
}
gpio_get_direction () {
## Gets the direction of the given pin.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
##
## Standard output:
## - direction :: either "in" or "out"
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
_gpio_is_exported "$pin" \
|| return "$GPIO_RC_FORBIDDEN"
cat "$GPIO_CLASS"/gpio"$pin"/direction
}
gpio_set_direction () {
## Sets the direction of the given pin.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
## - direction :: either "in" or "out"
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
## - GPIO_RC_INVALID_DIRECTION :: if the direction isn't "in" or "out"
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
local direction=$1
[ "$direction" == 'in' -o "$direction" == 'out' ] \
|| return "$GPIO_RC_INVALID_DIRECTION"
shift
_gpio_is_exported "$pin" \
|| return "$GPIO_RC_FORBIDDEN"
echo "$direction" > "$GPIO_CLASS"/gpio"$pin"/direction
}
gpio_get_value () {
## Gets the value of the given pin.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
##
## Standard output:
## - value :: "0" or "1" depending on the state of the pin.
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
## - GPIO_RC_FORBIDDEN :: if the direction of the given pin isn't "in"
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
_gpio_is_exported "$pin" \
|| return "$GPIO_RC_FORBIDDEN"
cat "$GPIO_CLASS"/gpio"$pin"/value
}
gpio_set_value () {
## Sets the value of the given pin.
##
## Arguments:
## - pin :: an integer between 0 (incl.) and 8 (excl.)
## - value :: either "0" or "1"
##
## Return code:
## - GPIO_RC_INVALID_PIN :: if the given pin isn't between 0 and 8
## - GPIO_RC_INVLIAD_VALUE :: if the value isn't "0" or "1"
## - GPIO_RC_FORBIDDEN :: if the direction of the given pin isn't "out"
local pin=$(_gpio_pin "$1") \
|| return "$GPIO_RC_INVALID_PIN"
shift
local value=$1
[ "$value" -eq 0 -o "$value" -eq 1 ] \
|| return "$GPIO_RC_INVALID_VALUE"
shift
_gpio_is_exported "$pin" \
|| return "$GPIO_RC_FORBIDDEN"
echo "$value" > "$GPIO_CLASS"/gpio"$pin"/value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment