Commit fec7156b authored by Jordan Yates's avatar Jordan Yates Committed by Henrik Brix Andersen
Browse files

adc: current_sense_amplifier: reduce valid scaling range



Reduce the valid scaling range for the gain multipliers and dividers to
provide more headroom on int64_t overflows in the calculations. Take
advantage of this headroom to perform all multiplications before
divisions.

Signed-off-by: default avatarJordan Yates <jordan@embeint.com>
parent 4361c96c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -243,6 +243,9 @@ Sensors
* The :dtcompatible:`current-sense-amplifier` sense resistor is now specified in milli-ohms
  (``sense-resistor-milli-ohms``) instead of micro-ohms in order to increase the maximum representable
  resistor from 4.2k to 4.2M.
* The :dtcompatible:`current-sense-amplifier` properties ``sense-gain-mult`` and ``sense-gain-div``
  are now limited to a maximum value of ``UINT16_MAX`` to enable smaller rounding errors in internal
  calculations.

* The ``nxp,`` prefixed properties in :dtcompatible:`nxp,kinetis-acmp` have been deprecated in favor
  of properties without the prefix. The sensor based driver for the :dtcompatible:`nxp,kinetis-acmp`
+2 −2
Original line number Diff line number Diff line
@@ -30,13 +30,13 @@ properties:
    type: int
    default: 1
    description: |
      Amplifier gain multiplier. The default is <1>.
      Amplifier gain multiplier. The default is <1>. The maximum value is <65535>.

  sense-gain-div:
    type: int
    default: 1
    description: |
      Amplifier gain divider. The default is <1>.
      Amplifier gain divider. The default is <1>. The maximum value is <65535>.

  power-gpios:
    type: phandle-array
+6 −4
Original line number Diff line number Diff line
@@ -13,8 +13,8 @@
struct current_sense_amplifier_dt_spec {
	const struct adc_dt_spec port;
	uint32_t sense_milli_ohms;
	uint32_t sense_gain_mult;
	uint32_t sense_gain_div;
	uint16_t sense_gain_mult;
	uint16_t sense_gain_div;
	struct gpio_dt_spec power_gpio;
};

@@ -51,8 +51,10 @@ current_sense_amplifier_scale_dt(const struct current_sense_amplifier_dt_spec *s
	/* store in a temporary 64 bit variable to prevent overflow during calculation */
	int64_t tmp = *v_to_i;

	/* multiplies by 1,000 before dividing by sense resistance in milli-ohms. */
	tmp = tmp * 1000 / spec->sense_milli_ohms * spec->sense_gain_div / spec->sense_gain_mult;
	/* (INT32_MAX * 1000 * UINT16_MAX) < INT64_MAX
	 * Therefore all multiplications can be done before divisions, preserving resolution.
	 */
	tmp = tmp * 1000 * spec->sense_gain_div / spec->sense_milli_ohms / spec->sense_gain_mult;

	*v_to_i = (int32_t)tmp;
}