# Lint as: python2, python3
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A Python library to interact with INA219 module for TPM testing.

Background
 - INA219 is one of two modules on TTCI board
 - This library provides methods to interact with INA219 programmatically

Dependency
 - This library depends on a new C shared library called "libsmogcheck.so".
 - In order to run test cases built using this API, one needs a TTCI board

Notes:
 - An exception is raised if it doesn't make logical sense to continue program
   flow (e.g. I/O error prevents test case from executing)
 - An exception is caught and then converted to an error code if the caller
   expects to check for error code per API definition
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging, re
from autotest_lib.client.common_lib import i2c_node
import six


# INA219 registers
INA_REG = {
    'CONF': 0,        # Configuration Register
    'SHUNT_VOLT': 1,  # Shunt Voltage
    'BUS_VOLT': 2,    # Bus Voltage
    'POWER': 3,       # Power
    'CURRENT': 4,     # Current
    'CALIB': 5,       # Calibration
    }

# Regex pattern for measurement value
HEX_STR_PATTERN = re.compile('^0x([0-9a-f]{2})([0-9a-f]{2})$')

# Constants used to initialize INA219 registers
# TODO(tgao): add docstring for these values after stevenh replies
INA_CONF_INIT_VAL = 0x9f31
INA_CALIB_INIT_VAL = 0xc90e

# Default values used to calculate/interpret voltage and current measurements.
DEFAULT_MEAS_RANGE_VALUE = {
    'current': {'max': 0.1, 'min': 0.0, 'denom': 10000.0,
                'reg': INA_REG['CURRENT']},
    'voltage': {'max': 3.35, 'min': 3.25, 'denom': 2000.0,
                'reg': INA_REG['BUS_VOLT']},
    }


class InaError(Exception):
    """Base class for all errors in this module."""


class InaController(i2c_node.I2cNode):
    """Object to control INA219 module on TTCI board."""

    def __init__(self, node_addr=None, range_dict=None):
        """Constructor.

        Mandatory params:
          node_addr: node address to set. Default: None.

        Optional param:
          range_dict: desired max/min thresholds for measurement values.
                      Default: DEFAULT_MEAS_RANGE_VALUE.

        Args:
          node_addr: an integer, address of main or backup power.
          range_dict: desired max/min thresholds for measurement values.

        Raises:
          InaError: if error initializing INA219 module or invalid range_dict.
        """
        super(InaController, self).__init__()
        if node_addr is None:
            raise InaError('Error node_addr expected')

        try:
            if range_dict is None:
                range_dict = DEFAULT_MEAS_RANGE_VALUE
            else:
                self._validateRangeDict(DEFAULT_MEAS_RANGE_VALUE, range_dict)
            self.range_dict = range_dict

            self.setNodeAddress(node_addr)
            self.writeWord(INA_REG['CONF'], INA_CONF_INIT_VAL)
            self.writeWord(INA_REG['CALIB'], INA_CALIB_INIT_VAL)
        except InaError as e:
            raise InaError('Error initializing INA219: %s' % e)

    def _validateRangeDict(self, d_ref, d_in):
        """Validates keys and types of value in range_dict.

        Iterate over d_ref to make sure all keys exist in d_in and
        values are of the correct type.

        Args:
          d_ref: a dictionary, used as reference.
          d_in: a dictionary, to be validated against reference.

        Raises:
          InaError: if range_dict is invalid.
        """
        for k, v in six.iteritems(d_ref):
            if k not in d_in:
                raise InaError('Key %s not present in dict %r' % (k, d_in))
            if type(v) != type(d_in[k]):
                raise InaError(
                    'Value type mismatch for key %s. Expected: %s; actual = %s'
                    % (k, type(v), type(d_in[k])))
            if type(v) is dict:
                self._validateRangeDict(v, d_in[k])

    def readMeasure(self, measure):
        """Reads requested measurement.

        Args:
          measure: a string, 'current' or 'voltage'.

        Returns:
          a float, measurement in native units. Or None if error.

        Raises:
          InaError: if error reading requested measurement.
        """
        try:
            hex_str = '0x%.4x' % self.readWord(self.range_dict[measure]['reg'])
            logging.debug('Word read = %r', hex_str)
            return self._checkMeasureRange(hex_str, measure)
        except InaError as e:
            logging.error('Error reading %s: %s', measure, e)

    def getPowerMetrics(self):
        """Get measurement metrics for Main Power.

        Returns:
          an integer, 0 for success and -1 for error.
          a float, voltage value in Volts. Or None if error.
          a float, current value in Amps. Or None if error.
        """
        logging.info('Attempt to get power metrics')
        try:
            return (0, self.readMeasure('voltage'),
                    self.readMeasure('current'))
        except InaError as e:
            logging.error('getPowerMetrics(): %s', e)
            return (-1, None, None)

    def _checkMeasureRange(self, hex_str, measure):
        """Checks if measurement value falls within a pre-specified range.

        Args:
          hex_str: a string (hex value).
          measure: a string, 'current' or 'voltage'.

        Returns:
          measure_float: a float, measurement value.

        Raises:
          InaError: if value doesn't fall in range.
        """
        measure_float = self._convertHexToFloat(
            hex_str, self.range_dict[measure]['denom'])
        measure_msg = '%s value %.2f' % (measure, measure_float)
        range_msg = '[%(min).2f, %(max).2f]' % self.range_dict[measure]
        if (measure_float < self.range_dict[measure]['min'] or
            measure_float > self.range_dict[measure]['max']):
            raise InaError('%s is out of range %s' % measure_msg, range_msg)
        logging.info('%s is in range %s', measure_msg, range_msg)
        return measure_float

    def _convertHexToFloat(self, hex_str, denom):
        """Performs measurement calculation.

        The measurement reading from INA219 module is a 2-byte hex string.
        To convert this hex string to a float, we need to swap these two bytes
        and perform a division. An example:
          response = 0xca19
          swap bytes to get '0x19ca'
          convert to decimal value = 6602
          divide decimal by 2000.0 = 3.301 (volts)

        Args:
          hex_str: a string (raw hex value).
          denom: a float, denominator used for hex-to-float conversion.

        Returns:
          a float, measurement value.

        Raises:
          InaError: if error converting measurement to float.
        """
        match = HEX_STR_PATTERN.match(hex_str)
        if not match:
            raise InaError('Error: hex string %s does not match '
                           'expected pattern' % hex_str)

        decimal = int('0x%s%s' % (match.group(2), match.group(1)), 16)
        return decimal/denom
