Drone.Adapters.Crazyflie.CRTP (ex_drone v0.3.0)

View Source

Pure CRTP packet encode/decode for Crazyflie communication.

A CRTP packet is a 1-byte header plus a payload of at most 30 bytes. Header layout (matching the documented CRTP format used by Crazyflie 2.x):

bits 7..4  port (0..15)
bits 3..2  link (legacy; set to `0b11`)
bits 1..0  channel (0..3)

Null packets use port 15 / channel 3 and are used to poll the radio link.

Examples

packet = %{port: 8, channel: 0, payload: <<3, 0>>}
{:ok, <<header, payload::binary>>} = Drone.Adapters.Crazyflie.CRTP.encode(packet)
{:ok, ^packet} = Drone.Adapters.Crazyflie.CRTP.decode(<<header, payload::binary>>)

Summary

Types

Decoded CRTP packet.

Functions

Decodes a CRTP binary into a packet map.

Decodes a header byte into {port, channel}.

Encodes a CRTP packet to a binary (header <> payload).

Encodes a null packet binary (single 0xFF header with empty payload).

Builds a CRTP header byte from port and channel.

Maximum CRTP payload size in bytes.

True when the packet is a null/poll packet (port 15, channel 3).

Builds a null packet used to poll downlink when idle.

Types

packet()

@type packet() :: %{port: 0..15, channel: 0..3, payload: binary()}

Decoded CRTP packet.

FieldTypeMeaning
:port0..15CRTP port (subsystem); see Drone.Adapters.Crazyflie.CRTP.Ports
:channel0..3Channel within the port
:payloadbinary()0..30 bytes of command/data

Examples

%{port: 15, channel: 3, payload: <<>>}  # null / poll
%{port: 8, channel: 0, payload: <<3, 0>>}  # high-level STOP, group 0
%{port: 9, channel: 0, payload: <<0>>}  # supervisor arm

Functions

decode(arg1)

@spec decode(binary()) :: {:ok, packet()} | {:error, :empty_packet | :invalid_packet}

Decodes a CRTP binary into a packet map.

Parameters

  • binary (binary()) — raw CRTP frame (header <> payload)

Returns

  • {:ok, packet()} — decoded packet
  • {:error, :empty_packet} — empty binary
  • {:error, :invalid_packet} — payload longer than 30 bytes or non-binary

Examples

{:ok, %{port: 15, channel: 3, payload: <<>>}} =
  Drone.Adapters.Crazyflie.CRTP.decode(<<0xFF>>)

{:error, :empty_packet} = Drone.Adapters.Crazyflie.CRTP.decode(<<>>)

decode_header(header)

@spec decode_header(byte()) :: {0..15, 0..3}

Decodes a header byte into {port, channel}.

Parameters

  • header (byte()) — first byte of a CRTP frame

Returns

{port :: 0..15, channel :: 0..3}.

Examples

{8, 0} = Drone.Adapters.Crazyflie.CRTP.decode_header(0x8C)

encode(arg1)

@spec encode(packet()) ::
  {:ok, binary()} | {:error, :oversized_payload | :invalid_packet}

Encodes a CRTP packet to a binary (header <> payload).

Parameters

  • packet (packet/0) — map with :port, :channel, :payload

Returns

  • {:ok, binary()} — encoded frame
  • {:error, :oversized_payload} — payload longer than 30 bytes
  • {:error, :invalid_packet} — missing or out-of-range fields

Examples

{:ok, bin} =
  Drone.Adapters.Crazyflie.CRTP.encode(%{
    port: 9,
    channel: 0,
    payload: <<0>>
  })

{:error, :oversized_payload} =
  Drone.Adapters.Crazyflie.CRTP.encode(%{
    port: 0,
    channel: 0,
    payload: :binary.copy(<<0>>, 31)
  })

encode_null()

@spec encode_null() :: binary()

Encodes a null packet binary (single 0xFF header with empty payload).

Returns

binary() — typically <<0xFF>>.

Examples

<<0xFF>> = Drone.Adapters.Crazyflie.CRTP.encode_null()

header(port, channel)

@spec header(0..15, 0..3) :: byte()

Builds a CRTP header byte from port and channel.

The legacy link bits are always set to 0b11.

Parameters

  • port (0..15) — CRTP port number
  • channel (0..3) — channel within the port

Returns

byte() header.

Examples

header = Drone.Adapters.Crazyflie.CRTP.header(15, 3)
{15, 3} = Drone.Adapters.Crazyflie.CRTP.decode_header(header)

max_payload()

@spec max_payload() :: 30

Maximum CRTP payload size in bytes.

Returns

30.

Examples

30 = Drone.Adapters.Crazyflie.CRTP.max_payload()

null?(arg1)

@spec null?(packet()) :: boolean()

True when the packet is a null/poll packet (port 15, channel 3).

Parameters

Returns

boolean().

Examples

true = Drone.Adapters.Crazyflie.CRTP.null?(Drone.Adapters.Crazyflie.CRTP.null_packet())
false = Drone.Adapters.Crazyflie.CRTP.null?(%{port: 8, channel: 0, payload: <<>>})

null_packet()

@spec null_packet() :: packet()

Builds a null packet used to poll downlink when idle.

Returns

packet/0 with port 15, channel 3, empty payload.

Examples

%{port: 15, channel: 3, payload: <<>>} =
  Drone.Adapters.Crazyflie.CRTP.null_packet()