x328_proto/
lib.rs

1#![cfg_attr(not(any(feature = "std", test)), no_std)]
2
3//! Sans-IO implementation of the ANSI X3.28 serial line protocol
4//!
5//! X3.28 is an old field bus protocol, commonly used on top of a RS-422 bus.
6//! The bus settings should be 9600 baud, 7 bit char, no flow control, even parity, 1 stop bit (7E1).
7//! Since this crate doesn't provide IO at all, feel free to use whatever transport you want.
8#![deny(missing_docs)]
9
10pub mod master;
11pub mod node;
12
13pub use master::Master;
14pub use node::NodeState;
15pub use types::{
16    addr, param, value, Address, Error as TypeError, IntoAddress, IntoParameter, IntoValue,
17    Parameter, Value,
18};
19
20mod buffer;
21mod nom_parser;
22pub mod scanner;
23pub mod types;
24
25mod ascii {
26    /// Acknowledge
27    pub const ACK: u8 = 6;
28    /// Backspace
29    pub const BS: u8 = 8;
30    /// Enquiry, terminates a parameter read
31    pub const ENQ: u8 = 5;
32    /// "End of transmission", sent as first byte of each command.
33    /// A node will reply with EOT if the parameter number in a request is invalid.
34    pub const EOT: u8 = 4;
35    /// End of text, sent after parameter value
36    pub const ETX: u8 = 3;
37    /// Negative ACK
38    pub const NAK: u8 = 21;
39    /// Start of text, separates address and parameter in a write command
40    pub const STX: u8 = 2;
41}
42
43/// Calculates the BCC checksum according to the X3.28 spec.
44pub(crate) fn bcc(data: &[u8]) -> u8 {
45    let mut checksum: u8 = 0;
46    for byte in data {
47        checksum ^= *byte;
48    }
49    if checksum < 0x20 {
50        checksum += 0x20;
51    }
52    checksum
53}