use core::fmt;
use arrayvec::ArrayVec;
use crate::register::{AccessPattern, Subpage};
use crate::util::Sealed;
pub trait FromI2C<I2C> {
type Error;
type Ok;
fn from_i2c(bus: &mut I2C, i2c_address: u8) -> Result<Self::Ok, Self::Error>;
}
#[doc = include_str!("katex.html")]
pub trait CalibrationData<'a> {
type Camera: MelexisCamera;
fn k_v_dd(&self) -> i16;
fn v_dd_25(&self) -> i16;
fn resolution(&self) -> u8;
fn v_dd_0(&self) -> f32 {
3.3f32
}
fn k_v_ptat(&self) -> f32;
fn k_t_ptat(&self) -> f32;
fn v_ptat_25(&self) -> f32;
fn alpha_ptat(&self) -> f32;
fn gain(&self) -> f32;
fn k_s_ta(&self) -> f32;
fn corner_temperatures(&self) -> &[i16];
fn k_s_to(&self) -> &[f32];
fn alpha_correction(&self) -> &[f32];
fn emissivity(&self) -> Option<f32> {
None
}
type OffsetReferenceIterator: Iterator<Item = &'a i16>;
fn offset_reference_pixels(&'a self, subpage: Subpage) -> Self::OffsetReferenceIterator;
fn offset_reference_cp(&self, subpage: Subpage) -> i16;
type AlphaIterator: Iterator<Item = &'a f32>;
fn alpha_pixels(&'a self, subpage: Subpage) -> Self::AlphaIterator;
fn alpha_cp(&self, subpage: Subpage) -> f32;
type KvIterator: Iterator<Item = &'a f32>;
fn k_v_pixels(&'a self, subpage: Subpage) -> Self::KvIterator;
fn k_v_cp(&self, subpage: Subpage) -> f32;
type KtaIterator: Iterator<Item = &'a f32>;
fn k_ta_pixels(&'a self, subpage: Subpage) -> Self::KtaIterator;
fn k_ta_cp(&self, subpage: Subpage) -> f32;
fn temperature_gradient_coefficient(&self) -> Option<f32>;
type AccessPatternCompensation: Iterator<Item = Option<&'a f32>>;
fn access_pattern_compensation_pixels(
&'a self,
access_pattern: AccessPattern,
) -> Self::AccessPatternCompensation;
fn access_pattern_compensation_cp(
&self,
subpage: Subpage,
access_pattern: AccessPattern,
) -> Option<f32>;
}
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
pub struct Address(u16);
impl Address {
pub const fn new(address: u16) -> Self {
Self(address)
}
pub(crate) fn as_bytes(&self) -> [u8; 2] {
self.0.to_be_bytes()
}
}
impl fmt::Debug for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Address({:#X})", self.0)
}
}
impl From<u16> for Address {
fn from(raw_address: u16) -> Self {
Self::new(raw_address)
}
}
impl From<Address> for u16 {
fn from(address: Address) -> Self {
address.0
}
}
impl From<Address> for usize {
fn from(address: Address) -> Self {
address.0 as usize
}
}
#[doc = include_str!("katex.html")]
pub trait MelexisCamera: Sealed {
type PixelRangeIterator: IntoIterator<Item = PixelAddressRange>;
type PixelsInSubpageIterator: IntoIterator<Item = bool>;
fn pixel_ranges(subpage: Subpage, access_pattern: AccessPattern) -> Self::PixelRangeIterator;
fn pixels_in_subpage(
subpage: Subpage,
access_pattern: AccessPattern,
) -> Self::PixelsInSubpageIterator;
const T_A_V_BE: Address;
const T_A_PTAT: Address;
fn compensation_pixel(subpage: Subpage) -> Address;
const GAIN: Address;
const V_DD_PIXEL: Address;
fn resolution_correction(calibrated_resolution: u8, current_resolution: u8) -> f32;
const BASIC_TEMPERATURE_RANGE: usize;
const SELF_HEATING: f32;
const HEIGHT: usize;
const WIDTH: usize;
const NUM_PIXELS: usize;
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PixelAddressRange {
pub(crate) start_address: Address,
pub(crate) buffer_offset: usize,
pub(crate) length: usize,
}
pub(crate) fn alpha_correction_coefficients<const NUM_RANGES: usize>(
basic_range: usize,
corner_temperatures: &[i16],
k_s_to: &[f32],
) -> [f32; NUM_RANGES] {
let results: ArrayVec<f32, NUM_RANGES> = (0..NUM_RANGES)
.map(|n| alpha_corr_n(n, basic_range, corner_temperatures, k_s_to))
.collect();
results
.into_inner()
.expect("The Rust-range 0..NUM_RANGES should fill an array of NUM_RANGES elements")
}
fn alpha_corr_n(n: usize, basic_range: usize, ct: &[i16], k_s_to: &[f32]) -> f32 {
match n.cmp(&basic_range) {
core::cmp::Ordering::Equal => 1f32,
core::cmp::Ordering::Less => {
(1f32 + k_s_to[n] * f32::from(ct[n + 1] - ct[n])).recip()
* alpha_corr_n(n + 1, basic_range, ct, k_s_to)
}
core::cmp::Ordering::Greater => {
(1f32 + k_s_to[n - 1] * f32::from(ct[n] - ct[n - 1]))
* alpha_corr_n(n - 1, basic_range, ct, k_s_to)
}
}
}