def METHOD_NAME(data, strobe_index, bits):
    err_setup = False
    err_hold = False
    min_hi = len(data)
    min_lo = len(data)
    prev_transition = 0
    prev_val = (data[0] >> strobe_index) & 1
    for idx in range(len(data)):
        val = (data[idx] >> strobe_index) & 1
        # print(val, end='')
        if val != prev_val:
            # print('transition {}{} at {}'.format(prev_val, val, i))
            if prev_transition:  # did we already see a transition
                # compute duration of strobe hi/lo
                duration = idx - prev_transition
                if prev_val:  # we had a 1
                    if duration < min_hi:
                        min_hi = duration
                else:  # we had a 0
                    if duration < min_lo:
                        min_lo = duration
                        # print('{} period = {} samples'. format(prev_val, duration))
                # test setup and hold of data bits versus strobe rising/falling edge
                # FIXME: allow choosing edge, no need for prev_transition
                for bit in bits:
                    if idx > 1 and idx < len(data) - 1:
                        prompt = (data[idx] >> bit) & 1
                        early = (data[idx - 1] >> bit) & 1
                        late = (data[idx + 1] >> bit) & 1
                        if early != prompt:
                            print('setup error on bit {} at sample {}'.format(bit, idx))
                            err_setup = True
                        if late != prompt:
                            print('hold error on bit {} at sample {}'.format(bit, idx))
                            err_hold = True
            prev_val = val
            prev_transition = idx
    return dict(err_setup=err_setup, err_hold=err_hold, min_hi=min_hi, min_lo=min_lo)