This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/fixed/src/helpers.rs
T
swaitsandClaude Opus 4.6 3102fc747a feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:42:54 -06:00

160 lines
5.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright © 2018–2025 Trevor Spiteri
// This library is free software: you can redistribute it and/or
// modify it under the terms of either
//
// * the Apache License, Version 2.0 or
// * the MIT License
//
// at your option.
//
// You should have recieved copies of the Apache License and the MIT
// License along with the library. If not, see
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
use crate::int_helper;
use crate::types::extra::{LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128};
use crate::{
FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32, FixedU64,
FixedU128,
};
use core::cmp::Ordering;
// Unsigned can have 0 ≤ x < 2^128, that is its msb can be 0 or 1.
// Negative can have -2^127 ≤ x < 0, that is its msb must be 1.
pub enum Widest {
Unsigned(u128),
Negative(i128),
}
pub struct ToFixedHelper {
pub(crate) bits: Widest,
pub(crate) dir: Ordering,
pub(crate) overflow: bool,
}
pub struct ToFloatHelper {
pub(crate) neg: bool,
pub(crate) abs: u128,
}
pub struct FromFloatHelper {
pub(crate) kind: FloatKind,
}
pub enum FloatKind {
NaN,
Infinite { neg: bool },
Finite { neg: bool, conv: ToFixedHelper },
}
pub struct Private;
pub trait Sealed: Copy {
fn to_fixed_helper(self, _: Private, dst_frac_nbits: u32, dst_int_nbits: u32) -> ToFixedHelper;
fn to_float_helper(self, _: Private) -> ToFloatHelper;
fn saturating_from_float_helper(_: Private, src: FromFloatHelper) -> Self;
fn overflowing_from_float_helper(_: Private, src: FromFloatHelper) -> (Self, bool);
}
macro_rules! impl_sealed {
($Fixed:ident($LeEqU:ident, $Signedness:ident, $Inner:ident)) => {
impl<Frac: $LeEqU> Sealed for $Fixed<Frac> {
#[inline]
fn to_fixed_helper(
self,
_: Private,
dst_frac_nbits: u32,
dst_int_nbits: u32,
) -> ToFixedHelper {
int_helper::$Inner::to_fixed_helper(
self.to_bits(),
Self::FRAC_NBITS as i32,
dst_frac_nbits,
dst_int_nbits,
)
}
#[inline]
fn to_float_helper(self, _: Private) -> ToFloatHelper {
let (neg, abs) = int_helper::$Inner::neg_abs(self.to_bits());
let abs = abs.into();
ToFloatHelper { neg, abs }
}
#[inline]
fn saturating_from_float_helper(_: Private, src: FromFloatHelper) -> Self {
let neg = match src.kind {
FloatKind::NaN => panic!("NaN"),
FloatKind::Infinite { neg } => neg,
FloatKind::Finite { neg, .. } => neg,
};
let saturated = if neg { Self::MIN } else { Self::MAX };
let FloatKind::Finite { conv, .. } = src.kind else {
return saturated;
};
if conv.overflow {
return saturated;
}
let bits = if_signed_unsigned!(
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
let bits = bits as _;
if bits < 0 {
return Self::MAX;
}
bits
}
Widest::Negative(bits) => bits as _,
},
match conv.bits {
Widest::Unsigned(bits) => bits as _,
Widest::Negative(_) => return Self::MIN,
},
);
Self::from_bits(bits)
}
#[inline]
#[track_caller]
fn overflowing_from_float_helper(_: Private, src: FromFloatHelper) -> (Self, bool) {
let conv = match src.kind {
FloatKind::NaN => panic!("NaN"),
FloatKind::Infinite { .. } => panic!("infinite"),
FloatKind::Finite { conv, .. } => conv,
};
let mut new_overflow = false;
let bits = if_signed_unsigned!(
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
let bits = bits as _;
if bits < 0 {
new_overflow = true;
}
bits
}
Widest::Negative(bits) => bits as _,
},
match conv.bits {
Widest::Unsigned(bits) => bits as _,
Widest::Negative(bits) => {
new_overflow = true;
bits as _
}
},
);
(Self::from_bits(bits), conv.overflow || new_overflow)
}
}
};
}
impl_sealed! { FixedI8(LeEqU8, Signed, i8) }
impl_sealed! { FixedI16(LeEqU16, Signed, i16) }
impl_sealed! { FixedI32(LeEqU32, Signed, i32) }
impl_sealed! { FixedI64(LeEqU64, Signed, i64) }
impl_sealed! { FixedI128(LeEqU128, Signed, i128) }
impl_sealed! { FixedU8(LeEqU8, Unsigned, u8) }
impl_sealed! { FixedU16(LeEqU16, Unsigned, u16) }
impl_sealed! { FixedU32(LeEqU32, Unsigned, u32) }
impl_sealed! { FixedU64(LeEqU64, Unsigned, u64) }
impl_sealed! { FixedU128(LeEqU128, Unsigned, u128) }