def generate_du(display):
    """
    Generate the "direct update" mode for a display.
    """
    frame_times = FRAME_TIMES_DU[display]
    num_phases = len(frame_times)

    phases = []
    for frame in range(num_phases):

        def lutfunc(t, f):
            if t == 0 and f > 0:
                return 1
            elif t == 30 and f < 30:
                return 2
            else:
                return 0

        phase = generate_frame(lutfunc)
        phases.append(phase)

    return {
        "mode": mode_id("MODE_DU"),
        "ranges": [{
            "index": 0,
            "phases": phases,
            "phase_times": frame_times
        }]
    }
def generate_mode_GL16(display):
    """
    Do non-flashing arbitrary transitions by going to full black, then the desired value.
    """
    phases = []
    for frame in range(15):
        phase = generate_frame(lambda t, f: f >= (30 - 2 * frame))
        phase[30][30] = 0
        phase[0][0] = 0
        phases.append(phase)
    for frame in range(15):
        phase = generate_frame(lambda t, f: 2 * (t > (2 * frame)))
        phase[30][30] = 0
        phase[0][0] = 0
        phases.append(phase)

    frame_times = FRAME_TIMES_WHITE_TO_GL16[
        display] + FRAME_TIMES_BLACK_TO_GL16[display]
    return {
        "mode": mode_id("MODE_GL16"),
        "ranges": [{
            "index": 0,
            "phases": phases,
            "phase_times": frame_times
        }]
    }
def generate_epdiy_waveform(display):
    # we say that these temperature waveforms are valid in ~room temperature.
    default_temperature_range = {"from": 20, "to": 30}

    white_to_gl16 = generate_mode_x_to_GL16(
        display, mode_id("MODE_EPDIY_WHITE_TO_GL16"))
    black_to_gl16 = generate_mode_x_to_GL16(
        display, mode_id("MODE_EPDIY_BLACK_TO_GL16"))
    gc16 = generate_mode_GC16(display)
    gl16 = generate_mode_GL16(display)
    du = generate_du(display)

    temperature_ranges = {"range_bounds": [default_temperature_range]}
    return {
        "temperature_ranges": temperature_ranges,
        "modes": [du, gc16, gl16, white_to_gl16, black_to_gl16]
    }