use crate::config::{Config, LineFreq};
use crate::error::InitStage;
use crate::registers::*;
const READ_FLAG: u8 = 0x80;
pub fn build_read_frame(addr: u16) -> [u8; 4] {
let addr_h = READ_FLAG | ((addr >> 8) as u8 & 0x03);
let addr_l = (addr & 0xFF) as u8;
[addr_h, addr_l, 0x00, 0x00]
}
pub fn build_write_frame(addr: u16, value: u16) -> [u8; 4] {
let addr_h = (addr >> 8) as u8 & 0x03;
let addr_l = (addr & 0xFF) as u8;
[addr_h, addr_l, (value >> 8) as u8, value as u8]
}
pub fn parse_read_response(rx: &[u8; 4]) -> u16 {
((rx[2] as u16) << 8) | rx[3] as u16
}
pub fn combine_power_words(high: u16, low: u16) -> i32 {
((high as i32) << 16) | (low as i32)
}
pub const POWER_SCALE: f32 = 0.00032;
pub fn voltage_raw_to_volts(raw: u16) -> f32 {
raw as f32 / 100.0
}
pub fn current_raw_to_amps(raw: u16) -> f32 {
raw as f32 / 1000.0
}
pub fn power_raw_to_watts(high: u16, low: u16) -> f32 {
combine_power_words(high, low) as f32 * POWER_SCALE
}
pub fn power_combined_to_watts(raw: i32) -> f32 {
raw as f32 * POWER_SCALE
}
pub fn power_factor_raw_to_unitless(raw: u16) -> f32 {
(raw as i16) as f32 / 1000.0
}
pub fn frequency_raw_to_hz(raw: u16) -> f32 {
raw as f32 / 100.0
}
pub fn phase_angle_raw_to_degrees(raw: u16) -> f32 {
raw as f32 / 10.0
}
pub fn temperature_raw_to_celsius(raw: u16) -> f32 {
(raw as i16) as f32
}
#[derive(Debug, Clone, Copy)]
pub struct InitStep {
pub addr: u16,
pub value: u16,
pub stage: InitStage,
}
pub const INIT_STEP_COUNT: usize = 22;
#[rustfmt::skip]
pub fn build_init_sequence(cfg: &Config) -> [InitStep; INIT_STEP_COUNT] {
let (freq_hi, freq_lo) = match cfg.line_freq_hz {
LineFreq::Hz60 => (6300u16, 5700u16), LineFreq::Hz50 => (5300u16, 4700u16), };
let mmode0 = match cfg.line_freq_hz {
LineFreq::Hz60 => cfg.mmode0_base | (1 << 12),
LineFreq::Hz50 => cfg.mmode0_base,
};
[
InitStep { addr: REG_CFGREGACCEN, value: 0x55AA, stage: InitStage::UnlockConfig },
InitStep { addr: REG_METEREN, value: 0x0001, stage: InitStage::EnableMeter },
InitStep { addr: REG_SAGPEAKDETCFG, value: cfg.sag_peak_det_cfg, stage: InitStage::WriteSagPeak },
InitStep { addr: REG_PLCONSTH, value: cfg.pl_constant_high, stage: InitStage::WritePlConst },
InitStep { addr: REG_PLCONSTL, value: cfg.pl_constant_low, stage: InitStage::WritePlConst },
InitStep { addr: REG_ZXCONFIG, value: cfg.zx_config, stage: InitStage::WriteZxConfig },
InitStep { addr: REG_MMODE0, value: mmode0, stage: InitStage::WriteMMode0 },
InitStep { addr: REG_MMODE1, value: cfg.pga_gain.mmode1(), stage: InitStage::WriteMMode1 },
InitStep { addr: REG_FREQHITH, value: freq_hi, stage: InitStage::WriteFreqThresholds },
InitStep { addr: REG_FREQLOTH, value: freq_lo, stage: InitStage::WriteFreqThresholds },
InitStep { addr: REG_PSTARTTH, value: cfg.pstart_threshold, stage: InitStage::WriteStartupThresholds },
InitStep { addr: REG_QSTARTTH, value: cfg.qstart_threshold, stage: InitStage::WriteStartupThresholds },
InitStep { addr: REG_SSTARTTH, value: cfg.sstart_threshold, stage: InitStage::WriteStartupThresholds },
InitStep { addr: REG_PPHASETH, value: cfg.pphase_threshold, stage: InitStage::WriteStartupThresholds },
InitStep { addr: REG_QPHASETH, value: cfg.qphase_threshold, stage: InitStage::WriteStartupThresholds },
InitStep { addr: REG_UGAIN_A, value: cfg.voltage_gain[0], stage: InitStage::WriteVoltageGains },
InitStep { addr: REG_UGAIN_B, value: cfg.voltage_gain[1], stage: InitStage::WriteVoltageGains },
InitStep { addr: REG_UGAIN_C, value: cfg.voltage_gain[2], stage: InitStage::WriteVoltageGains },
InitStep { addr: REG_IGAIN_A, value: cfg.current_gain[0], stage: InitStage::WriteCurrentGains },
InitStep { addr: REG_IGAIN_B, value: cfg.current_gain[1], stage: InitStage::WriteCurrentGains },
InitStep { addr: REG_IGAIN_C, value: cfg.current_gain[2], stage: InitStage::WriteCurrentGains },
InitStep { addr: REG_CFGREGACCEN, value: 0x0000, stage: InitStage::LockConfig },
]
}