# 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.
"""Allows creation of i2c interface via libftdii2c (C) library for FTDI devices.
"""
import ctypes
import logging

import ftdi_common
import ftdi_utils


class Fi2cError(Exception):
  """Class for exceptions of Fi2c.
  """
  pass


class Fi2cContext(ctypes.Structure):
  """Defines primary context structure for libftdii2c.

  Declared in ftdii2c.h and named fi2c_context.
  """
  _fields_ = [("fc", ctypes.POINTER(ftdi_common.FtdiContext)),
              ("gpio", ftdi_common.Gpio),
              ("clk", ctypes.c_uint),
              ("error", ctypes.c_int),
              ("slv", ctypes.c_ubyte),
              ("buf", ctypes.POINTER(ctypes.c_ubyte)),
              ("bufcnt", ctypes.c_int),
              ("bufsize", ctypes.c_int)]


class Fi2c(object):
  """Provide interface to libftdii2c c-library via python ctypes module.
  """

  def __init__(self, vendor=ftdi_common.DEFAULT_VID,
               product=ftdi_common.DEFAULT_PID, interface=2):
    """Fi2c constructor.

    Loads libraries for libftdi, libftdii2c.  Creates instance objects
    (Structures), Fi2cContext, FtdiContext and Gpio to iteract with the library
    and intializes them.

    Args:
      vendor: usb vendor id of FTDI device
      product: usb product id of FTDI device
      interface: interface number of FTDI device to use

    Raises:
      Fi2cError: If either ftdi or fi2c inits fail
    """
    self._logger = logging.getLogger("Fi2c")
    self._logger.debug("")

    (self._flib, self._lib) = ftdi_utils.load_libs("ftdi", "ftdii2c")
    self._fargs = ftdi_common.FtdiCommonArgs(vendor_id=vendor,
                                             product_id=product,
                                             interface=interface)
    self._fc = ftdi_common.FtdiContext()
    self._fic = Fi2cContext()
    self._is_closed = True
    if self._flib.ftdi_init(ctypes.byref(self._fc)):
      raise Fi2cError("doing ftdi_init")
    if self._lib.fi2c_init(ctypes.byref(self._fic), ctypes.byref(self._fc)):
      raise Fi2cError("doing fi2c_init")

  def __del__(self):
    """Fi2c destructor.

    Calls close to release device
    """
    if not self._is_closed:
      self.close()

  def open(self):
    """Opens access to FTDI interface as a i2c (MPSSE mode) interface.

    Raises:
      Fi2cError: If open fails
    """
    if self._lib.fi2c_open(ctypes.byref(self._fic), ctypes.byref(self._fargs)):
      raise Fi2cError("doing fi2c_open")
    self.is_closed = False

  def setclock(self, speed=100000):
    """Sets i2c clock speed.

    Args:
      speed: clock speed in hertz.  Default is 100kHz
    """
    if self._lib.fi2c_setclock(ctypes.byref(self._fic), speed):
      raise Fi2cError("doing fi2c_setclock")

  def wr_rd(self, slv, wlist, rcnt):
    """Write and/or read a slave i2c device.

    Args:
      slv: 7-bit address of the slave device
      wlist: list of bytes to write to the slave.  If list length is zero its
          just a read
      rcnt: number of bytes to read from the device.  If zero, its just a write

    Returns:
      list of c_ubyte's read from i2c device.
    """
    self._fic.slv = slv
    wcnt = len(wlist)
    wbuf_type = ctypes.c_ubyte * wcnt
    wbuf = wbuf_type()
    for i in xrange(wcnt):
      wbuf[i] = wlist[i]

    rbuf_type = ctypes.c_ubyte * rcnt
    rbuf = rbuf_type()
    for i, wval in enumerate(wbuf):
      self._logger.debug("wbuf[%i] = 0x%02x" % (i, wval))
    if self._lib.fi2c_wr_rd(ctypes.byref(self._fic), ctypes.byref(wbuf), wcnt,
                            ctypes.byref(rbuf), rcnt):
      raise Fi2cError("doing fi2c_wr_rd")
    for i, rval in enumerate(rbuf):
      self._logger.debug("rbuf[%i] = 0x%02x" % (i, rval))
    return list(rbuf)

  def close(self):
    """Close connection to FTDI device and cleanup.
    """
    if self._lib.fi2c_close(ctypes.byref(self._fic)):
      raise Fi2cError("doing fi2c_close")


def test():
  """Test code.

  (TODO) tbroch: enhance and make Googley & pythonic from a unittest perspective
  """
  (options, args) = ftdi_utils.parse_common_args(interface=2)

  loglevel=logging.INFO
  if options.debug:
    loglevel = logging.DEBUG
  logging.basicConfig(level=loglevel,
                      format="%(asctime)s - %(name)s - " +
                      "%(levelname)s - %(message)s")
  fobj = Fi2c(options.vendor, options.product, options.interface)
  fobj.open()
  fobj.setclock(100000)

  wbuf = [0]
  slv = 0x21
  rbuf = fobj.wr_rd(slv, wbuf, 1)
  logging.info("first: i2c read of slv=0x%02x reg=0x%02x == 0x%02x" %
               (slv, wbuf[0], rbuf[0]))
  errcnt = 0
  for cnt in xrange(1000):
    try:
      rbuf = fobj.wr_rd(slv, [], 1)
    except:
      errcnt += 1
      logging.error("errs = %d cnt = %d" % (errcnt, cnt))

  logging.info("last: i2c read of slv=0x%02x reg=0x%02x == 0x%02x" %
               (slv, wbuf[0], rbuf[0]))
  fobj.close()

if __name__ == "__main__":
  test()
