pamoja_can/lib.rs
1#![cfg_attr(not(test), no_std)]
2
3//! CAN bus framing for the pamoja SDK.
4//!
5//! CAN is the bus that connects the moving parts of a machine: motor controllers, servos,
6//! battery management, and the engines, gensets, and farm equipment that speak J1939 on
7//! top of it. It is how a robot or a vehicle's pieces talk to each other reliably over a
8//! short, noisy two-wire link, which is why it is the SDK's path to actuators and to the
9//! diesel-and-hydraulic world of rural machinery.
10//!
11//! This crate is the byte layer for that, with no controller and no allocation:
12//!
13//! - [`CanId`] - a standard 11-bit or extended 29-bit identifier, always masked to width.
14//! - [`Frame`] - a classic CAN 2.0 frame, a CAN-FD frame at the discrete CAN-FD lengths,
15//! or a remote frame, with [`len_to_dlc`] and [`dlc_to_len`] for the length encoding
16//! CAN-FD uses above eight bytes.
17//! - [`J1939Id`] - the priority, parameter group, and addresses J1939 packs into a 29-bit
18//! identifier, decoded from one and composed back into one.
19//!
20//! The controller hardware handles the wire itself (arbitration, bit timing, the frame
21//! CRC); this is the identifier and payload layer above it, the part an application
22//! actually reasons about. Driving a real controller arrives with the hardware-I/O layer.
23//!
24//! # Examples
25//!
26//! ```
27//! use pamoja_can::{CanId, Frame, J1939Id};
28//!
29//! // Build a classic frame for a motor controller.
30//! let frame = Frame::new(CanId::standard(0x20A), &[0x01, 0xF4]).unwrap();
31//! assert_eq!(frame.dlc(), 2);
32//!
33//! // Decode an engine-speed broadcast from a J1939 genset.
34//! let message = J1939Id::from_id(CanId::extended(0x0CF0_0400)).unwrap();
35//! assert_eq!(message.pgn(), 61_444);
36//! assert!(message.is_broadcast());
37//! ```
38
39mod error;
40mod frame;
41mod id;
42mod j1939;
43mod signals;
44
45pub use error::CanError;
46pub use frame::{dlc_to_len, len_to_dlc, Frame};
47pub use id::CanId;
48pub use j1939::{priority, J1939Id, BROADCAST_ADDRESS};
49pub use signals::{Signals, NOT_AVAILABLE};