# `Sml.CRC16`
[🔗](https://github.com/emischorr/sml_ex/blob/v0.1.0/lib/sml/crc16.ex#L1)

The 16 bit checksums used by SML for the transport frame and each message.

The standard algorithm is CRC-16/X-25 (polynomial `0x1021` reflected,
init `0xFFFF`, final XOR `0xFFFF`), transmitted low byte first. Some meters,
notably the Holley DTZ541, use CRC-16/Kermit (init `0`, no final XOR)
transmitted high byte first instead.

`valid?/3` checks the two checksum bytes as they appear on the wire against
either or both variants.

# `mode`

```elixir
@type mode() :: :auto | :x25 | :kermit
```

# `kermit`

```elixir
@spec kermit(binary()) :: 0..65535
```

Calculates the CRC-16/Kermit checksum of `data`.

    iex> Sml.CRC16.kermit("123456789")
    0x2189

# `valid?`

```elixir
@spec valid?(binary(), &lt;&lt;_::16&gt;&gt;, mode()) :: boolean()
```

Checks the checksum bytes `crc` (in wire order) for `data`.

`mode` is `:x25`, `:kermit` or `:auto` (accept either).

    iex> Sml.CRC16.valid?("123456789", <<0x6E, 0x90>>, :x25)
    true

    iex> Sml.CRC16.valid?("123456789", <<0x21, 0x89>>, :auto)
    true

# `x25`

```elixir
@spec x25(binary()) :: 0..65535
```

Calculates the CRC-16/X-25 checksum of `data`.

    iex> Sml.CRC16.x25("123456789")
    0x906E

---

*Consult [api-reference.md](api-reference.md) for complete listing*
