"""Physical unit conversions for the laser control module. Converts between physical quantities (°C, mA, V) and the raw ADC/DAC integer values used by the device firmware, using the hardware's bridge/divider formulas. """ import math from .constants import ADC_BITS_16, BETA_INTERNAL, R0, R1, R3, R4, R5, R6, RREF, T0_K, VREF def temp_c_to_n(temp_c: float) -> int: """ Convert temperature (°C) to 16-bit DAC integer (Wheatstone bridge setpoint). Args: temp_c: Temperature in degrees Celsius. Returns: Integer in [0, 65535] for the DAC. """ rt = R0 * math.exp(BETA_INTERNAL / (temp_c + 273) - BETA_INTERNAL / T0_K) u = VREF / (R5 * (R3 + R4)) * ( R1 * R4 * (R5 + R6) - rt * (R3 * R6 - R4 * R5) ) / (rt + R1) n = int(u * ADC_BITS_16 / VREF) n = max(0, min(ADC_BITS_16, n)) return n def current_ma_to_n(current_ma: float) -> int: """ Convert laser drive current (mA) to 16-bit DAC integer. Args: current_ma: Current in milliamps. Returns: Integer in [0, 65535] for the DAC. """ n = int(ADC_BITS_16 / 2000 * RREF * current_ma) n = max(0, min(ADC_BITS_16, n)) return n