pub const DEFAULT_RSENSE: f32 = 0.11;
pub const VREF: f32 = 0.325;
#[inline]
fn round_f32(x: f32) -> f32 {
if x >= 0.0 {
(x + 0.5) as i32 as f32
} else {
(x - 0.5) as i32 as f32
}
}
pub fn current_to_cs(rms_current_ma: u16, rsense: f32, vsense: bool) -> Option<u8> {
let rms_current = rms_current_ma as f32 / 1000.0;
let vfs = if vsense { 0.180 } else { 0.325 };
let sqrt2 = 1.41421356f32;
let cs_float = (rms_current * sqrt2 * rsense * 32.0 / vfs) - 1.0;
if cs_float < 0.0 {
Some(0)
} else if cs_float > 31.0 {
None } else {
Some(round_f32(cs_float) as u8)
}
}
pub fn cs_to_current(cs: u8, rsense: f32, vsense: bool) -> u16 {
let vfs = if vsense { 0.180 } else { 0.325 };
let sqrt2 = 1.41421356f32;
let cs = (cs.min(31) + 1) as f32;
let rms_current = cs / 32.0 * vfs / (sqrt2 * rsense);
round_f32(rms_current * 1000.0) as u16
}
pub fn optimal_vsense(rms_current_ma: u16, rsense: f32) -> bool {
let max_current_vsense1 = cs_to_current(31, rsense, true);
rms_current_ma <= max_current_vsense1
}
pub fn calculate_current_settings(rms_current_ma: u16, rsense: f32) -> Option<(u8, bool)> {
let vsense = optimal_vsense(rms_current_ma, rsense);
let cs = current_to_cs(rms_current_ma, rsense, vsense)?;
Some((cs, vsense))
}
pub fn velocity_to_vactual(steps_per_sec: f32, microsteps: u16, fclk: u32) -> i32 {
let microsteps_per_sec = steps_per_sec * microsteps as f32;
let vactual = microsteps_per_sec * 8388608.0 / fclk as f32; round_f32(vactual) as i32
}
pub fn tstep_to_velocity(tstep: u32, microsteps: u16, fclk: u32) -> Option<f32> {
if tstep == 0 {
return None;
}
let microsteps_per_sec = fclk as f32 / tstep as f32;
let steps_per_sec = microsteps_per_sec / microsteps as f32;
Some(steps_per_sec)
}
pub fn velocity_to_tpwmthrs(steps_per_sec: f32, microsteps: u16, fclk: u32) -> u32 {
if steps_per_sec <= 0.0 {
return 0xFFFFF; }
let microsteps_per_sec = steps_per_sec * microsteps as f32;
let tstep = fclk as f32 / microsteps_per_sec;
(tstep as u32).min(0xFFFFF)
}
pub const DEFAULT_FCLK: u32 = 12_000_000;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_current_to_cs() {
let cs = current_to_cs(1000, 0.11, false);
assert!(cs.is_some());
let cs = current_to_cs(5000, 0.11, false);
assert!(cs.is_none());
}
#[test]
fn test_cs_to_current() {
let current = cs_to_current(31, 0.11, false);
assert!(current > 2000); }
#[test]
fn test_velocity_conversion() {
let vactual = velocity_to_vactual(100.0, 256, 12_000_000);
assert!(vactual > 0);
let tstep = 12_000_000 / (100 * 256); let velocity = tstep_to_velocity(tstep as u32, 256, 12_000_000);
assert!(velocity.is_some());
}
}