# Path: basil/HL/HardwareLayer.py
# class HardwareLayer(Base):
#     '''Hardware layer (HL) base class.
#     '''
#     def __init__(self, intf, conf):
#         super(HardwareLayer, self).__init__(conf)
#         # interface not required for some cases
#         if intf is not None:
#             self._intf = intf
# 
#     @property
#     def is_ready(self):
#         raise NotImplementedError("is_ready() not implemented")
# 
#     def wait_for_ready(self, timeout=None, times=None, delay=None, delay_between=None, abort=None):
#         '''Determine the ready state of the device and wait until device is ready.
# 
#         Parameters
#         ----------
#         timeout : int, float
#             The maximum amount of time to wait in seconds. Reaching the timeout will raise a RuntimeError.
#         times : int
#             Maximum number of times reading the ready state.
#         delay : int, float
#             The number of seconds to sleep before checks. Defaults to 0.
#         delay_between : int, float
#             The number of seconds to sleep between each check. Defaults to 0.
#         abort : Threading.Event
#             Breaking the loop from other threads.
# 
#         Returns
#         -------
#         True if state is ready, else False.
#         '''
#         if delay:
#             try:
#                 sleep(delay)
#             except IOError:  # negative values
#                 pass
#         if timeout is not None:
#             if timeout < 0:
#                 raise ValueError("timeout is smaller than 0")
#             else:
#                 stop = time() + timeout
#         times_checked = 0
#         while not self.is_ready:
#             now = time()
#             times_checked += 1
#             if abort and abort.is_set():
#                 False
#             if timeout is not None and stop <= now:
#                 raise RuntimeError('Time out while waiting for ready in %s, module %s' % (self.name, self.__class__.__module__))
#             if times and times > times_checked:
#                 False
#             if delay_between:
#                 try:
#                     sleep(delay_between)
#                 except IOError:  # negative values
#                     pass
#         return True
# 
# Path: basil/HL/FEI4AdapterCard.py
# class Eeprom24Lc128(HardwareLayer):
#     '''EEPROM 24LC128
# 
#     Reading and writing EEPROM (AC & QMAC).
#     '''
#     CAL_EEPROM_ADD = 0xa8
#     CAL_EEPROM_PAGE_SIZE = 32
# 
#     def __init__(self, intf, conf):
#         super(Eeprom24Lc128, self).__init__(intf, conf)
#         self._base_addr = conf['base_addr']
# 
#     def _read_eeprom(self, address, size):
#         '''Read EEPROM
#         '''
#         self._intf.write(self._base_addr + self.CAL_EEPROM_ADD, array('B', pack('>H', address & 0x3FFF)))  # 14-bit address, 16384 bytes
# 
#         n_pages, n_bytes = divmod(size, self.CAL_EEPROM_PAGE_SIZE)
#         data = array('B')
#         for _ in range(n_pages):
#             data.extend(self._intf.read(self._base_addr + self.CAL_EEPROM_ADD | 1, size=self.CAL_EEPROM_PAGE_SIZE))
# 
#         if n_bytes > 0:
#             data.extend(self._intf.read(self._base_addr + self.CAL_EEPROM_ADD | 1, size=n_bytes))
# 
#         return data
# 
#     def _write_eeprom(self, address, data):
#         raise NotImplementedError("_write_eeprom() not implemented")


import logging
import string
from struct import pack, unpack_from, calcsize
from array import array
from collections import OrderedDict
from time import sleep
from basil.HL.HardwareLayer import HardwareLayer
from basil.HL.FEI4AdapterCard import Eeprom24Lc128
            AdcMax11644._setup_adc(self, self.MAX11644_INT_REF)
            sleep(0.010)
        adc_ch0, adc_ch1 = AdcMax11644._get_adc_value(self)
        if 15 < address < 20:
            AdcMax11644._setup_adc(self, self.MAX11644_EXT_REF)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)
        return adc_ch0, adc_ch1

    def _set_power_gpio_value(self, bit, value):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)
        if value:
            self.power_gpio._set_output_port(bit)
        else:
            self.power_gpio._clear_output_port(bit)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)

    def _get_power_gpio_value(self, bit):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)
        value = self.power_gpio._get_input_port(bit)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)
        return value


class I2cEeprom(Eeprom24Lc128, MuxPca9540B):
    I2CBUS_ADC = MuxPca9540B.PCA9540B_SEL_CH1
    I2CBUS_DAC = MuxPca9540B.PCA9540B_SEL_CH0
    I2CBUS_DEFAULT = MuxPca9540B.PCA9540B_SEL_NONE

    def _read_eeprom(self, address, size):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)

# Path: basil/HL/HardwareLayer.py
# class HardwareLayer(Base):
#     '''Hardware layer (HL) base class.
#     '''
#     def __init__(self, intf, conf):
#         super(HardwareLayer, self).__init__(conf)
#         # interface not required for some cases
#         if intf is not None:
#             self._intf = intf
# 
#     @property
#     def is_ready(self):
#         raise NotImplementedError("is_ready() not implemented")
# 
#     def wait_for_ready(self, timeout=None, times=None, delay=None, delay_between=None, abort=None):
#         '''Determine the ready state of the device and wait until device is ready.
# 
#         Parameters
#         ----------
#         timeout : int, float
#             The maximum amount of time to wait in seconds. Reaching the timeout will raise a RuntimeError.
#         times : int
#             Maximum number of times reading the ready state.
#         delay : int, float
#             The number of seconds to sleep before checks. Defaults to 0.
#         delay_between : int, float
#             The number of seconds to sleep between each check. Defaults to 0.
#         abort : Threading.Event
#             Breaking the loop from other threads.
# 
#         Returns
#         -------
#         True if state is ready, else False.
#         '''
#         if delay:
#             try:
#                 sleep(delay)
#             except IOError:  # negative values
#                 pass
#         if timeout is not None:
#             if timeout < 0:
#                 raise ValueError("timeout is smaller than 0")
#             else:
#                 stop = time() + timeout
#         times_checked = 0
#         while not self.is_ready:
#             now = time()
#             times_checked += 1
#             if abort and abort.is_set():
#                 False
#             if timeout is not None and stop <= now:
#                 raise RuntimeError('Time out while waiting for ready in %s, module %s' % (self.name, self.__class__.__module__))
#             if times and times > times_checked:
#                 False
#             if delay_between:
#                 try:
#                     sleep(delay_between)
#                 except IOError:  # negative values
#                     pass
#         return True
# 
# Path: basil/HL/FEI4AdapterCard.py
# class Eeprom24Lc128(HardwareLayer):
#     '''EEPROM 24LC128
# 
#     Reading and writing EEPROM (AC & QMAC).
#     '''
#     CAL_EEPROM_ADD = 0xa8
#     CAL_EEPROM_PAGE_SIZE = 32
# 
#     def __init__(self, intf, conf):
#         super(Eeprom24Lc128, self).__init__(intf, conf)
#         self._base_addr = conf['base_addr']
# 
#     def _read_eeprom(self, address, size):
#         '''Read EEPROM
#         '''
#         self._intf.write(self._base_addr + self.CAL_EEPROM_ADD, array('B', pack('>H', address & 0x3FFF)))  # 14-bit address, 16384 bytes
# 
#         n_pages, n_bytes = divmod(size, self.CAL_EEPROM_PAGE_SIZE)
#         data = array('B')
#         for _ in range(n_pages):
#             data.extend(self._intf.read(self._base_addr + self.CAL_EEPROM_ADD | 1, size=self.CAL_EEPROM_PAGE_SIZE))
# 
#         if n_bytes > 0:
#             data.extend(self._intf.read(self._base_addr + self.CAL_EEPROM_ADD | 1, size=n_bytes))
# 
#         return data
# 
#     def _write_eeprom(self, address, data):
#         raise NotImplementedError("_write_eeprom() not implemented")


# Path: basil/HL/GPAC.py
import logging
import string
from struct import pack, unpack_from, calcsize
from array import array
from collections import OrderedDict
from time import sleep
from basil.HL.HardwareLayer import HardwareLayer
from basil.HL.FEI4AdapterCard import Eeprom24Lc128

            AdcMax11644._setup_adc(self, self.MAX11644_INT_REF)
            sleep(0.010)
        adc_ch0, adc_ch1 = AdcMax11644._get_adc_value(self)
        if 15 < address < 20:
            AdcMax11644._setup_adc(self, self.MAX11644_EXT_REF)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)
        return adc_ch0, adc_ch1

    def _set_power_gpio_value(self, bit, value):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)
        if value:
            self.power_gpio._set_output_port(bit)
        else:
            self.power_gpio._clear_output_port(bit)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)

    def _get_power_gpio_value(self, bit):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)
        value = self.power_gpio._get_input_port(bit)
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DEFAULT)
        return value


class I2cEeprom(Eeprom24Lc128, MuxPca9540B):
    I2CBUS_ADC = MuxPca9540B.PCA9540B_SEL_CH1
    I2CBUS_DAC = MuxPca9540B.PCA9540B_SEL_CH0
    I2CBUS_DEFAULT = MuxPca9540B.PCA9540B_SEL_NONE

    def _read_eeprom(self, address, size):
        MuxPca9540B._set_i2c_mux(self, self.I2CBUS_DAC)

        data = Eeprom24Lc128._read_eeprom(self, address, size)