ashv2
Implementation of Silicon Labs' Asynchronous Serial Host protocol v2 (ASHv2), host side.
Specification
Silicon Labs publishes the documentation online:
Current implementation status
The crate currently provides:
- Frame parsing/encoding for
DATA,ACK,NAK,RST,RST-ACK, andERROR. - CRC-16 validation/generation for all supported frame types.
- Byte stuffing/unstuffing and ASH payload randomization (masking/unmasking).
- Async actor futures created with
start(...), with caller-owned transmitter/receiver execution. - Transport-independent async I/O over caller-provided
tokio::io::AsyncReadandtokio::io::AsyncWriteimplementations. - Automatic initial reset handshake (
RST->RST-ACK) before normal traffic. - Automatic handling of inbound
ACK/NAKand retransmission of queuedDATAframes. - Automatic reset/recovery on protocol errors (
ERROR,RST, and selected I/O failures). - Optional EZSP adapters implementing
ezsp::Transmitandezsp::Receive.
Important behavior details:
start(reader, writer, response)accepts separate async reader and writer values. The caller is responsible for opening and configuring the transport and splitting it when necessary.- The core crate does not depend on
serialportorasync-serialport. Serial ports, sockets, in-memory streams, and other transports can be used when they implement the required Tokio I/O traits. start(...)returns transmitter and receiver futures in a namedFuturescontainer for the caller to spawn or poll.- The crate does not spawn Tokio tasks internally.
- The transmitter terminates after every
Handleclone has been dropped and the outbound message queue has been drained. There is no terminate message. - When the transmitter terminates, it signals the receiver to terminate as well.
Handle::send(payload).awaitconfirms local transmission attempt (I/O success), not the remote ASH response payload.- Payload requests made before the ASH link is established remain queued while the initial reset handshake is driven.
- When the transmit window is full, the transmitter requeues the payload request without delay.
- Incoming
DATApayloads are delivered through the response channel passed tostart(...). - Payload type is
heapless::Vec<u8, MAX_PAYLOAD_SIZE>(MAX_PAYLOAD_SIZEdefaults to128).
Compile-time tunables (via const_env):
ASHV2_MAX_PAYLOAD_SIZE(default:128)ASHV2_T_RSTACK_MAX_MILLIS(default:3200)ASHV2_TX_K(default:5)ASHV2_T_RX_ACK_MAX_MILLIS(default:3200)
Usage
use start;
use ;
use channel;
async
The reader and writer can come from any transport integration. For a bidirectional type that
implements both traits, use that transport's split operation (for example,
tokio::io::split) before calling start(...).
Every clone of Handle, including a handle used through the optional EZSP transmitter adapter,
must be dropped before termination can begin.
EZSP integration
Enable the ezsp feature to get typed EZSP adapters:
[]
= { = "11", = ["ezsp"] }
With the feature enabled:
ashv2::ezsp::Transmitteris an alias forashv2::Handle, which implementsezsp::Transmit.ashv2::ezsp::Receiverowns the inbound ASHv2 payload receiver and implementsezsp::Receive. The EZSP layer supplies the currently negotiated protocol version to each receive call.
The same payload channel connects the core ASHv2 actor to the EZSP receiver:
use ;
use start;
use channel;
let = channel;
let = start;
let ezsp_transmitter: EzspTransmitter = ash_handle;
let ezsp_receiver = new;
// Spawn or otherwise poll futures.transmitter and futures.receiver.
// Pass ezsp_transmitter and ezsp_receiver to the EZSP API.
Without the feature, the EZSP dependency and adapter module are not compiled.
Development
The CI workflow currently runs:
cargo +nightly fmt --checkcargo clippy --all-features -- -A clippy::multiple_crate_versions -D warningscargo test --all-featurescargo build --all-features --releasecargo vet check
Legal
This project is free software and is not affiliated with Silicon Labs.
Credits
Special thanks to Simon Farnsworth, Kevin Reid, and the community at https://users.rust-lang.org/.