Ejemplo n.º 1
0
def prepare_master(device, acq_time, nb_points):
    ct_11_config = CtConfig(clock_source=CtClockSrc.CLK_100_MHz,
                            gate_source=CtGateSrc.CT_12_GATE_ENVELOP,
                            hard_start_source=CtHardStartSrc.CT_12_START,
                            hard_stop_source=CtHardStopSrc.CT_11_EQ_CMP_11,
                            reset_from_hard_soft_stop=True,
                            stop_from_hard_stop=False)
    device.set_counter_config(11, ct_11_config)

    ct_12_config = CtConfig(clock_source=CtClockSrc.INC_CT_11_STOP,
                            gate_source=CtGateSrc.GATE_CMPT,
                            hard_start_source=CtHardStartSrc.SOFTWARE,
                            hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,
                            reset_from_hard_soft_stop=True,
                            stop_from_hard_stop=True)
    device.set_counter_config(12, ct_12_config)

    device.set_counter_comparator_value(11, int(acq_time * 1E8))
    device.set_counter_comparator_value(12, nb_points)

    # dma transfer and error will trigger DMA
    # also counter 12 stop should trigger an interrupt (this way we know that the
    # acquisition has finished without having to query the counter 12 status)
    device.set_interrupts(counters=(12, ), dma=True, error=True)

    # make master enabled by software
    device.set_counters_software_enable([11, 12])
Ejemplo n.º 2
0
def prepare(card, counter, value):

    # internal clock 100 Mhz
    card.set_clock(Clock.CLK_100_MHz)

    hard_stop = getattr(CtHardStopSrc, "CT_{0}_EQ_CMP_{0}".format(counter))
    ct_config = CtConfig(clock_source=CtClockSrc.CLK_1_MHz,
                         gate_source=CtGateSrc.GATE_CMPT,
                         hard_start_source=CtHardStartSrc.SOFTWARE,
                         hard_stop_source=hard_stop,
                         reset_from_hard_soft_stop=True,
                         stop_from_hard_stop=False)

    card.set_counter_config(counter, ct_config)

    card.set_counter_comparator_value(counter, value)

    # Latch N on Counter N HardStop
    card.set_counters_latch_sources({counter: counter})

    card.set_counter_comparator_value(counter, value)

    card.set_DMA_enable_trigger_latch({1: True}, {1: True})

    card.set_interrupts(counters={counter: True},
                        dma=True,
                        fifo_half_full=True,
                        error=True)

    card.set_counters_software_enable({1: True})

    card._fifo = card.fifo

    card._interrupt_delay_stats = []
Ejemplo n.º 3
0
def prepare_slaves(device, acq_time, nb_points, channels, accumulate=False):
    channel_nbs = list(channels.values())

    if accumulate:
        hard_stop = CtHardStopSrc.SOFTWARE
    else:
        hard_stop = CtHardStopSrc.CT_11_EQ_CMP_11

    for ch_name, ch_nb in channels.iteritems():
        ct_config = device.get_counter_config(ch_nb)
        ct_config = CtConfig(clock_source=ct_config.clock_source,
                             gate_source=CtGateSrc.CT_12_GATE_ENVELOP,
                             hard_start_source=CtHardStartSrc.CT_12_START,
                             hard_stop_source=CtHardStopSrc.CT_11_EQ_CMP_11,
                             reset_from_hard_soft_stop=True,
                             stop_from_hard_stop=False)
        device.set_counter_config(ch_nb, ct_config)

    # counter 11 will latch all active counters/channels
    latch_sources = dict([(ct, 11) for ct in channel_nbs + [11, 12]])
    device.set_counters_latch_sources(latch_sources)

    # one of the active counter-to-latch signal will trigger DMA; at each DMA
    # trigger, all active counters (+ counter 12) are stored to FIFO
    # (counter 11 cannot be the one to trigger because it is not being latched)
    device.set_DMA_enable_trigger_latch((11, ), channel_nbs + [11, 12])

    device.set_counters_software_enable(channel_nbs)
Ejemplo n.º 4
0
def configure(device, channels):
    device.request_exclusive_access()
    device.disable_interrupts()
    device.reset()
    device.software_reset()
    device.reset_FIFO_error_flags()
    device.enable_interrupts(100)

    # -------------------------------------------------------------------------
    # Channel configuration (could be loaded from beacon, for example. We
    # choose to hard code it here)
    # -------------------------------------------------------------------------

    # for counters we only care about clock source, gate source here. The rest
    # will be up to the actual acquisition to setup according to the type of
    # acquisition
    for _, ch_nb in channels.items():
        ct_config = CtConfig(
            clock_source=CtClockSrc(ch_nb % 5),
            # anything will do for the remaining fields. It
            # will be properly setup in the acquisition slave
            # setup
            gate_source=CtGateSrc.CT_11_GATE_ENVELOP,
            hard_start_source=CtHardStartSrc.SOFTWARE,
            hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,
            reset_from_hard_soft_stop=True,
            stop_from_hard_stop=True)
        device.set_counter_config(ch_nb, ct_config)

    # TODO: Set input and output channel configuration (TTL/NIM level, 50ohm,
    # edge interrupt, etc)

    # internal clock 100 Mhz
    device.set_clock(Clock.CLK_100_MHz)
Ejemplo n.º 5
0
def prepare_master(device, acq_time, nb_points):
    ct_11_config = CtConfig(clock_source=CtClockSrc.CLK_100_MHz,
                            gate_source=CtGateSrc.CT_12_GATE_ENVELOP,
                            hard_start_source=CtHardStartSrc.SOFTWARE,
                            hard_stop_source=CtHardStopSrc.CT_11_EQ_CMP_11,
                            reset_from_hard_soft_stop=True,
                            stop_from_hard_stop=False)
    ct_12_config = CtConfig(clock_source=CtClockSrc.INC_CT_11_STOP,
                            gate_source=CtGateSrc.GATE_CMPT,
                            hard_start_source=CtHardStartSrc.SOFTWARE,
                            hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,
                            reset_from_hard_soft_stop=True,
                            stop_from_hard_stop=True)

    device.set_counters_config({11: ct_11_config, 12: ct_12_config})
    device.set_counter_comparator_value(11, int(acq_time * 1E8))
    device.set_counter_comparator_value(12, nb_points)
Ejemplo n.º 6
0
def main():
    #logging.basicConfig(level=logging.DEBUG)

    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('--counter',
                        type=int,
                        help='counter number',
                        default=1)
    parser.add_argument('--value',
                        type=int,
                        default=10000 * 1000,
                        help='count until value')

    args = parser.parse_args()
    counter = args.counter
    value = args.value

    def out(msg):
        sys.stdout.write(msg)
        sys.stdout.flush()

    p201 = P201Card()
    p201.request_exclusive_access()
    p201.reset()
    p201.software_reset()

    # internal clock 100 Mhz
    p201.set_clock(Clock.CLK_100_MHz)

    # channel 10 output: counter 10 gate envelop
    p201.set_output_channels_level({counter: Level.TTL})

    # no 50 ohm adapter
    p201.set_input_channels_50ohm_adapter({})

    # channel 9 and 10: no filter, no polarity
    p201.set_output_channels_filter({})

    # channel N output: counter N gate envelop
    ct_N_gate = getattr(OutputSrc, "CT_%d_GATE" % counter)
    p201.set_output_channels_source({counter: ct_N_gate})

    # Internal clock to 1 Mhz [1us], Gate=1, Soft Start, HardStop on CMP,
    # Reset on Hard/SoftStop, Stop on HardStop
    hard_stop = getattr(CtHardStopSrc, "CT_{0}_EQ_CMP_{0}".format(counter))
    ct_config = CtConfig(clock_source=CtClockSrc.CLK_1_MHz,
                         gate_source=CtGateSrc.GATE_CMPT,
                         hard_start_source=CtHardStartSrc.SOFTWARE,
                         hard_stop_source=hard_stop,
                         reset_from_hard_soft_stop=True,
                         stop_from_hard_stop=True)
    p201.set_counter_config(counter, ct_config)

    # Latch N on Counter N HardStop
    p201.set_counters_latch_sources({counter: counter})

    # Counter N will count V/1000*1000 sec
    p201.set_counter_comparator_value(counter, value)

    started, start_count = False, 0
    while not started:
        # SoftStart on Counter N
        start_count += 1
        if start_count > 10:
            print("failed to start after 10 atempts")
            break
        p201.set_counters_software_start_stop({counter: True})
        status = p201.get_counters_status()
        started = status[counter].run

    if start_count > 1:
        logging.warning("took %d times to start", start_count)

    if started:
        print("Started!")
        import time
        while True:
            try:
                time.sleep(0.1)
                counter_value = p201.get_counter_value(counter)
                latch_value = p201.get_latch_value(counter)
                status = p201.get_counters_status()
                if not status[counter].run:
                    break
                msg = "\r%07d %07d" % (counter_value, latch_value)
                out(msg)
            except KeyboardInterrupt:
                p201.trigger_counters_software_latch((counter, ))
        print("\n%07d %07d" % (counter_value, latch_value))

    p201.disable_counters_software((counter, ))

    pprint.pprint(p201.get_counters_status())
    p201.relinquish_exclusive_access()

    return p201
Ejemplo n.º 7
0
def go(card):

    n_so = 4000 # scan origin count
    n_e = 44000 # end count
    i = 20      # displacement interval count
    d = 2000    # displacement interval size

    # counters:
    c_so = 1
    c_i = 11
    c_d = 12
    c_t_1 = 2
    c_t_2 = 3

    counter_interrupts = {}
    latch_sources = {}

    card.request_exclusive_access()
    card.reset()
    card.software_reset()

    # internal clock 40 Mhz
    card.set_clock(Clock.CLK_40_MHz)

    # Make sure the counters are disabled (soft_enable_disable).
    card.set_counters_software_enable({})

    # Configure counter 1 aka c_so:
    # (1) clock source is s_en
    # (2) gate wide open
    # (3) started by s_si
    # (4) halted by ccl 1/egal ...
    # (5) ... while keeping its value ...
    config = CtConfig(clock_source=CtClockSrc.CH_1_RISING_EDGE,          # (1)
                      gate_source=CtGateSrc.GATE_CMPT,                   # (2)
                      hard_start_source=CtHardStartSrc.CH_2_RISING_EDGE, # (3)
                      hard_stop_source=CtHardStopSrc.CT_1_EQ_CMP_1,      # (4)
                      reset_from_hard_soft_stop=False,                   # (5)
                      stop_from_hard_stop=True)                          # (4)
    card.set_counter_config(c_so, config)

    card.set_counter_comparator_value(c_so, n_so)

    # ... and signaling its end to the outside world.
    counter_interrupts[c_so] = True
    
    # Configure counter 11 aka c_i:
    # (1) clock source is ccl 12/end aka c_d/end
    # (2) gate wide open
    # (3) started by ccl 1/end aka c_so/end
    # (4) halted by ccl 11/egal ...
    # (5) ... while keeping its value ...    
    config = CtConfig(clock_source=CtClockSrc.INC_CT_12_STOP,            # (1)
                      gate_source=CtGateSrc.GATE_CMPT,                   # (2)
                      hard_start_source=CtHardStartSrc.CT_1_STOP,        # (3)
                      hard_stop_source=CtHardStopSrc.CT_11_EQ_CMP_11,    # (4)
                      reset_from_hard_soft_stop=False,                   # (5)
                      stop_from_hard_stop=True)                          # (4)
    card.set_counter_config(c_i, config)

    card.set_counter_comparator_value(c_i, i)
    
    # ... and signaling its end to the outside world.
    counter_interrupts[c_i] = True
    
    # Configure counter 12 aka c_d:
    # (1) clock source is s_en
    # (2) gate wide open
    # (3) started by ccl 1/end aka c_so/end
    # (4) reset by ccl 12/egal ...
    # (5) ... while running continuously ...
    config = CtConfig(clock_source=CtClockSrc.CH_1_RISING_EDGE,          # (1)
                      gate_source=CtGateSrc.GATE_CMPT,                   # (2)
                      hard_start_source=CtHardStartSrc.CT_1_STOP,        # (3)
                      hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,    # (4)
                      reset_from_hard_soft_stop=True,                    # (5)
                      stop_from_hard_stop=False)                         # (4)
    card.set_counter_config(c_d, config)

    card.set_counter_comparator_value(c_d, d)

    # ... and having us tell when it wraps.
    counter_interrupts[c_d] = True
  
    # Configure counter 2 aka c_t_1:
    # (1) clock source is s_t_1
    # (2) gate wide open
    # (3) started by ccl 1/end aka c_so/end
    # (4) reset by ccl 12/egal aka c_d/egal
    # (5) ... while running continuously
    config = CtConfig(clock_source=CtClockSrc.CLK_10_KHz,                # (1)
                      gate_source=CtGateSrc.GATE_CMPT,                   # (2)
                      hard_start_source=CtHardStartSrc.CT_1_STOP,        # (3)
                      hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,    # (4)
                      reset_from_hard_soft_stop=True,                    # (5)
                      stop_from_hard_stop=False)                         # (4)
    card.set_counter_config(c_t_1, config)

    # The latch signal shall be generated from ccl 12/stop + disable
    # aka c_d/stop + disable, so that we're latching all from the same
    # source and before actually clearing the counter.
    latch_sources[c_t_1] = [c_d]

    # Configure counter 3 aka c_t_2:
    # (1) clock source is s_t_2
    # (2) gate wide open
    # (3) started by ccl 1/end aka c_so/end
    # (4) reset by ccl 12/egal aka c_d/egal
    # (5) ... while running continuously
    config = CtConfig(clock_source=CtClockSrc.CLK_1_25_KHz,              # (1)
                      gate_source=CtGateSrc.GATE_CMPT,                   # (2)
                      hard_start_source=CtHardStartSrc.CT_1_STOP,        # (3)
                      hard_stop_source=CtHardStopSrc.CT_12_EQ_CMP_12,    # (4)
                      reset_from_hard_soft_stop=True,                    # (5)
                      stop_from_hard_stop=False)                         # (4)
    card.set_counter_config(c_t_2, config)
    
    latch_sources[c_t_2] = [c_d]

    # write all latch sources
    card.set_counters_latch_sources(latch_sources)

    # We store the latched counter values of ccls 2 and 3 (2)
    # while it should suffice that the transfer is triggered by
    # c_t_1's latch (1).  But first and foremost, we enable the
    # transfer (3).
    card.set_DMA_enable_trigger_latch({c_t_1:True}, {c_t_1:True, c_t_2:True})

    # Set output cell 1's signal source to ic 1 (1) and
    # output cell 2's signal source to ic 2(2).
    card.set_output_channels_source({9: OutputSrc.CH_1_INPUT,
                                     10: OutputSrc.CH_2_INPUT})

    # Set the filter configuration for both outputs.  Neither cell's signal
    # shall be inverted nor filters used
    card.set_output_channels_filter({9: FilterOutput(polarity=0, enable=False, 
                                                     clock=FilterClock.CLK_100_MHz),
                                     10: FilterOutput(polarity=0, enable=False, 
                                                      clock=FilterClock.CLK_100_MHz)})

    # Set both output cells' levels to TTL.
    card.set_output_channels_level({9: Level.TTL, 10: Level.TTL})

    # Enable input termination on all inputs except ic 9 and ic10.
    card.set_input_channels_50ohm_adapter(dict([(i, True) for i in range(1, 9)]))
    
    # Set input cells 1's (1) and 2's (2) filter configuration
    # to short pulse capture.
    card.set_input_channels_filter(
        {1: FilterInput(clock=FilterClock.CLK_100_MHz,
                        selection=FilterInputSelection.SINGLE_SHORT_PULSE_CAPTURE),
         2:  FilterInput(clock=FilterClock.CLK_100_MHz,
                         selection=FilterInputSelection.SINGLE_SHORT_PULSE_CAPTURE)})

    card.set_input_channels_level({1: Level.TTL, 2: Level.TTL})

    fifo = ct2.create_fifo_mmap(card)

    poll = select.epoll()
    poll.register(card, select.EPOLLIN | select.EPOLLHUP | select.EPOLLERR)
    
    card.enable_interrupts(100)

    card.set_interrupts(counters=counter_interrupts,
                        dma=True, fifo_half_full=True, error=True)

    # enable counters
    card.set_counters_software_enable({1: True, 11: True, 12: True, 2: True, 3: True})
    
    stop, finish = False, False
    while not stop:
        events = poll.poll(timeout=1)
        if not events:
            logging.debug("poll loop")
            continue
        for fd, event in events:
            result = handle_event(card, fifo, fd, event)
            if result == 0:
                continue
            elif result == 1:
                stop = finish = True
                break
            elif result in (2, 3):
                stop = True
                break
            else:
                stop = True
                break
Ejemplo n.º 8
0
def main():
    #logging.basicConfig(level=logging.DEBUG)

    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('--value',
                        type=int,
                        default=1000 * 1000,
                        help='count until value')

    args = parser.parse_args()
    value = args.value

    def out(msg):
        sys.stdout.write(msg)
        sys.stdout.flush()

    p201 = P201()
    p201.request_exclusive_access()
    p201.reset()
    p201.software_reset()

    # internal clock 100 Mhz
    p201.set_clock(Clock.CLK_100_MHz)

    # channel 10 output: counter 10 gate envelop
    p201.set_output_channels_level(
        dict([(ct, Level.TTL) for ct in p201.COUNTERS]))

    # no 50 ohm adapter
    p201.set_input_channels_50ohm_adapter({})

    # channel 9 and 10: no filter, no polarity
    p201.set_output_channels_filter({})

    # channel N output: counter N gate envelop
    gate = dict([(ct, getattr(OutputSrc, "CT_%d_GATE" % ct))
                 for ct in p201.COUNTERS])
    p201.set_output_channels_source(gate)

    # Internal clock to 1 Mhz [1us], Gate=1, Soft Start, HardStop on CMP,
    # Reset on Hard/SoftStop, Stop on HardStop
    cts_cfg = {}
    for counter in p201.COUNTERS:
        hard_stop = getattr(CtHardStopSrc, "CT_{0}_EQ_CMP_{0}".format(counter))
        cfg = CtConfig(clock_source=CtClockSrc.CLK_1_MHz,
                       gate_source=CtGateSrc.GATE_CMPT,
                       hard_start_source=CtHardStartSrc.SOFTWARE,
                       hard_stop_source=hard_stop,
                       reset_from_hard_soft_stop=True,
                       stop_from_hard_stop=True)
        cts_cfg[counter] = cfg
    p201.set_counters_config(cts_cfg)

    # Latch N on Counter N HardStop
    p201.set_counters_latch_sources(dict([(c, c) for c in p201.COUNTERS]))

    # Counter N will count V/1000*1000 sec
    for counter in p201.COUNTERS:
        p201.set_counter_comparator_value(counter, value)

    started, start_count = False, 0
    while not started:
        # SoftStart on Counter N
        start_count += 1
        if start_count > 10:
            print("failed to start after 10 atempts")
            break
        p201.set_counters_software_start_stop(
            dict([(c, True) for c in p201.COUNTERS]))
        status = p201.get_counters_status()
        started = status[1].run

    if start_count > 1:
        logging.warning("took %d times to start", start_count)

    if started:
        print("Started!")
        import time
        while True:
            time.sleep(0.1)
            counter_values = p201.get_counters_values()
            latch_values = p201.get_latches_values()
            status = p201.get_counters_status()
            if not status[counter].run:
                break
            msg = "\r{0} {1}".format(counter_values.tolist(),
                                     latch_values.tolist())
            out(msg)
        print("\n{0} {1}".format(counter_values.tolist(),
                                 latch_values.tolist()))

    pprint.pprint(p201.get_counters_status())
    p201.relinquish_exclusive_access()

    return p201
Ejemplo n.º 9
0
def prepare(context):

    card = context.card
    counter = context.counter
    value = context.value
    acq_len = context.acq_len

    # internal clock 100 Mhz
    card.set_clock(Clock.CLK_100_MHz)

    hard_stop = getattr(CtHardStopSrc, "CT_{0}_EQ_CMP_{0}".format(counter))
    ct_config = CtConfig(clock_source=CtClockSrc.CLK_1_MHz,
                         gate_source=CtGateSrc.GATE_CMPT,
                         hard_start_source=CtHardStartSrc.SOFTWARE,
                         hard_stop_source=hard_stop,
                         reset_from_hard_soft_stop=True,
                         stop_from_hard_stop=False)

    hard_start = getattr(CtHardStartSrc, "CT_{0}_START".format(counter))
    ct_11_config = CtConfig(clock_source=CtClockSrc.CLK_1_MHz,
                            gate_source=CtGateSrc.GATE_CMPT,
                            hard_start_source=hard_start,
                            hard_stop_source=CtHardStopSrc.SOFTWARE,
                            reset_from_hard_soft_stop=False,
                            stop_from_hard_stop=False)

    clock_source = getattr(CtClockSrc, "INC_CT_{0}_STOP".format(counter))
    ct_12_config = CtConfig(clock_source=clock_source,
                            gate_source=CtGateSrc.GATE_CMPT,
                            hard_start_source=hard_start,
                            hard_stop_source=CtHardStopSrc.SOFTWARE,
                            reset_from_hard_soft_stop=False,
                            stop_from_hard_stop=False)

    card.set_counters_config({
        counter: ct_config,
        11: ct_11_config,
        12: ct_12_config
    })

    card.set_counter_comparator_value(counter, value)

    # Latch N on Counter N HardStop
    #    card.set_counters_latch_sources({counter: [counter], 10 : [counter]})
    card.set_counters_latch_sources({
        counter: [counter],
        11: [counter],
        12: [counter]
    })

    # counter *counter* to latch triggers DMA
    # at each DMA trigger, counters *counter*, 11 and 12 are stored to FIFO
    card.set_DMA_enable_trigger_latch({counter: True}, {
        counter: True,
        11: True,
        12: True
    })

    card.set_interrupts(dma=True, error=True)

    card.set_counters_software_enable({counter: True, 11: True, 12: True})

    # force creation of a FIFO interface
    fifo = card.fifo

    etl = card.get_DMA_enable_trigger_latch()
    nb_counters = etl[1].values().count(True)

    usec = acq_len * 1000000
    card._fifo_stat = numpy.zeros((int(usec / value), ), dtype='uint32')
    card._fifo_stat_index = 0
Ejemplo n.º 10
0
def main():

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--log-level', type=str, default='info',
                        help='log level (debug, info, warning, error) [default: info]')
    parser.add_argument('--value', type=int, default=10000,
                        help='count until value')
    parser.add_argument('--nb_counters', type=int, default=5,
                        help='use first n counters (max=6)')

    args = parser.parse_args()

    logging.basicConfig(level=getattr(logging, args.log_level.upper()),
                        format="%(asctime)s %(levelname)s %(name)s: %(message)s")
    
    value = args.value
    nb_counters = args.nb_counters

    if nb_counters > 6:
        print("Can only use first 6 counters")
        sys.exit(1)

    counters = tuple(range(1, nb_counters+1))

    card = P201Card()
    card.request_exclusive_access()
    card.reset()
    card.software_reset()

    # internal clock 100 Mhz
    card.set_clock(Clock.CLK_100_MHz)

    ct_config = CtConfig(clock_source=CtClockSrc.CLK_100_MHz,
                         gate_source=CtGateSrc.GATE_CMPT,
                         hard_start_source=CtHardStartSrc.SOFTWARE,
                         hard_stop_source=CtHardStopSrc.CT_1_EQ_CMP_1,
                         reset_from_hard_soft_stop=True,
                         stop_from_hard_stop=False)

    card.set_counter_config(1, ct_config)
    card.set_counter_comparator_value(1, value)

    for counter in counters[1:]:
        clock = getattr(CtClockSrc, "INC_CT_{0}_STOP".format(counter-1))
        hard_stop = getattr(CtHardStopSrc, "CT_{0}_EQ_CMP_{0}".format(counter))
        ct_config = CtConfig(clock_source=clock,
                             gate_source=CtGateSrc.GATE_CMPT,
                             hard_start_source=CtHardStartSrc.SOFTWARE,
                             hard_stop_source=hard_stop,
                             reset_from_hard_soft_stop=True,
                             stop_from_hard_stop=False)

        card.set_counter_config(counter, ct_config)
        v_ct = value/10**(counter-1)
        print(v_ct)
        card.set_counter_comparator_value(counter, v_ct)

    # Latch N on Counter N HardStop
    card.set_counters_latch_sources(dict([(counter, (counter,)) for counter in counters]))
    card.enable_counters_software(counters)

    # Start!
    card.set_counters_software_start(counters)

    print("Started!")
    while True:
        time.sleep(0.1)
        counters_values = card.get_counters_values()[:nb_counters]
        latches_values = card.get_latches_values()[:nb_counters]
        run = False
        for ct_status in card.get_counters_status().values():
            run = run or ct_status.run
        if not run:
            break
        out("\r{0} {1}".format(counters_values, latches_values))
    print("\n{0} {1}".format(counters_values.tolist(), latches_values.tolist()))

    pprint.pprint(card.get_counters_status())
    card.disable_counters_software((counter,))
    card.relinquish_exclusive_access()

    return card