# `EtherCAT.Slave.Mailbox.CoE`
[🔗](https://github.com/sid2baker/ethercat/blob/main/lib/ethercat/slave/mailbox/coe.ex#L34)

CANopen over EtherCAT (CoE) mailbox protocol.

Implements blocking SDO download/upload transfers over the mailbox SyncManagers.
The transfer mode is selected internally:

- expedited for small payloads
- normal + segmented for larger payloads

This module stays procedural and synchronous because it is currently used from
slave PREOP configuration paths, not as a standalone mailbox state machine.

This is the runtime CoE transport/protocol layer. For the small driver-facing
helper that builds common `0x1C32` / `0x1C33` mailbox steps, see
`EtherCAT.Slave.Sync.CoE`.

# `mailbox_config`

```elixir
@type mailbox_config() :: %{
  recv_offset: non_neg_integer(),
  recv_size: pos_integer(),
  send_offset: non_neg_integer(),
  send_size: pos_integer()
}
```

# `download_sdo`

```elixir
@spec download_sdo(
  EtherCAT.Bus.server(),
  non_neg_integer(),
  mailbox_config(),
  0..7,
  non_neg_integer(),
  non_neg_integer(),
  binary()
) :: {:ok, 1..7} | {:error, term()}
```

Download an SDO value of any size.

`mailbox_counter` is the last mailbox counter used for this slave. The return
value includes the final counter after the full transfer.

# `next_mailbox_counter`

```elixir
@spec next_mailbox_counter(0..7) :: 1..7
```

# `upload_sdo`

```elixir
@spec upload_sdo(
  EtherCAT.Bus.server(),
  non_neg_integer(),
  mailbox_config(),
  0..7,
  non_neg_integer(),
  non_neg_integer()
) :: {:ok, binary(), 1..7} | {:error, term()}
```

Upload an SDO value of any size.

Returns the full payload and the final mailbox counter.

---

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