Skip to content

Instantly share code, notes, and snippets.

@hansfbaier
Last active February 23, 2024 23:44
Show Gist options
  • Save hansfbaier/6a9a9fab6917b4e5e6394e5ad2df6fe9 to your computer and use it in GitHub Desktop.
Save hansfbaier/6a9a9fab6917b4e5e6394e5ad2df6fe9 to your computer and use it in GitHub Desktop.
ADV7513 status display tool in python
#!/usr/bin/env python
from smbus import SMBus
def byte(addr):
return bus.read_byte_data(0x39, addr)
def bit(addr, n):
d = bus.read_byte_data(0x39, addr)
return (d >> n) & 0x1
def bits(reg, msb, lsb):
d = bus.read_byte_data(0x39, reg)
assert msb >= lsb
return (d >> lsb) & ((1 << (msb - lsb + 1)) - 1)
def must(reg, msb, lsb, val):
dat = bits(reg, msb, lsb)
result = "OK" if dat == val else "FAIL"
print(f"{reg:2x}: 0x{dat:02x} 0b{dat:b} {result}")
def two(reg, bit, msg, yay, nay):
d = (bus.read_byte_data(0x39, reg) >> bit) & 0x1
print(f"{msg}: {yay if d == 1 else nay}")
ddc_error = \
{
0b0000: "No Error",
0b0001: "Bad Receiver BKSV",
0b0010: "Ri Mismatch",
0b0011: "Pj Mismatch",
0b0100: "I2C Error (usually a no-ack)",
0b0101: "Timed Out Waiting for Downstream Repeater DONE",
0b0110: "Max Cascade of Repeaters Exceeded",
0b0111: "SHA-1 Hash Check of KSV List Failed",
0b1000: "Too Many Devices Connected to Repeater Tree"
}
ddc_state = \
{
0b0000: "In Reset (No Hot Plug Detected)",
0b0001: "Reading EDID",
0b0010: "IDLE (Waiting for HDCP Requested)",
0b0011: "Initializing HDCP",
0b0100: "HDCP Enabled",
0b0101: "Initializing HDCP Repeater",
}
input_format = \
{
0b0000: "24 bit RGB 4:4:4 or YCbCr 4:4:4 (separate syncs)",
0b0001: "16, 20, 24 bit YCbCr 4:2:2 (separate syncs)",
0b0010: "16, 20, 24 bit YCbCr 4:2:2 (embedded syncs)",
0b0011: "8, 10, 12 bit YCbCr 4:2:2 (2x pixel clock, separate syncs)",
0b0100: "8, 10, 12 bit YCbCr 4:2:2 (2x pixel clock, embedded syncs)",
0b0101: "12, 15, 16 bit RGB 4:4:4 or YCbCr (DDR with separate syncs)",
0b0110: "8,10,12 bit YCbCr 4:2:2 (DDR with separate syncs) ",
0b0111: "8, 10, 12 bit YCbCr 4:2:2 (DDR separate syncs) ",
0b1000: "8, 10, 12 bit YCbCr 4:2:2 (DDR embedded syncs)",
}
video_modes = \
{
0b000000: 'VIC#0: VIC Unavailable',
0b000001: 'VIC#1: VGA (640x480) 4:3',
0b000010: 'VIC#2: 480p-60, 4:3',
0b000011: 'VIC#3: 480p-60, 16:9',
0b000100: 'VIC#4: 720p-60, 16:9',
0b000101: 'VIC#5: 1080i-60, 16:9',
0b000110: 'VIC#6: 480i-60, 2x Clk, 4:3',
0b000111: 'VIC#7: 480i-60, 2x Clk, 16:9',
0b001000: 'VIC#8: 240p-60, 2x Clk, 4:3',
0b001001: 'VIC#9: 240p-60, 2x Clk, 16:9',
0b001010: 'VIC#10: 480i-60, 4x Clk, 4:3',
0b001011: 'VIC#11: 480i-60, 4x Clk, 16:9',
0b001100: 'VIC#12: 240p-60, 8x Clk, 4:3',
0b001101: 'VIC#13: 240p-60, 8x Clk, 16:9',
0b001110: 'VIC#14: 480p-60, 2x Clk, 4:3',
0b001111: 'VIC#15: 480p-60, 2x Clk, 16:9',
0b010000: 'VIC#16: 1080p-60, 16:9',
0b010001: 'VIC#17: 576p-50, 4:3',
0b010010: 'VIC#18: 576p-50, 16:9',
0b010011: 'VIC#19: 720p-50, 16:9',
0b010100: 'VIC#20: 1080i-50, 16:9',
0b010101: 'VIC#21: 576i-50, 2x Clk, 4:3',
0b010110: 'VIC#22: 576i-50, 2x Clk, 16:9',
0b010111: 'VIC#23: 288p-50, 2x Clk, 4:3',
0b011000: 'VIC#24: 288p-50, 2x Clk, 16:9',
0b011001: 'VIC#25: 576i-50, 4x Clk, 4:3',
0b011010: 'VIC#26: 576i-50, 4x Clk, 16:9',
0b011011: 'VIC#27: 288p-50, 8x Clk, 4:3',
0b011100: 'VIC#28: 288p-50, 8x Clk, 16:9',
0b011101: 'VIC#29: 576p-50, 2x Clk, 4:3',
0b011110: 'VIC#30: 576p-50, 2x Clk, 16:9',
0b011111: 'VIC#31: 1080p-50, 16:9',
0b100000: 'VIC#32: 1080p-24, 16:9',
0b100001: 'VIC#33: 1080p-25, 16:9',
0b100010: 'VIC#34: 1080p-30, 16:9',
0b100011: 'VIC#35: 480p-60, 4x Clk, 4:3',
0b100100: 'VIC#36: 480p-60, 4x Clk, 16:9',
0b100101: 'VIC#37: 576p-50, 4x Clk, 4:3',
0b100110: 'VIC#38: 576p-50, 4x Clk, 16:9',
0b100111: 'VIC#39: 1080i-50, Alt Blanking',
0b101000: 'VIC#40: 1080i-100, 16:9',
0b101001: 'VIC#41: 720p-100, 16:9',
0b101010: 'VIC#42: 576p-100, 4:3',
0b101011: 'VIC#43: 576p-100, 16:9',
0b101100: 'VIC#44: 576i-100, 4:3',
0b101101: 'VIC#45: 576i-100, 16:9',
0b101110: 'VIC#46: 1080i-120, 16:9',
0b101111: 'VIC#47: 720p-120, 16:9',
0b110000: 'VIC#48: 480p-120, 4:3',
0b110001: 'VIC#49: 480p-120, 16:9',
0b110010: 'VIC#50: 480i-120, 4:3',
0b110011: 'VIC#51: 480i-120, 16:9',
0b110100: 'VIC#52: 576p-200, 4:3',
0b110101: 'VIC#53: 576p-200, 16:9',
0b110110: 'VIC#54: 576i-200, 4:3',
0b110111: 'VIC#55: 576i-200, 16:9',
0b111000: 'VIC#56: 480p-240, 4:3',
0b111001: 'VIC#57: 480p-240, 16:9',
0b111010: 'VIC#58: 480i-240, 4:3',
0b111011: 'VIC#59: 480i-240, 16:9',
0b111100: 'VIC#60: 60+ For Future Use',
}
pixel_repeat = \
{
0b00: 'auto mode',
0b01: 'max mode',
0b10: 'manual mode',
0b11: 'manual mode',
}
bus=SMBus(2)
two(0x41, 6, 'Power down', 'on', 'off')
print(f"Hot plug detect: {bit(0x42, 6)}")
print(f"HDMI clock termination: {bit(0x42, 5)}")
print(f"HDMI Mode: {bit(0xaf, 1)}")
two(0xaf, 7, "HDCP", 'enabled', 'disabled')
print("")
print(f"GC packet enabled: {bit(0x40, 7)}")
print(f"GC packet update active: {bit(0x4a, 4)}")
print(f"clear AV mute: {bit(0x4b, 7)}")
print(f"set AV mute: {bit(0x4b, 6)}\n")
print(f"Channel 0 power down: {bit(0xa1, 5)}")
print(f"Channel 1 power down: {bit(0xa1, 4)}")
print(f"Channel 2 power down: {bit(0xa1, 3)}")
print(f"Clock driver power down: {bit(0xa1, 2)}")
print(f"TMDS clock soft turn on: {bit(0xd6, 4)}")
print(f"TMDS clock inversion: {bit(0xde, 3)}\n")
print(f"Source Product Description enabled: {bit(0x40, 6)}")
print(f"DDC state: {ddc_state[((bus.read_byte_data(0x39, 0xc8) >> 0) & 0xf)]}")
print(f"DDC error: {ddc_error[((bus.read_byte_data(0x39, 0xc8) >> 4) & 0xf)]}")
print(f"PLL Lock: {bit(0x9e, 4)}\n")
print("Must set registers:")
must(0x9A, 7, 1, 0b111000)
must(0x98, 7, 0, 0x03)
must(0x9C, 7, 0, 0x30)
must(0x9D, 1, 0, 0b01)
must(0xA2, 7, 0, 0xA4)
must(0xA3, 7, 0, 0xA4)
must(0xE0, 7, 0, 0xD0)
must(0xF9, 7, 0, 0x00)
print(f"\ninput format: {input_format[((bus.read_byte_data(0x39, 0x15)) & 0xf)]}")
two(0x16, 7, "Output format", "4:2:2", "4:4:4")
two(0x17, 6, "VSYNC polarity", "low", "high")
two(0x17, 5, "HSYNC polarity", "low", "high")
two(0x48, 6, "input bit reverse", "reverse", "normal")
input_clkdiv = \
{
0b00: "Input Clock not Divided",
0b01: "Input Clock Divided by 2",
0b10: "Input Clock Divided by 4",
0b11: "Invalid Setting",
}
print(f"\ninput clock division: {input_clkdiv[(bus.read_byte_data(0x39, 0x9d) >> 2) & 0b11]}")
two(0x17, 0, "DE generation", "internal", "external")
print("\nVideo mode detect:")
two(0x17, 1, 'aspect ratio', '16:9', '4:3')
print(f"Actual detected: {video_modes[((bus.read_byte_data(0x39, 0x3e)) >> 2)]}")
print(f"Vic manual: {video_modes[((bus.read_byte_data(0x39, 0x3c)) & 0b111111)]}")
print(f"Vic to RX: {video_modes[((bus.read_byte_data(0x39, 0x3d)) & 0b111111)]}")
two(0x41, 1, "sync adjustment", 'enabled', 'disabled')
print(f"pixel repeat : {pixel_repeat[((bus.read_byte_data(0x39, 0x3cbd)) >> 5) & 0b11]}")
two(0x44, 4, 'AVI info frame', 'enabled', 'disabled')
print('\nAudio:')
spdif_freq = \
{
0b0000: '44.1 kHz',
0b0001: 'N/A',
0b0010: '48.0 kHz',
0b0011: '32.0 kHz',
0b0100: 'N/A',
0b0101: 'N/A',
0b0110: 'N/A',
0b0111: 'N/A',
0b1000: '88.2 kHz',
0b1001: 'N/A',
0b1010: '96.0 kHz',
0b1011: 'N/A',
0b1100: '176.4 kHz',
0b1101: 'N/A',
0b1110: '192.0 kHz',
0b1111: 'N/A',
}
two(0x0b, 7, 'SPDIF', 'enabled', 'disabled')
print(f"SPDIF frequency: {spdif_freq[bits(0x04, 7, 4)]}")
audio_select = \
{
0b000: 'I2S',
0b001: 'SPDIF',
0b010: 'N/A',
0b011: 'High Bit Rate (HBR Audio)',
0b100: 'N/A',
0b101: 'N/A',
0b110: 'N/A',
0b111: 'N/A',
}
print(f"audio select : {audio_select[bits(0x0a, 6, 4)]}")
mclk_ratio = \
{
0b00: '128xfs',
0b01: '256xfs',
0b10: '384xfs',
0b11: '512xfs',
}
two(0x0b, 6, 'Audo clock polarity', 'falling edge', 'rising edge')
two(0x0b, 5, 'MCLK', 'external', 'internally generated')
print(f"mclk ratio: {mclk_ratio[bits(0x0a, 1, 0)]}")
two(0x0c, 7, 'sampling freq select', 'from register', 'from stream')
two(0x0c, 5, 'I2S3 Enable', 'enabled', 'disabled')
two(0x0c, 4, 'I2S2 Enable', 'enabled', 'disabled')
two(0x0c, 3, 'I2S1 Enable', 'enabled', 'disabled')
two(0x0c, 2, 'I2S0 Enable', 'enabled', 'disabled')
i2s_format = \
{
0b00: 'Standard I2S mode',
0b01: 'right justified mode',
0b10: 'left justified mode',
0b11: 'AES3 direct mode',
}
print(f"I2S Format: {i2s_format[bits(0x0c, 1, 0)]}")
sampling_freq = \
{
0b0000: '44.1 kHz',
0b0001: 'Do not use',
0b0010: '48.0 kHz',
0b0011: '32.0 kHz',
0b0100: 'Do not use',
0b0101: 'Do not use',
0b0110: 'Do not use',
0b0111: 'Do not use',
0b1000: '88.2 kHz',
0b1001: 'HBR Audio',
0b1010: '96.0 kHz',
0b1011: 'Do not use',
0b1100: '176.4 kHz',
0b1101: 'Do not use',
0b1110: '192.0 kHz',
0b1111: 'Do not use',
}
print(f"sampling frequency for pixel repeat: {sampling_freq[bits(0x15, 7, 4)]}")
print("")
two(0x0a, 7, "CTS Source Select", 'manual', 'automatic')
two(0x44, 6, 'CTS packet', 'enable', 'disable')
N = ((byte(0x01) & 0xff) << 16) | (byte(0x02) << 8) | byte(0x03)
CTSa = ((byte(0x04) & 0xff) << 16) | (byte(0x05) << 8) | byte(0x06)
CTSm = ((byte(0x07) & 0xff) << 16) | (byte(0x08) << 8) | byte(0x09)
#print(f"{byte(0x04):2x} {byte(0x05):2x} {byte(0x06):2x}")
print(f"N: {N} CTS manual: {CTSm} auto: {CTSa}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment