Open source
Open source
Every public crate, from register to GUI: what it does, a code sample and where to read more.
All of them are Rust and open source. The first four are the core: the API, its wire format, units and the firmware template. canzone is work in progress. The last ones are the tools around the boards: a test bench scheduler and the GUI building blocks. draft
- ProductsDonguru · rePort · CAN line · IOWeaver · RockFace
-
API
API description language and code generator: RPC, streams and properties, backwards and forwards compatible, no_std and no alloc.
#[ww_trait] #[claim(exclusive)] pub trait Uart { #[counted] stream!(rx: RxChunk<'i>); #[credit] sink!(tx: MaxLen<RefVec<'i, u8>, UART_TX_MAX>); fn capabilities() -> Capabilities<'i>; } -
Wire format
Compact zero-copy wire format for microcontrollers. No allocator, dynamic types, packed down to the bit.
#[derive_shrink_wrap(ww_repr = u1)] enum I2cAddress { Seven(U7), Ten(U10) } // 1 + 7 or 1 + 10 bits #[derive_shrink_wrap] struct I2cWrite<'i> { addr: I2cAddress, // 0x50: 0 1010000 stop: bool, // 1 bit fast: bool, // 1 bit retries: Nibble, // 3: 0011, on a nibble timeout_ms: Option<U10>, // Some(500): 1 0111110100 data: RefVec<'i, u8>, // ab cd, the count at the back } // 50 83 be 80 ab cd 02: 7 bytes. As a repr(C) struct: 20. -
Units
exact_units
not on crates.io yetUnits of measure checked at compile time, with exact scales. The same bytes as the plain integer, no_std and no alloc.
// exact or refused, never rounded through a float let t: Micros<u32> = Fixed::new(1500); assert_eq!(t.to::<Milli, u16>(), None); // not whole ms // V/V and W/W are different kinds: the kind picks the dB type VGain = Fixed<Per<Volt, Volt>, One, f64>; type PGain = Fixed<Per<Watt, Watt>, One, f64>; VGain::new(2.0).to_db(); // 6.0206: 20·lg 2 PGain::new(2.0).to_db(); // 3.0103: 10·lg 2 // a threshold in dB, an integer at compile time let v: Fixed<Per<Volt, Volt>, Milli, u16> = db!(-6); // 501 let p: Fixed<Per<Watt, Watt>, Milli, u16> = db!(-6); // 251 // a duty cycle has no level: 0.5 duty is not -3 dB // Fixed::<Ratio, One, f64>::new(0.5).to_db(); // error[E0080]: decibels are for W/W or V/V, A/A, Pa/Pa: // a plain Ratio has no level form -
Firmware
embedded_bedrock
not on crates.io yetBare-metal firmware template with ruggedizing, debugging and logging built in. Optional embassy, RTIC and HAL support.
use bedrock_led::code::*; use bedrock_sync::{Config, Sync}; use cortex_m::asm::delay; // A firmware that will not start // says why on its status LED, then // waits in the ROM bootloader. if !guard.runs_board() { let pause = |n| delay(n * KHZ); blink(Code::UnknownRework, led, pause); reboot_into_rom_bootloader(); } // One clock on all boards, steered // by the host over WireWeaver: // Acquiring, Locked within 2 ms. // `ww sync` locks the boards in // 1.2-1.6 s. On Donguru it costs // about 1.5 KB of flash. static SYNC: Sync = Sync::new(Config::DEFAULT); // clock.steer, once a second let r = SYNC.with(|clock, now| { server.steer(clock, now, &p) }); // all boards act at the same µs SYNC.wait_until_shared(t).await?; -
Firmware
canzone work in progress
renamed from mcan, not on crates.io yetStand-alone Rust driver for the Bosch M_CAN controller, aimed at STM32 G0, G4, H5, H7 and L5. Goals: no panics, no blocking waits without a timeout, optional async.
let mut can = unwrap!(can.into_config_mode()); can.set_nominal_bit_timing(unwrap!(NominalBitTiming::new(1, 55, 8, 1))); unwrap!(can.set_layout(layout_fdcan1)); can.set_automatic_bus_off_recovery(true); let mut can = unwrap!(can.into_normal()); can.write_tx_buffer_pend( tx_buffers.idx1, TxFrameHeader::fd_brs(Id::Standard(unwrap!(StandardId::new(0x123)))), &[0xAA, 0xBB, 0xCC], ); -
Test bench
choreograph
not on crates.io yetPlans and runs jobs over shared instruments and resources, with priorities and deadlines. Says why each waiting job waits.
[[resource]] name = "supply" kind = "supply" states = ["off", "3V0", "3V3", "3V6"] safe = "off" [[job]] name = "a-3V3" needs = [{ kind = "probe", state = "fw-a" }, { kind = "supply", state = "3V3" }] run = "10s" -
GUI
Fast table viewer and editor that only draws the visible rows. Data from vectors, files, databases or live bus traces.
let mut table = VariantTable::new([ColumnDef::new("Name", VariantTy::Str)]); let mut view = TableView::new(TableViewOptions::default()); let mut config = TableViewConfig::default(); // Every frame: let output = view.show(ui, &mut table, &mut VariantCellUi, &mut config); -
GUI
vhrd_egui
not on crates.io yetegui building blocks: the widget frame every panel sits in, a dock that moves widgets between windows, an HDR phosphor scope.
let hints = SizeHints::new([90.0, 30.0], [200.0, 80.0], [360.0, 80.0]).tall(200.0); WidgetFrame::new("log") .sizes(hints) .show_area(ui, &mut state, |ui, area| { let rows = match area.height { Height::Min => 1, Height::Nom => 5, Height::Tall => 15, }; });