LCOV - code coverage report
Current view: top level - zephyr/drivers/adc - current_sense_amplifier.h Coverage Total Hit
Test: new.info Lines: 21.4 % 14 3
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2023 The ChromiumOS Authors
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_
       8              : #define ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_
       9              : 
      10              : #include <zephyr/drivers/adc.h>
      11              : #include <zephyr/drivers/gpio.h>
      12              : 
      13            0 : struct current_sense_amplifier_dt_spec {
      14            0 :         struct adc_dt_spec port;
      15            0 :         struct gpio_dt_spec power_gpio;
      16            0 :         uint32_t sense_milli_ohms;
      17            0 :         uint16_t sense_gain_mult;
      18            0 :         uint16_t sense_gain_div;
      19            0 :         uint16_t noise_threshold;
      20            0 :         int16_t zero_current_voltage_mv;
      21            0 :         enum adc_gain gain_extended_range;
      22            0 :         bool enable_calibration;
      23              : };
      24              : 
      25              : /**
      26              :  * @brief Get current sensor information from devicetree.
      27              :  *
      28              :  * This returns a static initializer for a @p current_sense_amplifier_dt_spec structure
      29              :  * given a devicetree node.
      30              :  *
      31              :  * @param node_id Devicetree node identifier.
      32              :  *
      33              :  * @return Static initializer for an current_sense_amplifier_dt_spec structure.
      34              :  */
      35            1 : #define CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(node_id)                                               \
      36              :         {                                                                                          \
      37              :                 .port = ADC_DT_SPEC_GET(node_id),                                                  \
      38              :                 .power_gpio = GPIO_DT_SPEC_GET_OR(node_id, power_gpios, {0}),                      \
      39              :                 .sense_milli_ohms = DT_PROP(node_id, sense_resistor_milli_ohms),                   \
      40              :                 .sense_gain_mult = DT_PROP(node_id, sense_gain_mult),                              \
      41              :                 .sense_gain_div = DT_PROP(node_id, sense_gain_div),                                \
      42              :                 .noise_threshold = DT_PROP(node_id, zephyr_noise_threshold),                       \
      43              :                 .zero_current_voltage_mv = DT_PROP(node_id, zero_current_voltage_mv),              \
      44              :                 .gain_extended_range = DT_STRING_TOKEN_OR(node_id, gain_extended_range, 0xFF),     \
      45              :                 .enable_calibration = DT_PROP_OR(node_id, enable_calibration, false),              \
      46              :         }
      47              : 
      48              : /**
      49              :  * @brief Calculates the actual amperage from the measured voltage
      50              :  *
      51              :  * @param[in] spec current sensor specification from Devicetree.
      52              :  * @param[in,out] v_to_i Pointer to the measured voltage in millivolts on input, and the
      53              :  * corresponding scaled current value in milliamps on output.
      54              :  */
      55              : static inline void
      56            1 : current_sense_amplifier_scale_dt(const struct current_sense_amplifier_dt_spec *spec,
      57              :                                  int32_t *v_to_i)
      58              : {
      59              :         /* store in a temporary 64 bit variable to prevent overflow during calculation */
      60              :         int64_t tmp = *v_to_i;
      61              : 
      62              :         /* (INT32_MAX * 1000 * UINT16_MAX) < INT64_MAX
      63              :          * Therefore all multiplications can be done before divisions, preserving resolution.
      64              :          */
      65              :         tmp = tmp - spec->zero_current_voltage_mv;
      66              :         tmp = tmp * 1000 * spec->sense_gain_div / spec->sense_milli_ohms / spec->sense_gain_mult;
      67              : 
      68              :         *v_to_i = (int32_t)tmp;
      69              : }
      70              : 
      71              : /**
      72              :  * @brief Calculates the actual amperage from the measured voltage
      73              :  *
      74              :  * @param spec Current sensor specification from Devicetree.
      75              :  * @param microvolts Measured voltage in microvolts.
      76              :  *
      77              :  * @return int32_t Corresponding scaled output current in microamps.
      78              :  */
      79              : static inline int32_t
      80            1 : current_sense_amplifier_scale_ua_dt(const struct current_sense_amplifier_dt_spec *spec,
      81              :                                     int32_t microvolts)
      82              : {
      83              :         int64_t temp = microvolts;
      84              :         /* Perform all multiplications first to limit rounding errors.
      85              :          * Micro-volts/milli-ohms would result in milli-amps, scale by factor of 1,000.
      86              :          * Proof that the following cannot overflow:
      87              :          *    (millivolts * micro_scale) * max_gain <= INT64_MAX
      88              :          *          (INT32_MAX * 1000) * UINT16_MAX <= INT64_MAX
      89              :          *                                   ~2**57 <= 2**63
      90              :          */
      91              :         int64_t scaled = temp * 1000 * spec->sense_gain_div;
      92              :         /* Perform final divisions */
      93              :         return scaled / spec->sense_gain_mult / spec->sense_milli_ohms;
      94              : }
      95              : 
      96              : #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ */
        

Generated by: LCOV version 2.0-1