# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)
# 
# Path: ripyl/sigproc.py
# def remove_excess_edges(edges):
#     '''Remove incorrect edge transitions from an edge stream
#     
#     This is a generator function.
#     
#     This function is most useful for conditioning the outputs of the protocol
#     synthesizers. For those protocols with multiple signals, the synthesizers
#     myst yield a new output set for *all* signals when any *one* of them changes.
#     This results in non-conforming edge streams that contain multiple consecutive
#     pairs with a non-changing value.
#     
#     edges (iterable of (float, int) tuples)
#         An edge stream to filter for extraneous non-edges
#         
#     Yields an edge stream.
#     '''
#     prev_state = None
#     last_e = None
#     for e in edges:
#         if prev_state is None:
#             prev_state = e[1]
#             yield e
#         else:
#             if e[1] != prev_state:
#                 prev_state = e[1]
#                 last_e = None
#                 yield e
#             else: # Save last edge so we can yield it at the end
#                 last_e = e
#         
#     if last_e is not None:
#         yield last_e


import itertools
import math
import ripyl.streaming as stream
        import bisect
from ripyl.decode import *
from ripyl.util.enum import Enum
from ripyl.util.bitops import *
from ripyl.sigproc import remove_excess_edges
    t += idle_end
    yield (t, diff_d) # final state


def usb_hsic_synth(packets, idle_start=0.0, idle_end=0.0):
    '''Generate synthesized USB HSIC waveforms

    This function simulates USB packet transmission on the HSIC strobe and data signals.
    
    packets (sequence of USBPacket)
        The packet objects that are to be simulated
    
    idle_start (float)
        The amount of idle time before the transmission of packets begins
    
    idle_end (float)
        The amount of idle time after the last packet

    Returns a pair of iterators (strobe, data) for the strobe and data channels. Each
      iterator is a 2-tuple (time, value) representing the time and the
      logic value (0 or 1) for each edge transition on strobe and data. The first tuple
      yielded is the initial state of the waveform. All remaining tuples are
      edges where the state changes.
    '''

    # This is a wrapper around the actual synthesis code in _usb_hsic_synth()
    # It unzips the yielded tuple and removes unwanted artifact edges
    strobe, data = itertools.izip(*_usb_hsic_synth(packets, idle_start, idle_end))

    strobe = remove_excess_edges(strobe)

# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)
# 
# Path: ripyl/sigproc.py
# def remove_excess_edges(edges):
#     '''Remove incorrect edge transitions from an edge stream
#     
#     This is a generator function.
#     
#     This function is most useful for conditioning the outputs of the protocol
#     synthesizers. For those protocols with multiple signals, the synthesizers
#     myst yield a new output set for *all* signals when any *one* of them changes.
#     This results in non-conforming edge streams that contain multiple consecutive
#     pairs with a non-changing value.
#     
#     edges (iterable of (float, int) tuples)
#         An edge stream to filter for extraneous non-edges
#         
#     Yields an edge stream.
#     '''
#     prev_state = None
#     last_e = None
#     for e in edges:
#         if prev_state is None:
#             prev_state = e[1]
#             yield e
#         else:
#             if e[1] != prev_state:
#                 prev_state = e[1]
#                 last_e = None
#                 yield e
#             else: # Save last edge so we can yield it at the end
#                 last_e = e
#         
#     if last_e is not None:
#         yield last_e


# Path: ripyl/protocol/usb.py
import itertools
import math
import ripyl.streaming as stream
        import bisect
from ripyl.decode import *
from ripyl.util.enum import Enum
from ripyl.util.bitops import *
from ripyl.sigproc import remove_excess_edges

    t += idle_end
    yield (t, diff_d) # final state


def usb_hsic_synth(packets, idle_start=0.0, idle_end=0.0):
    '''Generate synthesized USB HSIC waveforms

    This function simulates USB packet transmission on the HSIC strobe and data signals.
    
    packets (sequence of USBPacket)
        The packet objects that are to be simulated
    
    idle_start (float)
        The amount of idle time before the transmission of packets begins
    
    idle_end (float)
        The amount of idle time after the last packet

    Returns a pair of iterators (strobe, data) for the strobe and data channels. Each
      iterator is a 2-tuple (time, value) representing the time and the
      logic value (0 or 1) for each edge transition on strobe and data. The first tuple
      yielded is the initial state of the waveform. All remaining tuples are
      edges where the state changes.
    '''

    # This is a wrapper around the actual synthesis code in _usb_hsic_synth()
    # It unzips the yielded tuple and removes unwanted artifact edges
    strobe, data = itertools.izip(*_usb_hsic_synth(packets, idle_start, idle_end))

    strobe = remove_excess_edges(strobe)

    data = remove_excess_edges(data)