Circuits.UART v1.4.1 Circuits.UART View Source

Find and use UARTs, serial ports, and more.

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor.

Close the serial port. The GenServer continues to run so that a port can be opened again.

Get the configuration of the serial port.

Change the serial port configuration after open/3 has been called. See open/3 for the valid options.

Change the controlling process that receives events from an active uart.

Waits until all data has been transmitted. See tcdrain(3) for low level details on Linux or OSX. This is not implemented on Windows.

Return a map of available ports with information about each one. The map looks like this

Find UARTs.

Flushes the :receive buffer, the :transmit buffer, or :both.

Invoked when the server is started. start_link/3 or start/3 will block until it returns.

Open a serial port.

Read data from the UART. This call returns data as soon as it's available or after timing out.

Send a continuous stream of zero bits for a duration in milliseconds. By default, the zero bits are transmitted at least 0.25 seconds.

Start or stop sending a break signal.

Set or clear the Data Terminal Ready signal.

Set or clear the Request To Send signal.

Returns a map of signal names and their current state (true or false). Signals include

Start up a UART GenServer.

Stop the UART GenServer.

Write data to the opened UART. It's possible for the write to return before all of the data is actually transmitted. To wait for the data, call drain/1.

Link to this section Types

Link to this type

uart_option()

View Source
uart_option() ::
  {:active, boolean()}
  | {:speed, non_neg_integer()}
  | {:data_bits, 5..8}
  | {:stop_bits, 1..2}
  | {:parity, :none | :even | :odd | :space | :mark | :ignore}
  | {:flow_control, :none | :hardware | :software}
  | {:framing, module() | {module(), [term()]}}
  | {:rx_framing_timeout, integer()}
  | {:id, :name | :pid}

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

close(pid)

View Source
close(GenServer.server()) :: :ok | {:error, term()}

Close the serial port. The GenServer continues to run so that a port can be opened again.

Link to this function

configuration(pid)

View Source
configuration(GenServer.server()) :: {binary() | :closed, [uart_option()]}

Get the configuration of the serial port.

Link to this function

configure(pid, opts)

View Source
configure(GenServer.server(), [uart_option()]) :: :ok | {:error, term()}

Change the serial port configuration after open/3 has been called. See open/3 for the valid options.

Link to this function

controlling_process(pid, controlling_process)

View Source
controlling_process(GenServer.server(), pid()) :: :ok | {:error, term()}

Change the controlling process that receives events from an active uart.

Link to this function

drain(pid)

View Source
drain(GenServer.server()) :: :ok | {:error, term()}

Waits until all data has been transmitted. See tcdrain(3) for low level details on Linux or OSX. This is not implemented on Windows.

Link to this function

enumerate()

View Source
enumerate() :: map()

Return a map of available ports with information about each one. The map looks like this:

   %{ "ttyS0" -> %{vendor_id: 1234, product_id: 1,
                   manufacturer: "Acme Corporation", serial_number: "000001"},
      "ttyUSB0" -> ${vendor_id: 1234, product_id: 2} }

Depending on the port and the operating system, not all fields may be returned. Informational fields are:

  • :vendor_id - The 16-bit USB vendor ID of the device providing the port. Vendor ID to name lists are managed through usb.org
  • :product_id - The 16-bit vendor supplied product ID
  • :manufacturer - The manufacturer of the port
  • :description - A description or product name
  • :serial_number - The device's serial number if it has one
Link to this function

find_pids()

View Source
find_pids() :: [{binary() | :closed, pid()}]

Find UARTs.

This is intended as a diagnostic function for finding UARTs that you may have opened and forgotten about. Since a UART can only be opened once, this helps you find the problematic one so that you can close it.

It returns a list of {pid, uart_name} tuples.

NOTE: Do not rely on this function in production code. It may change if updates to the interface make it more convenient to use.

Link to this function

flush(pid, direction \\ :both)

View Source

Flushes the :receive buffer, the :transmit buffer, or :both.

See tcflush(3) for low level details on Linux or OSX. This calls PurgeComm on Windows.

Invoked when the server is started. start_link/3 or start/3 will block until it returns.

init_arg is the argument term (second argument) passed to start_link/3.

Returning {:ok, state} will cause start_link/3 to return {:ok, pid} and the process to enter its loop.

Returning {:ok, state, timeout} is similar to {:ok, state}, except that it also sets a timeout. See the "Timeouts" section in the module documentation for more information.

Returning {:ok, state, :hibernate} is similar to {:ok, state} except the process is hibernated before entering the loop. See c:handle_call/3 for more information on hibernation.

Returning {:ok, state, {:continue, continue}} is similar to {:ok, state} except that immediately after entering the loop the c:handle_continue/2 callback will be invoked with the value continue as first argument.

Returning :ignore will cause start_link/3 to return :ignore and the process will exit normally without entering the loop or calling c:terminate/2. If used when part of a supervision tree the parent supervisor will not fail to start nor immediately try to restart the GenServer. The remainder of the supervision tree will be started and so the GenServer should not be required by other processes. It can be started later with Supervisor.restart_child/2 as the child specification is saved in the parent supervisor. The main use cases for this are:

  • The GenServer is disabled by configuration but might be enabled later.
  • An error occurred and it will be handled by a different mechanism than the Supervisor. Likely this approach involves calling Supervisor.restart_child/2 after a delay to attempt a restart.

Returning {:stop, reason} will cause start_link/3 to return {:error, reason} and the process to exit with reason reason without entering the loop or calling c:terminate/2.

Callback implementation for GenServer.init/1.

Link to this function

open(pid, name, opts \\ [])

View Source
open(GenServer.server(), binary(), [uart_option()]) :: :ok | {:error, term()}

Open a serial port.

The following options are available:

  • :active - (true or false) specifies whether data is received as messages or by calling read/2. See discussion below.

  • :speed - (number) set the initial baudrate (e.g., 115200)

  • :data_bits - (5, 6, 7, 8) set the number of data bits (usually 8)

  • :stop_bits - (1, 2) set the number of stop bits (usually 1)

  • :parity - (:none, :even, :odd, :space, or :mark) set the parity. Usually this is :none. Other values:

    • :space means that the parity bit is always 0
    • :mark means that the parity bit is always 1
    • :ignore means that the parity bit is ignored (Linux/OSX only)
  • :flow_control - (:none, :hardware, or :software) set the flow control strategy.

  • :framing - (module or {module, args}) set the framing for data. The module must implement the Circuits.UART.Framing behaviour. See Circuits.UART.Framing.None, Circuits.UART.Framing.Line, and Circuits.UART.Framing.FourByte. The default is Circuits.UART.Framing.None.

  • :rx_framing_timeout - (milliseconds) this specifies how long incomplete frames will wait for the remainder to be received. Timed out partial frames are reported as {:partial, data}. A timeout of <= 0 means to wait forever.

  • :id - (:name or :pid) specify what to return with the uart active messages. with :name the messages are returned as {:circuits_uart, serial_port_name, data} otherwise they are returned as {:circuits_uart, pid, data}. The name and pid are the name of the connected UART or the pid of the Circuits.UART server pid as returned by start_link/1. The default value is :name.

Active mode defaults to true and means that data received on the UART is reported in messages. The messages have the following form:

{:circuits_uart, serial_port_id, data}

or

{:circuits_uart, serial_port_id, {:error, reason}}

When in active mode, flow control can not be used to push back on the sender and messages will accumulated in the mailbox should data arrive fast enough. If this is an issue, set :active to false and call read/2 manually when ready for more data.

On success, open/3 returns :ok. On error, {:error, reason} is returned. The following are some reasons:

  • :enoent - the specified port couldn't be found
  • :eagain - the port is already open
  • :eacces - permission was denied when opening the port
Link to this function

read(pid, timeout \\ 5000)

View Source
read(GenServer.server(), non_neg_integer()) ::
  {:ok, binary()} | {:error, term()}

Read data from the UART. This call returns data as soon as it's available or after timing out.

Returns {:ok, binary}, where binary is a binary data object that contains the read data, or {:error, reason} if an error occurs.

Typical error reasons:

  • :ebadf - the UART is closed
  • :einval - the UART is in active mode
Link to this function

send_break(pid, duration \\ 250)

View Source
send_break(GenServer.server(), integer()) :: :ok | {:error, term()}

Send a continuous stream of zero bits for a duration in milliseconds. By default, the zero bits are transmitted at least 0.25 seconds.

This is a convenience function for calling set_break/2 to enable the break signal, wait, and then turn it off.

Link to this function

set_break(pid, value)

View Source
set_break(GenServer.server(), boolean()) :: :ok | {:error, term()}

Start or stop sending a break signal.

Link to this function

set_dtr(pid, value)

View Source
set_dtr(GenServer.server(), boolean()) :: :ok | {:error, term()}

Set or clear the Data Terminal Ready signal.

Link to this function

set_rts(pid, value)

View Source
set_rts(GenServer.server(), boolean()) :: :ok | {:error, term()}

Set or clear the Request To Send signal.

Link to this function

signals(pid)

View Source
signals(GenServer.server()) :: map() | {:error, term()}

Returns a map of signal names and their current state (true or false). Signals include:

  • :dsr - Data Set Ready
  • :dtr - Data Terminal Ready
  • :rts - Request To Send
  • :st - Secondary Transmitted Data
  • :sr - Secondary Received Data
  • :cts - Clear To Send
  • :cd - Data Carrier Detect
  • :rng - Ring Indicator
Link to this function

start_link(opts \\ [])

View Source
start_link([term()]) :: {:ok, pid()} | {:error, term()}

Start up a UART GenServer.

Stop the UART GenServer.

Link to this function

write(pid, data, timeout \\ 5000)

View Source
write(GenServer.server(), iodata(), non_neg_integer()) :: :ok | {:error, term()}

Write data to the opened UART. It's possible for the write to return before all of the data is actually transmitted. To wait for the data, call drain/1.

This call blocks until all of the data to be written is in the operating system's internal buffers. If you're sending a lot of data on a slow link, supply a longer timeout to avoid timing out prematurely.

Returns :ok on success or {:error, reason} if an error occurs.

Typical error reasons:

  • :ebadf - the UART is closed