# 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 base class to interact with I2C node device.

Dependency
 - This library depends on a new C shared library called "libsmogcheck.so".
"""

import ctypes, logging


# I2C constants
I2C_BUS = 2

# Path of shared library.
SMOGCHECK_C_LIB = "/usr/local/lib/libsmogcheck.so.0"


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


class I2cNode(object):
    """A generic I2C node object that supports basic I2C bus input/output."""

    def __init__(self, adapter_nr=None, load_lib=None):
        """Constructor.

        Mandatory params:
          adapter_nr: adapter's number address. Default: I2C_BUS.
          fd: file descriptor to communicate with I2C bus.
          lib_obj: ctypes library object to interface with SMOGCHECK_C_LIB.
          load_lib: a string, name of C shared library object to load.
          node_addr: node address to set. Default: None.

        Args:
          lib: a string, name of C shared library object to load.
        """
        self.node_addr = None

        if adapter_nr is None:
            adapter_nr = I2C_BUS
        self.adapter_nr = adapter_nr

        if load_lib is None:
            load_lib = SMOGCHECK_C_LIB
        self.load_lib = load_lib

        # Load shared library object.
        self.lib_obj = self._loadSharedLibrary()
        self.fd = self._getDeviceFile()

    def _loadSharedLibrary(self):
        """Loads C shared library .so file.

        Returns:
          a new instance of the shared (C) library.

        Raises:
          I2cError: if error loading the shared library.
        """
        logging.info('Attempt to load shared library %s', self.load_lib)
        try:
            return ctypes.cdll.LoadLibrary(self.load_lib)
        except OSError, e:
            raise I2cError('Error loading C library %s: %s' %
                            (self.load_lib, e))
        logging.info('Successfully loaded shared library %s', self.load_lib)

    def _getDeviceFile(self):
        """Gets a file descriptor of a device file.

        Returns:
          fd: an integer, file descriptor to communicate with I2C bus.

        Raises:
          I2cError: if error getting device file.
        """
        logging.info('Attempt to get device file for adapter %s',
                     self.adapter_nr)
        fd = self.lib_obj.GetDeviceFile(self.adapter_nr)
        if fd < 0:
            raise I2cError('Error getting device file for adapter %s' %
                            self.adapter_nr)

        logging.info('Got device file for adapter %s', self.adapter_nr)
        return fd

    def setNodeAddress(self, addr):
        """Sets node address on I2C bus to be communicated with.

        TODO(tgao): add retry loop and raise error if all retries fail.
        (so that caller does not have to check self.err for status)

        We use 7-bit address space for I2C, which has 128 addresses total.
        Besides 16 reserved addresses, the total usable address space is 112.
        See - http://www.i2c-bus.org/addressing/

        Args:
          addr: a (positive) integer, 7-bit I2C node address.

        Raises:
          I2cError: if node address is invalid or can't be set.
        """
        if self.node_addr == addr:
            logging.info('Node address already set, noop: %s', addr)
            return

        if addr < 0x8 or addr > 0x77:
            raise I2cError('Error: invalid I2C node address %s', addr)

        logging.info('Attempt to set node address: %s', addr)
        if not self.fd:
            self.fd = self._getDeviceFile()

        ret = self.lib_obj.setNodeAddress(self.fd, addr)
        if ret < 0:
            raise I2cError('Error communicating to node address %s' % addr)

        self.node_addr = addr
        logging.info('node address set to: %s', addr)

    def writeByte(self, reg, byte):
        """Writes a byte to a specific register.

        TODO(tgao): add retry loop and raise error if all retries fail.

        Args:
          reg: a (positive) integer, register number.
          byte: a char (8-bit byte), value to write.

        Raises:
          I2cError: if error writing byte to I2C bus.
        """
        logging.info('Attempt to write byte %r to reg %r', byte, reg)
        if self.lib_obj.WriteByte(self.fd, reg, byte) < 0:
            raise I2cError('Error writing byte 0x%x to reg %r' % (byte, reg))

        logging.info('Successfully wrote byte 0x%x to reg %r', byte, reg)

    def readByte(self, reg):
        """Reads a byte from a specific register.

        TODO(tgao): add retry loop and raise error if all retries fail.

        Args:
          reg: a (positive) integer, register number.

        Returns:
          byte_read: a char (8-bit byte), value read from register.

        Raises:
          I2cError: if error reading byte from I2C bus.
        """
        logging.info('Attempt to read byte from register %r', reg)
        byte_read = self.lib_obj.ReadByte(self.fd, reg)
        if byte_read < 0:
            raise I2cError('Error reading byte from reg %r' % reg)

        logging.info('Successfully read byte 0x%x from reg %r',
                     byte_read, reg)
        return byte_read

    def writeWord(self, reg, word):
        """Writes a word to a specific register.

        TODO(tgao): add retry loop and raise error if all retries fail.

        Args:
          reg: a (positive) integer, register number.
          word: a 16-bit unsigned integer, value to write.

        Raises:
          I2cError: if error writing word to I2C bus.
        """
        logging.info('Attempt to write word %r to reg %r', word, reg)
        if self.lib_obj.WriteWord(self.fd, reg, ctypes.c_uint16(word)) < 0:
            raise I2cError('Error writing word 0x%x to reg %r' % (word, reg))

        logging.info('Successfully wrote word 0x%x to reg %r',
                     word, reg)

    def readWord(self, reg):
        """Reads a word from a specific register.

        TODO(tgao): add retry loop and raise error if all retries fail.

        Args:
          reg: a (positive) integer, register number.

        Returns:
          a 16-bit unsigned integer, value read from register.

        Raises:
          I2cError: if error reading word from I2C bus.
        """
        logging.info('Attempt to read word from register %r', reg)
        word_read = self.lib_obj.ReadWord(self.fd, reg)
        if word_read < 0:
            raise I2cError('Error reading word from reg %r' % reg)

        logging.info('Successfully read word 0x%x from reg %r',
                     word_read, reg)
        return word_read
