use crate::analog::VoltageReference;
use crate::settings::common::ClockOutputSetting;
use bit_field::BitField;
#[derive(Debug, Clone, Copy)]
pub struct ChipSettings {
pub cdc_serial_number_enumeration_enabled: bool,
pub clock_output: ClockOutputSetting,
pub dac_reference: VoltageReference,
pub dac_value: u8,
pub interrupt_on_negative_edge: bool,
pub interrupt_on_positive_edge: bool,
pub adc_reference: VoltageReference,
pub usb_vendor_id: u16,
pub usb_product_id: u16,
pub usb_power_attributes: u8,
pub usb_requested_number_of_ma: u16,
}
impl ChipSettings {
pub(crate) fn from_buffer(buf: &[u8; 64]) -> Self {
use bit_field::BitField;
Self {
cdc_serial_number_enumeration_enabled: buf[4].get_bit(7),
clock_output: buf[5].get_bits(0..=4).into(),
dac_reference: (buf[6].get_bit(5), buf[6].get_bits(6..=7)).into(),
dac_value: buf[6].get_bits(0..=4),
interrupt_on_negative_edge: buf[7].get_bit(6),
interrupt_on_positive_edge: buf[7].get_bit(5),
adc_reference: (buf[7].get_bit(2), buf[7].get_bits(3..=4)).into(),
usb_vendor_id: u16::from_le_bytes([buf[8], buf[9]]),
usb_product_id: u16::from_le_bytes([buf[10], buf[11]]),
usb_power_attributes: buf[12],
usb_requested_number_of_ma: buf[13] as u16 * 2,
}
}
pub(crate) fn apply_to_flash_buffer(&self, buf: &mut [u8; 64]) {
buf[2].set_bit(7, self.cdc_serial_number_enumeration_enabled);
buf[3].set_bits(0..=4, self.clock_output.into());
let (dac_vrm_vdd, dac_vrm_level) = self.dac_reference.into();
buf[4].set_bits(6..=7, dac_vrm_level);
buf[4].set_bit(5, dac_vrm_vdd);
buf[4].set_bits(0..=4, self.dac_value & 31);
buf[5].set_bit(6, self.interrupt_on_negative_edge);
buf[5].set_bit(5, self.interrupt_on_positive_edge);
let (adc_vrm_vdd, adc_vrm_level) = self.adc_reference.into();
buf[5].set_bits(3..=4, adc_vrm_level);
buf[5].set_bit(2, adc_vrm_vdd);
let vid_bytes = self.usb_vendor_id.to_le_bytes();
assert_ne!(vid_bytes[0], 0, "VID low byte is 0.");
buf[6] = vid_bytes[0];
buf[7] = vid_bytes[1];
let pid_bytes = self.usb_product_id.to_le_bytes();
assert_ne!(pid_bytes[0], 0, "PID low byte is 0.");
buf[8] = pid_bytes[0];
buf[9] = pid_bytes[1];
buf[10] = self.usb_power_attributes;
buf[11] = (self.usb_requested_number_of_ma / 2) as u8;
}
}