# circuits_cdev
[![CircleCI](https://circleci.com/gh/elixir-circuits/circuits_cdev.svg?style=svg)](https://circleci.com/gh/elixir-circuits/circuits_cdev)
Character device GPIO library for Elixir.
Since Linux 4.8 the `sysfs` interface is deprecated in preference of the
character device GPIO API.
The advantages of the character device API over the `sysfs` interface are:
* The allocation of the GPIO is tied to the process that is using it, which
prevents many process from trying to control a GPIO at once.
* Since the GPIO is tied to the process, if the process ends for any reason the
GPIO will be cleaned up automatically.
* It is possible to read or write many GPIOs at once.
* It is possible to configure the state of the GPIO (open-source, open-drain, etc).
* The polling process to catch event is reliable.
The way to drive a GPIO line (a pin) is by requesting a line handle from a GPIO
chip. A system may have many GPIO chips and these can be named or they default
to using the name `gpiochipN` where `N` is the chip number starting a `0`.
For example the main GPIO chip on the Raspberry PI systems is `gpiochip0`
located at `"/dev/gpiochip0"`.
## Install
```elixir
def deps do
[{:circuits_cdev, "~> 0.1.0"}]
end
```
## Controlling the output of a line
First request a line handle from the GPIO chip:
```elixir
{:ok, line_handle} = Circuits.GPIO.Chip.request_line("gpiochip0", 17, :output)
```
After getting a line handle can now set the value of the line:
```elixir
Circuits.GPIO.Chip.read_value(line_handle)
0
```
To set the value of the line:
```elixir
Circuits.GPIO.Chip.set_value(line_handle, 1)
:ok
```
## Controlling the output of many lines
First request a line handle from the GPIO chip:
```elixir
{:ok, line_handle} = Circuits.GPIO.Chip.request_line("gpiochip0", [17, 27 20], :output)
```
After getting the line handle you can set the values of the lines. Notice that
you to provide all the values in the same order as you requested the lines:
```elixir
Circuits.GPIO.Chip.set_values(line_handle, [0, 1, 1])
```
When reading the values of a line handle that controls more than one line you
will receive a list of values in the order of that you requested the lines:
```elixir
Circuits.GPIO.Chip.read_values(line_handle)
{:ok, [0, 1, 1]}
```
## Listen for events on a line
You can listen for events on an GPIO line by calling the `listen_event/2` function:
```elixir
Circuits.GPIO.Chip.listen_event("gpiochip0", 27)
:ok
```
When an event is received from the line it will be in the form of:
```elixir
{:circuits_cdev, pin_number, timestamp, new_value}
```
The `timestamp` is the unix time in nanoseconds. In order to convert it into a
`DateTime` you will need to pass the `:nanoseconds` as the unit to
`DateTime.from_unix/3` function:
```elixir
DateTime.from_unix(timestamp, :nanoseconds)
{:ok, ~U[1990-07-24 07:30:03.123456Z]}
```
Also when calculating the time delta between two events keep in mind the
difference will be nanoseconds.