Port over to using circuits_i2c
instead of elixir_ale
.
This commit is contained in:
parent
54a98a47da
commit
16ef8ac43e
|
@ -1,18 +1,30 @@
|
|||
defmodule PCA9641 do
|
||||
@moduledoc """
|
||||
Documentation for PCA9641.
|
||||
PCA9641 Driver for Elixir using Circuits.
|
||||
|
||||
## Usage:
|
||||
Add your devices to your config like so:
|
||||
|
||||
config :pca9641,
|
||||
devices: [
|
||||
%{bus: "i2c-1", address: 0x70, interrupt_pin: 7}
|
||||
]
|
||||
|
||||
Then use the functions in [PCA9641.Device] to send image data.
|
||||
Pretty simple.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Hello world.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> PCA9641.hello()
|
||||
:world
|
||||
|
||||
Connect to an PCA9641 device.
|
||||
"""
|
||||
def hello do
|
||||
:world
|
||||
def connect(config),
|
||||
do: Supervisor.start_child(PCA9641.Supervisor, {PCA9641.Device, config})
|
||||
|
||||
@doc """
|
||||
Disconnect an PCA9641 device.
|
||||
"""
|
||||
def disconnect(device_name) do
|
||||
Supervisor.terminate_child(PCA9641.Supervisor, {PCA9641.Device, device_name})
|
||||
Supervisor.delete_child(PCA9641.Supervisor, {PCA9641.Device, device_name})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule PCA9641.Commands do
|
||||
alias PCA9641.Registers
|
||||
alias ElixirALE.I2C
|
||||
alias Circuits.I2C
|
||||
use Bitwise
|
||||
|
||||
@moduledoc """
|
||||
|
@ -8,18 +8,27 @@ defmodule PCA9641.Commands do
|
|||
the device.
|
||||
"""
|
||||
|
||||
@doc false
|
||||
def start_link(bus, address), do: I2C.start_link(bus, address)
|
||||
@type bus_address :: {I2C.bus(), I2C.address()}
|
||||
|
||||
@doc false
|
||||
def release(pid), do: I2C.release(pid)
|
||||
@spec start_link(I2C.bus(), I2C.address()) :: {:ok, bus_address} | {:error, term}
|
||||
def start_link(bus, address) when is_integer(address) and address >= 0 and address <= 127 do
|
||||
case I2C.open(bus) do
|
||||
{:ok, bus} -> {:ok, {bus, address}}
|
||||
error -> error
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec release(bus_address) :: :ok
|
||||
def release({bus, _address}), do: I2C.release(bus)
|
||||
|
||||
@doc """
|
||||
Retrieve the device ID. For PCA9641 this should be 0x38.
|
||||
"""
|
||||
@spec id(pid) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def id(pid) do
|
||||
<<id>> = Registers.id(pid)
|
||||
@spec id(bus_address) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def id(bus_address) do
|
||||
<<id>> = Registers.id(bus_address)
|
||||
{:ok, id}
|
||||
end
|
||||
|
||||
|
@ -29,8 +38,8 @@ defmodule PCA9641.Commands do
|
|||
Master can set this register bit for setting priority of the winner when two
|
||||
masters request the downstream bus at the same time.
|
||||
"""
|
||||
@spec priority?(pid) :: boolean
|
||||
def priority?(pid), do: read_bit_as_boolean(pid, :control, 7)
|
||||
@spec priority?(bus_address) :: boolean
|
||||
def priority?(bus_address), do: read_bit_as_boolean(bus_address, :control, 7)
|
||||
|
||||
@doc """
|
||||
PRIORITY
|
||||
|
@ -38,8 +47,8 @@ defmodule PCA9641.Commands do
|
|||
Master can set this register bit for setting priority of the winner when two
|
||||
masters request the downstream bus at the same time.
|
||||
"""
|
||||
@spec priority(pid, boolean) :: :ok | {:error, term}
|
||||
def priority(pid, value), do: write_bit_as_boolean(pid, :control, 7, value)
|
||||
@spec priority(bus_address, boolean) :: :ok | {:error, term}
|
||||
def priority(bus_address, value), do: write_bit_as_boolean(bus_address, :control, 7, value)
|
||||
|
||||
@doc """
|
||||
SMBUS_DIS
|
||||
|
@ -51,8 +60,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Connectivity between master and downstream bus will be
|
||||
disconnected upon detecting an SMBus time-out condition.
|
||||
"""
|
||||
@spec downstream_disconnect_on_timeout?(pid) :: boolean
|
||||
def downstream_disconnect_on_timeout?(pid), do: read_bit_as_boolean(pid, :control, 6)
|
||||
@spec downstream_disconnect_on_timeout?(bus_address) :: boolean
|
||||
def downstream_disconnect_on_timeout?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :control, 6)
|
||||
|
||||
@doc """
|
||||
SMBUS_DIS
|
||||
|
@ -64,9 +74,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Connectivity between master and downstream bus will be
|
||||
disconnected upon detecting an SMBus time-out condition.
|
||||
"""
|
||||
@spec downstream_disconnect_on_timeout(pid, boolean) :: :ok | {:error, term}
|
||||
def downstream_disconnect_on_timeout(pid, value),
|
||||
do: write_bit_as_boolean(pid, :control, 6, value)
|
||||
@spec downstream_disconnect_on_timeout(bus_address, boolean) :: :ok | {:error, term}
|
||||
def downstream_disconnect_on_timeout(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :control, 6, value)
|
||||
|
||||
@doc """
|
||||
IDLE_TIMER_DIS
|
||||
|
@ -81,8 +91,8 @@ defmodule PCA9641.Commands do
|
|||
reserve timer is disabled, if the downstream bus is idle for more than 100
|
||||
ms, the connection between master and downstream bus will be disconnected.
|
||||
"""
|
||||
@spec idle_timer_disconnect?(pid) :: boolean
|
||||
def idle_timer_disconnect?(pid), do: read_bit_as_boolean(pid, :control, 5)
|
||||
@spec idle_timer_disconnect?(bus_address) :: boolean
|
||||
def idle_timer_disconnect?(bus_address), do: read_bit_as_boolean(bus_address, :control, 5)
|
||||
|
||||
@doc """
|
||||
IDLE_TIMER_DIS
|
||||
|
@ -97,8 +107,9 @@ defmodule PCA9641.Commands do
|
|||
reserve timer is disabled, if the downstream bus is idle for more than 100
|
||||
ms, the connection between master and downstream bus will be disconnected.
|
||||
"""
|
||||
@spec idle_timer_disconnect(pid, boolean) :: :ok | {:error, term}
|
||||
def idle_timer_disconnect(pid, value), do: write_bit_as_boolean(pid, :control, 5, value)
|
||||
@spec idle_timer_disconnect(bus_address, boolean) :: :ok | {:error, term}
|
||||
def idle_timer_disconnect(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :control, 5, value)
|
||||
|
||||
@doc """
|
||||
SMBUS_SWRST
|
||||
|
@ -110,8 +121,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Enable sending SMBus time-out to downstream bus, after receiving a
|
||||
general call soft reset from master.
|
||||
"""
|
||||
@spec smbus_software_reset?(pid) :: boolean
|
||||
def smbus_software_reset?(pid), do: read_bit_as_boolean(pid, :control, 4)
|
||||
@spec smbus_software_reset?(bus_address) :: boolean
|
||||
def smbus_software_reset?(bus_address), do: read_bit_as_boolean(bus_address, :control, 4)
|
||||
|
||||
@doc """
|
||||
SMBUS_SWRST
|
||||
|
@ -123,8 +134,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Enable sending SMBus time-out to downstream bus, after receiving a
|
||||
general call soft reset from master.
|
||||
"""
|
||||
@spec smbus_software_reset(pid, boolean) :: :ok | {:error, term}
|
||||
def smbus_software_reset(pid, value), do: write_bit_as_boolean(pid, :control, 4, value)
|
||||
@spec smbus_software_reset(bus_address, boolean) :: :ok | {:error, term}
|
||||
def smbus_software_reset(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :control, 4, value)
|
||||
|
||||
@doc """
|
||||
BUS_INIT
|
||||
|
@ -139,8 +151,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Start initialization on next bus connect function to downstream
|
||||
bus.
|
||||
"""
|
||||
@spec bus_init?(pid) :: boolean
|
||||
def bus_init?(pid), do: read_bit_as_boolean(pid, :control, 3)
|
||||
@spec bus_init?(bus_address) :: boolean
|
||||
def bus_init?(bus_address), do: read_bit_as_boolean(bus_address, :control, 3)
|
||||
|
||||
@doc """
|
||||
BUS_INIT
|
||||
|
@ -155,8 +167,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Start initialization on next bus connect function to downstream
|
||||
bus.
|
||||
"""
|
||||
@spec bus_init(pid, boolean) :: :ok | {:error, term}
|
||||
def bus_init(pid, value), do: write_bit_as_boolean(pid, :control, 3, value)
|
||||
@spec bus_init(bus_address, boolean) :: :ok | {:error, term}
|
||||
def bus_init(bus_address, value), do: write_bit_as_boolean(bus_address, :control, 3, value)
|
||||
|
||||
@doc """
|
||||
BUS_CONNECT
|
||||
|
@ -167,8 +179,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Do not connect I2C-bus from master to downstream bus.
|
||||
- `true` -> Connect downstream bus; the internal switch is closed only if LOCK_GRANT = 1.
|
||||
"""
|
||||
@spec bus_connect?(pid) :: boolean
|
||||
def bus_connect?(pid), do: read_bit_as_boolean(pid, :control, 2)
|
||||
@spec bus_connect?(bus_address) :: boolean
|
||||
def bus_connect?(bus_address), do: read_bit_as_boolean(bus_address, :control, 2)
|
||||
|
||||
@doc """
|
||||
BUS_CONNECT
|
||||
|
@ -179,8 +191,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Do not connect I2C-bus from master to downstream bus.
|
||||
- `true` -> Connect downstream bus; the internal switch is closed only if LOCK_GRANT = 1.
|
||||
"""
|
||||
@spec bus_connect(pid, boolean) :: :ok | {:error, term}
|
||||
def bus_connect(pid, value), do: write_bit_as_boolean(pid, :control, 2, value)
|
||||
@spec bus_connect(bus_address, boolean) :: :ok | {:error, term}
|
||||
def bus_connect(bus_address, value), do: write_bit_as_boolean(bus_address, :control, 2, value)
|
||||
|
||||
@doc """
|
||||
LOCK_GRANT
|
||||
|
@ -193,8 +205,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> This master does not have a lock on the downstream bus.
|
||||
- `true` -> This master has a lock on the downstream bus.
|
||||
"""
|
||||
@spec lock_grant?(pid) :: boolean
|
||||
def lock_grant?(pid), do: read_bit_as_boolean(pid, :control, 1)
|
||||
@spec lock_grant?(bus_address) :: boolean
|
||||
def lock_grant?(bus_address), do: read_bit_as_boolean(bus_address, :control, 1)
|
||||
|
||||
@doc """
|
||||
LOCK_REQ
|
||||
|
@ -209,8 +221,8 @@ defmodule PCA9641.Commands do
|
|||
up the lock if master had a lock on the downstream bus.
|
||||
- `true` -> Master is requesting a lock on the downstream bus.
|
||||
"""
|
||||
@spec lock_request?(pid) :: boolean
|
||||
def lock_request?(pid), do: read_bit_as_boolean(pid, :control, 0)
|
||||
@spec lock_request?(bus_address) :: boolean
|
||||
def lock_request?(bus_address), do: read_bit_as_boolean(bus_address, :control, 0)
|
||||
|
||||
@doc """
|
||||
LOCK_REQ
|
||||
|
@ -225,8 +237,8 @@ defmodule PCA9641.Commands do
|
|||
up the lock if master had a lock on the downstream bus.
|
||||
- `true` -> Master is requesting a lock on the downstream bus.
|
||||
"""
|
||||
@spec lock_request(pid, boolean) :: :ok | {:error, term}
|
||||
def lock_request(pid, value), do: write_bit_as_boolean(pid, :control, 0, value)
|
||||
@spec lock_request(bus_address, boolean) :: :ok | {:error, term}
|
||||
def lock_request(bus_address, value), do: write_bit_as_boolean(bus_address, :control, 0, value)
|
||||
|
||||
@doc """
|
||||
SDA_IO
|
||||
|
@ -243,8 +255,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> When read, indicates the SDA pin of the downstream bus is HIGH.
|
||||
When written, PCA9641 drives SDA pin of the downstream bus HIGH.
|
||||
"""
|
||||
@spec sda_becomes_io?(pid) :: boolean
|
||||
def sda_becomes_io?(pid), do: read_bit_as_boolean(pid, :status, 7)
|
||||
@spec sda_becomes_io?(bus_address) :: boolean
|
||||
def sda_becomes_io?(bus_address), do: read_bit_as_boolean(bus_address, :status, 7)
|
||||
|
||||
@doc """
|
||||
SDA_IO
|
||||
|
@ -261,8 +273,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> When read, indicates the SDA pin of the downstream bus is HIGH.
|
||||
When written, PCA9641 drives SDA pin of the downstream bus HIGH.
|
||||
"""
|
||||
@spec sda_becomes_io(pid, boolean) :: :ok | {:error, term}
|
||||
def sda_becomes_io(pid, value), do: write_bit_as_boolean(pid, :status, 7, value)
|
||||
@spec sda_becomes_io(bus_address, boolean) :: :ok | {:error, term}
|
||||
def sda_becomes_io(bus_address, value), do: write_bit_as_boolean(bus_address, :status, 7, value)
|
||||
|
||||
@doc """
|
||||
SCL_IO
|
||||
|
@ -279,8 +291,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> When read, shows the SCL pin of the downstream bus is HIGH. When
|
||||
written, PCA9641 drives SCL pin of the downstream bus HIGH.
|
||||
"""
|
||||
@spec scl_becomes_io?(pid) :: boolean
|
||||
def scl_becomes_io?(pid), do: read_bit_as_boolean(pid, :status, 6)
|
||||
@spec scl_becomes_io?(bus_address) :: boolean
|
||||
def scl_becomes_io?(bus_address), do: read_bit_as_boolean(bus_address, :status, 6)
|
||||
|
||||
@doc """
|
||||
SCL_IO
|
||||
|
@ -297,8 +309,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> When read, shows the SCL pin of the downstream bus is HIGH. When
|
||||
written, PCA9641 drives SCL pin of the downstream bus HIGH.
|
||||
"""
|
||||
@spec scl_becomes_io(pid, boolean) :: :ok | {:error, term}
|
||||
def scl_becomes_io(pid, value), do: write_bit_as_boolean(pid, :status, 6, value)
|
||||
@spec scl_becomes_io(bus_address, boolean) :: :ok | {:error, term}
|
||||
def scl_becomes_io(bus_address, value), do: write_bit_as_boolean(bus_address, :status, 6, value)
|
||||
|
||||
@doc """
|
||||
TEST_INT
|
||||
|
@ -313,8 +325,9 @@ defmodule PCA9641.Commands do
|
|||
Interrupt Mask register. Allows this master to invoke its Interrupt Service
|
||||
Routine to handle housekeeping tasks.
|
||||
"""
|
||||
@spec test_interrupt_pin(pid, boolean) :: :ok | {:error, term}
|
||||
def test_interrupt_pin(pid, value), do: write_bit_as_boolean(pid, :status, 5, value)
|
||||
@spec test_interrupt_pin(bus_address, boolean) :: :ok | {:error, term}
|
||||
def test_interrupt_pin(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :status, 5, value)
|
||||
|
||||
@doc """
|
||||
MBOX_FULL
|
||||
|
@ -326,8 +339,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No data is available for *this* master.
|
||||
- `true` -> Mailbox contains data for *this* master from the other master.
|
||||
"""
|
||||
@spec mailbox_full?(pid) :: boolean
|
||||
def mailbox_full?(pid), do: read_bit_as_boolean(pid, :status, 4)
|
||||
@spec mailbox_full?(bus_address) :: boolean
|
||||
def mailbox_full?(bus_address), do: read_bit_as_boolean(bus_address, :status, 4)
|
||||
|
||||
@doc """
|
||||
MBOX_EMPTY
|
||||
|
@ -342,8 +355,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> *Other* master mailbox is empty. *Other* master has read previous
|
||||
data and it is permitted to write new data.
|
||||
"""
|
||||
@spec mailbox_empty?(pid) :: boolean
|
||||
def mailbox_empty?(pid), do: read_bit_as_boolean(pid, :status, 3)
|
||||
@spec mailbox_empty?(bus_address) :: boolean
|
||||
def mailbox_empty?(bus_address), do: read_bit_as_boolean(bus_address, :status, 3)
|
||||
|
||||
@doc """
|
||||
BUS_HUNG
|
||||
|
@ -357,8 +370,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Downstream bus hung; when SDA signal is LOW and SCL signal does
|
||||
not toggle for more than 500 ms or SCL is LOW for 500 ms.
|
||||
"""
|
||||
@spec bus_hung?(pid) :: boolean
|
||||
def bus_hung?(pid), do: read_bit_as_boolean(pid, :status, 2)
|
||||
@spec bus_hung?(bus_address) :: boolean
|
||||
def bus_hung?(bus_address), do: read_bit_as_boolean(bus_address, :status, 2)
|
||||
|
||||
@doc """
|
||||
BUS_INIT_FAIL
|
||||
|
@ -372,8 +385,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Bus initialization has failed. SDA still LOW, the downstream bus
|
||||
cannot recover.
|
||||
"""
|
||||
@spec bus_initialisation_failed?(pid) :: boolean
|
||||
def bus_initialisation_failed?(pid), do: read_bit_as_boolean(pid, :status, 1)
|
||||
@spec bus_initialisation_failed?(bus_address) :: boolean
|
||||
def bus_initialisation_failed?(bus_address), do: read_bit_as_boolean(bus_address, :status, 1)
|
||||
|
||||
@doc """
|
||||
OTHER_LOCK
|
||||
|
@ -386,8 +399,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> The other master does not have a lock on the downstream bus.
|
||||
- `true` -> The other master has a lock on the downstream bus.
|
||||
"""
|
||||
@spec other_lock?(pid) :: boolean
|
||||
def other_lock?(pid), do: read_bit_as_boolean(pid, :status, 0)
|
||||
@spec other_lock?(bus_address) :: boolean
|
||||
def other_lock?(bus_address), do: read_bit_as_boolean(bus_address, :status, 0)
|
||||
|
||||
@doc """
|
||||
RES_TIME
|
||||
|
@ -397,9 +410,9 @@ defmodule PCA9641.Commands do
|
|||
Returns `{:ok, n}` where `n` is the number if milliseconds remaining in the
|
||||
reservation.
|
||||
"""
|
||||
@spec reserve_time(pid) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def reserve_time(pid) do
|
||||
<<ms>> = Registers.reserve_time(pid)
|
||||
@spec reserve_time(bus_address) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def reserve_time(bus_address) do
|
||||
<<ms>> = Registers.reserve_time(bus_address)
|
||||
{:ok, ms}
|
||||
end
|
||||
|
||||
|
@ -410,11 +423,11 @@ defmodule PCA9641.Commands do
|
|||
|
||||
`ms` is the number of milliseconds remaining in the reservation.
|
||||
"""
|
||||
@spec reserve_time(pid) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def reserve_time(pid, ms) when is_integer(ms) and ms >= 0 and ms <= 0xFF,
|
||||
do: Registers.reserve_time(pid, ms)
|
||||
@spec reserve_time(bus_address) :: {:ok, non_neg_integer} | {:error, term}
|
||||
def reserve_time(bus_address, ms) when is_integer(ms) and ms >= 0 and ms <= 0xFF,
|
||||
do: Registers.reserve_time(bus_address, ms)
|
||||
|
||||
def reserve_time(_pid, _ms), do: {:error, "Invalid milliseconds value"}
|
||||
def reserve_time(_bus_address, _ms), do: {:error, "Invalid milliseconds value"}
|
||||
|
||||
@doc """
|
||||
BUS_HUNG_INT
|
||||
|
@ -427,8 +440,8 @@ defmodule PCA9641.Commands do
|
|||
signal is LOW and SCL signal does not toggle for more than 500 ms or SCL is
|
||||
LOW for 500 ms,
|
||||
"""
|
||||
@spec bus_hung_interrupt?(pid) :: boolean
|
||||
def bus_hung_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 6)
|
||||
@spec bus_hung_interrupt?(bus_address) :: boolean
|
||||
def bus_hung_interrupt?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_status, 6)
|
||||
|
||||
@doc """
|
||||
BUS_HUNG_INT
|
||||
|
@ -441,8 +454,9 @@ defmodule PCA9641.Commands do
|
|||
signal is LOW and SCL signal does not toggle for more than 500 ms or SCL is
|
||||
LOW for 500 ms,
|
||||
"""
|
||||
@spec bus_hung_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def bus_hung_interrupt(pid, value), do: write_bit_as_boolean(pid, :interrupt_status, 6, value)
|
||||
@spec bus_hung_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def bus_hung_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 6, value)
|
||||
|
||||
@doc """
|
||||
MBOX_FULL_INT
|
||||
|
@ -452,8 +466,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt generated; mailbox is not full.
|
||||
- `true` -> Interrupt generated; mailbox full.
|
||||
"""
|
||||
@spec mailbox_full_interrupt?(pid) :: boolean
|
||||
def mailbox_full_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 5)
|
||||
@spec mailbox_full_interrupt?(bus_address) :: boolean
|
||||
def mailbox_full_interrupt?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :interrupt_status, 5)
|
||||
|
||||
@doc """
|
||||
MBOX_FULL_INT
|
||||
|
@ -463,9 +478,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt generated; mailbox is not full.
|
||||
- `true` -> Interrupt generated; mailbox full.
|
||||
"""
|
||||
@spec mailbox_full_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def mailbox_full_interrupt(pid, value),
|
||||
do: write_bit_as_boolean(pid, :interrupt_status, 5, value)
|
||||
@spec mailbox_full_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def mailbox_full_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 5, value)
|
||||
|
||||
@doc """
|
||||
MBOX_EMPTY_INT
|
||||
|
@ -475,8 +490,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt generated; sent mail is not empty.
|
||||
- `true` -> Interrupt generated; mailbox is empty.
|
||||
"""
|
||||
@spec mailbox_empty_interrupt?(pid) :: boolean
|
||||
def mailbox_empty_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 4)
|
||||
@spec mailbox_empty_interrupt?(bus_address) :: boolean
|
||||
def mailbox_empty_interrupt?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :interrupt_status, 4)
|
||||
|
||||
@doc """
|
||||
MBOX_EMPTY_INT
|
||||
|
@ -486,9 +502,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt generated; sent mail is not empty.
|
||||
- `true` -> Interrupt generated; mailbox is empty.
|
||||
"""
|
||||
@spec mailbox_empty_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def mailbox_empty_interrupt(pid, value),
|
||||
do: write_bit_as_boolean(pid, :interrupt_status, 4, value)
|
||||
@spec mailbox_empty_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def mailbox_empty_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 4, value)
|
||||
|
||||
@doc """
|
||||
TEST_INT_INT
|
||||
|
@ -500,8 +516,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Interrupt generated; master activates its interrupt pin via the
|
||||
TEST_INT bit in STATUS register.
|
||||
"""
|
||||
@spec test_interrupt_pin_interrupt?(pid) :: boolean
|
||||
def test_interrupt_pin_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 3)
|
||||
@spec test_interrupt_pin_interrupt?(bus_address) :: boolean
|
||||
def test_interrupt_pin_interrupt?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :interrupt_status, 3)
|
||||
|
||||
@doc """
|
||||
TEST_INT_INT
|
||||
|
@ -513,9 +530,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Interrupt generated; master activates its interrupt pin via the
|
||||
TEST_INT bit in STATUS register.
|
||||
"""
|
||||
@spec test_interrupt_pin_interrupt(pid, true) :: :ok | {:error, term}
|
||||
def test_interrupt_pin_interrupt(pid, value),
|
||||
do: write_bit_as_boolean(pid, :interrupt_status, 2, value)
|
||||
@spec test_interrupt_pin_interrupt(bus_address, true) :: :ok | {:error, term}
|
||||
def test_interrupt_pin_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 2, value)
|
||||
|
||||
@doc """
|
||||
LOCK_GRANT_INT
|
||||
|
@ -526,8 +543,9 @@ defmodule PCA9641.Commands do
|
|||
downstream bus.
|
||||
- `true` -> Interrupt generated; this master has a lock on the downstream bus.
|
||||
"""
|
||||
@spec lock_grant_interrupt?(pid) :: boolean
|
||||
def lock_grant_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 2)
|
||||
@spec lock_grant_interrupt?(bus_address) :: boolean
|
||||
def lock_grant_interrupt?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :interrupt_status, 2)
|
||||
|
||||
@doc """
|
||||
LOCK_GRANT_INT
|
||||
|
@ -538,8 +556,9 @@ defmodule PCA9641.Commands do
|
|||
downstream bus.
|
||||
- `true` -> Interrupt generated; this master has a lock on the downstream bus.
|
||||
"""
|
||||
@spec lock_grant_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def lock_grant_interrupt(pid, value), do: write_bit_as_boolean(pid, :interrupt_status, 2, value)
|
||||
@spec lock_grant_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def lock_grant_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 2, value)
|
||||
|
||||
@doc """
|
||||
BUS_LOST_INT
|
||||
|
@ -552,8 +571,8 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Interrupt generated; this master has involuntarily lost the
|
||||
control of the downstream bus.
|
||||
"""
|
||||
@spec bus_lost_interrupt?(pid) :: boolean
|
||||
def bus_lost_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 1)
|
||||
@spec bus_lost_interrupt?(bus_address) :: boolean
|
||||
def bus_lost_interrupt?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_status, 1)
|
||||
|
||||
@doc """
|
||||
BUS_LOST_INT
|
||||
|
@ -566,8 +585,9 @@ defmodule PCA9641.Commands do
|
|||
- `true` -> Interrupt generated; this master has involuntarily lost the
|
||||
control of the downstream bus.
|
||||
"""
|
||||
@spec bus_lost_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def bus_lost_interrupt(pid, value), do: write_bit_as_boolean(pid, :interrupt_status, 1, value)
|
||||
@spec bus_lost_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def bus_lost_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 1, value)
|
||||
|
||||
@doc """
|
||||
INT_IN_INT
|
||||
|
@ -578,8 +598,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt on interrupt input pin INT_IN.
|
||||
- `true` -> Interrupt on interrupt input pin INT_IN.
|
||||
"""
|
||||
@spec interupt_in_interrupt?(pid) :: boolean
|
||||
def interupt_in_interrupt?(pid), do: read_bit_as_boolean(pid, :interrupt_status, 0)
|
||||
@spec interupt_in_interrupt?(bus_address) :: boolean
|
||||
def interupt_in_interrupt?(bus_address),
|
||||
do: read_bit_as_boolean(bus_address, :interrupt_status, 0)
|
||||
|
||||
@doc """
|
||||
INT_IN_INT
|
||||
|
@ -590,9 +611,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> No interrupt on interrupt input pin INT_IN.
|
||||
- `true` -> Interrupt on interrupt input pin INT_IN.
|
||||
"""
|
||||
@spec interupt_in_interrupt(pid, boolean) :: :ok | {:error, term}
|
||||
def interupt_in_interrupt(pid, value),
|
||||
do: write_bit_as_boolean(pid, :interrupt_status, 0, value)
|
||||
@spec interupt_in_interrupt(bus_address, boolean) :: :ok | {:error, term}
|
||||
def interupt_in_interrupt(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_status, 0, value)
|
||||
|
||||
@doc """
|
||||
BUS_HUNG_MSK
|
||||
|
@ -600,8 +621,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when BUS_HUNG function is set.
|
||||
- `true` -> Disable output interrupt when BUS_HUNG function is set.
|
||||
"""
|
||||
@spec bus_hung_mask?(pid) :: boolean
|
||||
def bus_hung_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 6)
|
||||
@spec bus_hung_mask?(bus_address) :: boolean
|
||||
def bus_hung_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 6)
|
||||
|
||||
@doc """
|
||||
MBOX_FULL_MSK
|
||||
|
@ -609,8 +630,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when MBOX_FULL function is set.
|
||||
- `true` -> Disable output interrupt when MBOX_FULL function is set.
|
||||
"""
|
||||
@spec mailbox_full_mask?(pid) :: boolean
|
||||
def mailbox_full_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 5)
|
||||
@spec mailbox_full_mask?(bus_address) :: boolean
|
||||
def mailbox_full_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 5)
|
||||
|
||||
@doc """
|
||||
MBOX_FULL_MSK
|
||||
|
@ -618,8 +639,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when MBOX_FULL function is set.
|
||||
- `true` -> Disable output interrupt when MBOX_FULL function is set.
|
||||
"""
|
||||
@spec mailbox_full_mask(pid, boolean) :: :ok | {:error, term}
|
||||
def mailbox_full_mask(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 5, value)
|
||||
@spec mailbox_full_mask(bus_address, boolean) :: :ok | {:error, term}
|
||||
def mailbox_full_mask(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 5, value)
|
||||
|
||||
@doc """
|
||||
MBOX_EMPTY_MSK
|
||||
|
@ -627,8 +649,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when MBOX_EMPTY function is set.
|
||||
- `true` -> Disable output interrupt when MBOX_EMPTY function is set.
|
||||
"""
|
||||
@spec mailbox_empty_mask?(pid) :: boolean
|
||||
def mailbox_empty_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 4)
|
||||
@spec mailbox_empty_mask?(bus_address) :: boolean
|
||||
def mailbox_empty_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 4)
|
||||
|
||||
@doc """
|
||||
MBOX_EMPTY_MSK
|
||||
|
@ -636,8 +658,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when MBOX_EMPTY function is set.
|
||||
- `true` -> Disable output interrupt when MBOX_EMPTY function is set.
|
||||
"""
|
||||
@spec mailbox_empty_mask(pid, boolean) :: :ok | {:error, term}
|
||||
def mailbox_empty_mask(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 4, value)
|
||||
@spec mailbox_empty_mask(bus_address, boolean) :: :ok | {:error, term}
|
||||
def mailbox_empty_mask(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 4, value)
|
||||
|
||||
@doc """
|
||||
TEST_INT_MSK
|
||||
|
@ -645,8 +668,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when TEST_INT function is set.
|
||||
- `true` -> Disable output interrupt when TEST_INT function is set.
|
||||
"""
|
||||
@spec test_interrupt_mask?(pid) :: boolean
|
||||
def test_interrupt_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 3)
|
||||
@spec test_interrupt_mask?(bus_address) :: boolean
|
||||
def test_interrupt_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 3)
|
||||
|
||||
@doc """
|
||||
TEST_INT_MSK
|
||||
|
@ -654,8 +677,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when TEST_INT function is set.
|
||||
- `true` -> Disable output interrupt when TEST_INT function is set.
|
||||
"""
|
||||
@spec test_interrupt_mask?(pid, boolean) :: :ok | {:error, term}
|
||||
def test_interrupt_mask?(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 3, value)
|
||||
@spec test_interrupt_mask?(bus_address, boolean) :: :ok | {:error, term}
|
||||
def test_interrupt_mask?(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 3, value)
|
||||
|
||||
@doc """
|
||||
LOCK_GRANT_MSK
|
||||
|
@ -663,8 +687,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when LOCK_GRANT function is set.
|
||||
- `true` -> Disable output interrupt when LOCK_GRANT function is set.
|
||||
"""
|
||||
@spec lock_grant_mask?(pid) :: boolean
|
||||
def lock_grant_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 2)
|
||||
@spec lock_grant_mask?(bus_address) :: boolean
|
||||
def lock_grant_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 2)
|
||||
|
||||
@doc """
|
||||
LOCK_GRANT_MSK
|
||||
|
@ -672,8 +696,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when LOCK_GRANT function is set.
|
||||
- `true` -> Disable output interrupt when LOCK_GRANT function is set.
|
||||
"""
|
||||
@spec lock_grant_mask(pid, boolean) :: :ok | {:error, term}
|
||||
def lock_grant_mask(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 2, value)
|
||||
@spec lock_grant_mask(bus_address, boolean) :: :ok | {:error, term}
|
||||
def lock_grant_mask(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 2, value)
|
||||
|
||||
@doc """
|
||||
BUS_LOST_MSK
|
||||
|
@ -681,8 +706,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when BUS_LOST function is set.
|
||||
- `true` -> Disable output interrupt when BUS_LOST function is set.
|
||||
"""
|
||||
@spec bus_lost_mask?(pid) :: boolean
|
||||
def bus_lost_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 1)
|
||||
@spec bus_lost_mask?(bus_address) :: boolean
|
||||
def bus_lost_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 1)
|
||||
|
||||
@doc """
|
||||
BUS_LOST_MSK
|
||||
|
@ -690,8 +715,9 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when BUS_LOST function is set.
|
||||
- `true` -> Disable output interrupt when BUS_LOST function is set.
|
||||
"""
|
||||
@spec bus_lost_mask(pid, boolean) :: :ok | {:error, term}
|
||||
def bus_lost_mask(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 1, value)
|
||||
@spec bus_lost_mask(bus_address, boolean) :: :ok | {:error, term}
|
||||
def bus_lost_mask(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 1, value)
|
||||
|
||||
@doc """
|
||||
INT_IN_MSK
|
||||
|
@ -699,8 +725,8 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when INT_IN function is set.
|
||||
- `true` -> Disable output interrupt when INT_IN function is set.
|
||||
"""
|
||||
@spec int_in_mask?(pid) :: boolean
|
||||
def int_in_mask?(pid), do: read_bit_as_boolean(pid, :interrupt_mask, 0)
|
||||
@spec int_in_mask?(bus_address) :: boolean
|
||||
def int_in_mask?(bus_address), do: read_bit_as_boolean(bus_address, :interrupt_mask, 0)
|
||||
|
||||
@doc """
|
||||
INT_IN_MSK
|
||||
|
@ -708,44 +734,45 @@ defmodule PCA9641.Commands do
|
|||
- `false` -> Enable output interrupt when INT_IN function is set.
|
||||
- `true` -> Disable output interrupt when INT_IN function is set.
|
||||
"""
|
||||
@spec int_in_mask(pid, boolean) :: :ok | {:error, term}
|
||||
def int_in_mask(pid, value), do: write_bit_as_boolean(pid, :interrupt_mask, 0, value)
|
||||
@spec int_in_mask(bus_address, boolean) :: :ok | {:error, term}
|
||||
def int_in_mask(bus_address, value),
|
||||
do: write_bit_as_boolean(bus_address, :interrupt_mask, 0, value)
|
||||
|
||||
@doc """
|
||||
Read shared mailbox.
|
||||
"""
|
||||
@spec read_mailbox(pid) :: {:ok, binary} | {:error, term}
|
||||
def read_mailbox(pid), do: Registers.mailbox(pid)
|
||||
@spec read_mailbox(bus_address) :: {:ok, binary} | {:error, term}
|
||||
def read_mailbox(bus_address), do: Registers.mailbox(bus_address)
|
||||
|
||||
@doc """
|
||||
Write shared mailbox.
|
||||
"""
|
||||
@spec write_mailbox(pid, binary) :: :ok | {:error, term}
|
||||
def write_mailbox(pid, message), do: Registers.mailbox(pid, message)
|
||||
@spec write_mailbox(bus_address, binary) :: :ok | {:error, term}
|
||||
def write_mailbox(bus_address, message), do: Registers.mailbox(bus_address, message)
|
||||
|
||||
@doc """
|
||||
Request access to downstream bus.
|
||||
|
||||
Requests access to the downstream bus and blocks until given access.
|
||||
"""
|
||||
@spec request_downstream_bus(pid) :: :ok | {:error, term}
|
||||
def request_downstream_bus(pid), do: request_downstream_bus(pid, 0)
|
||||
@spec request_downstream_bus(bus_address) :: :ok | {:error, term}
|
||||
def request_downstream_bus(bus_address), do: request_downstream_bus(bus_address, 0)
|
||||
|
||||
@doc """
|
||||
Request access to downstream bus.
|
||||
|
||||
Requests access to the downstream bus and blocks until given access.
|
||||
"""
|
||||
@spec request_downstream_bus(pid, non_neg_integer) :: :ok | {:error, term}
|
||||
def request_downstream_bus(pid, reserve_time)
|
||||
@spec request_downstream_bus(bus_address, non_neg_integer) :: :ok | {:error, term}
|
||||
def request_downstream_bus(bus_address, reserve_time)
|
||||
when is_integer(reserve_time) and reserve_time >= 0 and reserve_time <= 0xFF do
|
||||
with :ok <- Registers.reserve_time(pid, reserve_time),
|
||||
with :ok <- Registers.reserve_time(bus_address, reserve_time),
|
||||
# Request the bus lock.
|
||||
:ok <- Registers.control(pid, 0x1),
|
||||
:ok <- block_until_lock_granted(pid),
|
||||
:ok <- Registers.control(bus_address, 0x1),
|
||||
:ok <- block_until_lock_granted(bus_address),
|
||||
# Connect the downstream bus.
|
||||
:ok <- Registers.control(pid, 0x5),
|
||||
true <- bus_connect?(pid) do
|
||||
:ok <- Registers.control(bus_address, 0x5),
|
||||
true <- bus_connect?(bus_address) do
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
@ -753,46 +780,46 @@ defmodule PCA9641.Commands do
|
|||
@doc """
|
||||
Abandon access to the downstream bus.
|
||||
"""
|
||||
@spec abandon_downstream_bus(pid) :: :ok | {:error, term}
|
||||
def abandon_downstream_bus(pid), do: Registers.control(pid, 0)
|
||||
@spec abandon_downstream_bus(bus_address) :: :ok | {:error, term}
|
||||
def abandon_downstream_bus(bus_address), do: Registers.control(bus_address, 0)
|
||||
|
||||
defp block_until_lock_granted(pid) do
|
||||
if lock_grant?(pid) do
|
||||
defp block_until_lock_granted(bus_address) do
|
||||
if lock_grant?(bus_address) do
|
||||
:ok
|
||||
else
|
||||
:timer.sleep(5)
|
||||
block_until_lock_granted(pid)
|
||||
block_until_lock_granted(bus_address)
|
||||
end
|
||||
end
|
||||
|
||||
defp read_bit_as_boolean(pid, register, bit)
|
||||
when is_pid(pid) and is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
defp read_bit_as_boolean(bus_address, register, bit)
|
||||
when is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
value =
|
||||
Registers
|
||||
|> apply(register, [pid])
|
||||
|> apply(register, [bus_address])
|
||||
|> get_bit(bit)
|
||||
|
||||
value == 1
|
||||
end
|
||||
|
||||
defp write_bit_as_boolean(pid, register, bit, true)
|
||||
when is_pid(pid) and is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
defp write_bit_as_boolean(bus_address, register, bit, true)
|
||||
when is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
value =
|
||||
Registers
|
||||
|> apply(register, [pid])
|
||||
|> apply(register, [bus_address])
|
||||
|> set_bit(bit)
|
||||
|
||||
apply(Registers, register, [pid, value])
|
||||
apply(Registers, register, [bus_address, value])
|
||||
end
|
||||
|
||||
defp write_bit_as_boolean(pid, register, bit, false)
|
||||
when is_pid(pid) and is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
defp write_bit_as_boolean(bus_address, register, bit, false)
|
||||
when is_atom(register) and is_integer(bit) and bit >= 0 and bit < 8 do
|
||||
value =
|
||||
Registers
|
||||
|> apply(register, [pid])
|
||||
|> apply(register, [bus_address])
|
||||
|> clear_bit(bit)
|
||||
|
||||
apply(Registers, register, [pid, value])
|
||||
apply(Registers, register, [bus_address, value])
|
||||
end
|
||||
|
||||
defp get_bit(<<byte>>, bit), do: byte >>> bit &&& 1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
defmodule PCA9641.Registers do
|
||||
alias ElixirALE.I2C
|
||||
alias Circuits.I2C
|
||||
use Bitwise
|
||||
|
||||
@moduledoc """
|
||||
|
@ -10,57 +10,96 @@ defmodule PCA9641.Registers do
|
|||
use the `Commands` module instead.
|
||||
"""
|
||||
|
||||
@type bus_address :: {I2C.bus(), I2C.address()}
|
||||
@type byte :: 0..255
|
||||
@type double :: 0..65535
|
||||
|
||||
@doc """
|
||||
Register 0: ID Register. 1 byte. RO.
|
||||
"""
|
||||
def id(pid), do: read_register(pid, 0)
|
||||
@spec id(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def id(bus_address), do: read_register(bus_address, 0)
|
||||
|
||||
@doc """
|
||||
Register 1: Control. 1 byte. RW.
|
||||
"""
|
||||
def control(pid), do: read_register(pid, 1)
|
||||
def control(pid, byte), do: write_register(pid, 1, byte)
|
||||
@spec control(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def control(bus_address), do: read_register(bus_address, 1)
|
||||
|
||||
@doc """
|
||||
Register 1: Control. 1 byte. RW.
|
||||
"""
|
||||
@spec control(bus_address, byte) :: :ok | {:error, term}
|
||||
def control(bus_address, byte), do: write_register(bus_address, 1, byte)
|
||||
|
||||
@doc """
|
||||
Register 2: Status. 1 byte. RO.
|
||||
"""
|
||||
def status(pid), do: read_register(pid, 2)
|
||||
@spec status(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def status(bus_address), do: read_register(bus_address, 2)
|
||||
|
||||
@doc """
|
||||
Register 3: Reserve Time. 1 byte. RW.
|
||||
"""
|
||||
def reserve_time(pid), do: read_register(pid, 3)
|
||||
def reserve_time(pid, byte), do: write_register(pid, 3, byte)
|
||||
@spec reserve_time(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def reserve_time(bus_address), do: read_register(bus_address, 3)
|
||||
|
||||
@doc """
|
||||
Register 3: Reserve Time. 1 byte. RW.
|
||||
"""
|
||||
@spec reserve_time(bus_address, byte) :: :ok | {:error, term}
|
||||
def reserve_time(bus_address, byte), do: write_register(bus_address, 3, byte)
|
||||
|
||||
@doc """
|
||||
Register 4: Interrupt Status Register. 1 byte. RW.
|
||||
"""
|
||||
def interrupt_status(pid), do: read_register(pid, 4)
|
||||
def interrupt_status(pid, byte), do: write_register(pid, 4, byte)
|
||||
@spec interrupt_status(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def interrupt_status(bus_address), do: read_register(bus_address, 4)
|
||||
|
||||
@doc """
|
||||
Register 4: Interrupt Status Register. 1 byte. RW.
|
||||
"""
|
||||
@spec interrupt_status(bus_address, byte) :: :ok | {:error, term}
|
||||
def interrupt_status(bus_address, byte), do: write_register(bus_address, 4, byte)
|
||||
|
||||
@doc """
|
||||
Register 5: Interrupt Mask Register. 1 byte. RW.
|
||||
"""
|
||||
def interrupt_mask(pid), do: read_register(pid, 5)
|
||||
def interrupt_mask(pid, byte), do: write_register(pid, 5, byte)
|
||||
@spec interrupt_mask(bus_address) :: {:ok, byte} | {:error, term}
|
||||
def interrupt_mask(bus_address), do: read_register(bus_address, 5)
|
||||
|
||||
@doc """
|
||||
Register 5: Interrupt Mask Register. 1 byte. RW.
|
||||
"""
|
||||
@spec interrupt_mask(bus_address, byte) :: :ok | {:error, term}
|
||||
def interrupt_mask(bus_address, byte), do: write_register(bus_address, 5, byte)
|
||||
|
||||
@doc """
|
||||
Register 6 (and 7): Mailbox. 2 bytes. RW.
|
||||
"""
|
||||
def mailbox(pid) do
|
||||
lsb = read_register(pid, 6)
|
||||
msb = read_register(pid, 7)
|
||||
@spec mailbox(bus_address) :: {:ok, double} | {:error, term}
|
||||
def mailbox(bus_address) do
|
||||
lsb = read_register(bus_address, 6)
|
||||
msb = read_register(bus_address, 7)
|
||||
(msb <<< 8) + lsb
|
||||
end
|
||||
|
||||
def mailbox(pid, message) do
|
||||
@doc """
|
||||
Register 6 (and 7): Mailbox. 2 bytes. RW.
|
||||
"""
|
||||
@spec mailbox(bus_address, double) :: :ok | {:error, term}
|
||||
def mailbox(bus_address, message) do
|
||||
msb = message >>> 8 &&& 0xFF
|
||||
lsb = message &&& 0xFF
|
||||
with :ok <- write_register(pid, 6, lsb), :ok <- write_register(pid, 7, msb), do: :ok
|
||||
|
||||
with :ok <- write_register(bus_address, 6, lsb),
|
||||
:ok <- write_register(bus_address, 7, msb),
|
||||
do: :ok
|
||||
end
|
||||
|
||||
defp read_register(pid, register, bytes \\ 1), do: I2C.write_read(pid, <<register>>, bytes)
|
||||
defp read_register({bus, address}, register, bytes \\ 1),
|
||||
do: I2C.write_read(bus, address, <<register>>, bytes)
|
||||
|
||||
defp write_register(pid, register, byte) when is_integer(byte),
|
||||
do: I2C.write(pid, <<register, byte>>)
|
||||
defp write_register({bus, address}, register, byte) when is_integer(byte),
|
||||
do: I2C.write(bus, address, <<register, byte>>)
|
||||
end
|
||||
|
|
4
mix.exs
4
mix.exs
|
@ -4,7 +4,7 @@ defmodule PCA9641.MixProject do
|
|||
def project do
|
||||
[
|
||||
app: :pca9641,
|
||||
version: "0.1.0",
|
||||
version: "0.2.0",
|
||||
elixir: "~> 1.9",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
description: "Driver for PCA9641 2-channel I2C bus master arbiter chip",
|
||||
|
@ -34,7 +34,7 @@ defmodule PCA9641.MixProject do
|
|||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
{:elixir_ale, "~> 1.2"},
|
||||
{:circuits_i2c, "~> 0.3"},
|
||||
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false}
|
||||
]
|
||||
end
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -1,6 +1,6 @@
|
|||
%{
|
||||
"circuits_i2c": {:hex, :circuits_i2c, "0.3.5", "43e043d7efc3aead364061f8a7ed627f81ff7cef52bfa47cb629d8a68ca56a9f", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.4.1", "07bb382826ee8d08d575a1981f971ed41bd5d7e86b917fd012a93c51b5d28727", [:mix], [], "hexpm"},
|
||||
"elixir_ale": {:hex, :elixir_ale, "1.2.1", "07ac2f17a0191b8bd3b0df6b526c7f699a3a4d690c9def573fcb5824eef24d98", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
|
Loading…
Reference in a new issue