Update full-res encode to use 10 bit TMDS symbols (still one symbol per word.)

two-pixels-per-word
Luke Wren 2021-03-02 16:41:22 +00:00
rodzic b20f4ef88f
commit 74f62e6252
5 zmienionych plików z 157 dodań i 169 usunięć

Wyświetl plik

@ -13,9 +13,15 @@ target_compile_definitions(vista_boot2 PRIVATE PICO_FLASH_SPI_CLKDIV=2)
pico_set_boot_stage2(vista vista_boot2)
target_compile_definitions(vista PRIVATE DVI_VERTICAL_REPEAT=1 DVI_N_TMDS_BUFFERS=5)
target_compile_definitions(vista PRIVATE
DVI_VERTICAL_REPEAT=1
DVI_N_TMDS_BUFFERS=5
DVI_SYMBOLS_PER_WORD=1
)
target_compile_definitions(vista PRIVATE PICO_STACK_SIZE=0x200)
target_link_libraries(vista
pico_stdlib
pico_multicore

Wyświetl plik

@ -201,13 +201,17 @@ const uint32_t __dvi_const(dvi_ctrl_syms)[4] = {
// Output solid red scanline if we are given NULL for tmdsbuff
#if DVI_SYMBOLS_PER_WORD == 2
static uint32_t __attribute__((aligned(8))) __dvi_const(empty_scanline_tmds)[3] = {
0x7fd00u, // 0x00
0x7fd00u, // 0x00
0xbfa01u // 0xfc
static uint32_t __dvi_const(empty_scanline_tmds)[3] = {
0x7fd00u, // 0x00, 0x00
0x7fd00u, // 0x00, 0x00
0xbfa01u // 0xfc, 0xfc
};
#else
#error "Can't handle empty scanlines with pixel-per-word right now"
static uint32_t __attribute__((aligned(8))) __dvi_const(empty_scanline_tmds)[6] = {
0x100u, 0x1ffu, // 0x00, 0x00
0x100u, 0x1ffu, // 0x00, 0x00
0x201u, 0x2feu // 0xfc, 0xfc
};
#endif
void dvi_timing_state_init(struct dvi_timing_state *t) {
@ -259,6 +263,7 @@ void dvi_setup_scanline_for_vblank(const struct dvi_timing *t, const struct dvi_
const uint32_t *sym_no_sync = get_ctrl_sym(false, false );
dma_cb_t *synclist = dvi_lane_from_list(l, TMDS_SYNC_LANE);
// The symbol table contains each control symbol *twice*, concatenated into 20 LSBs of table word, so we can always do word-repeat.
_set_data_cb(&synclist[0], &dma_cfg[TMDS_SYNC_LANE], sym_hsync_off, t->h_front_porch / DVI_SYMBOLS_PER_WORD, 2, false);
_set_data_cb(&synclist[1], &dma_cfg[TMDS_SYNC_LANE], sym_hsync_on, t->h_sync_width / DVI_SYMBOLS_PER_WORD, 2, false);
_set_data_cb(&synclist[2], &dma_cfg[TMDS_SYNC_LANE], sym_hsync_off, t->h_back_porch / DVI_SYMBOLS_PER_WORD, 2, true);
@ -298,7 +303,7 @@ void dvi_setup_scanline_for_active(const struct dvi_timing *t, const struct dvi_
t->h_active_pixels / DVI_SYMBOLS_PER_WORD, 0, false);
}
else {
// 8-byte read ring mode to repeat the correct DC-balanced symbol pair on blank scanlines
// Use read ring to repeat the correct DC-balanced symbol pair on blank scanlines (4 or 8 byte period)
_set_data_cb(&cblist[target_block], &dma_cfg[i], &empty_scanline_tmds[2 * i / DVI_SYMBOLS_PER_WORD],
t->h_active_pixels / DVI_SYMBOLS_PER_WORD, DVI_SYMBOLS_PER_WORD == 2 ? 2 : 3, false);
}

Wyświetl plik

@ -275,11 +275,9 @@ tmds_1bpp_table:
// once (2 words), and write 4 at once (4 words). This gives 7 cyc/pix.
//
// One issue is that the TMDS data in the bottom of ACCUM1 will eventually
// overflow and affect the running disparity. At least 64 pixels will pass
// before this happens, so we just need to read out ACCUM1, mask it, and write
// it back at least once every 64 pixels. This could be done at the end of
// every unrolled loop, before the test and branch. At 16 pix/loop this is an
// additional 0.5 cyc/pix.
// overflow and affect the running disparity, but with 16 zeroes in between,
// this would take much longer than one scanline, so everything is fine if
// we clear the accumulator at the start of the scanline.
//
// Note that we need to use two interpolators to get the bits from both pixels
// -- we are not outputting a single DC-balanced stream, but rather two
@ -355,16 +353,6 @@ tmds_1bpp_table:
stmia r1!, {r4, r5, r6, r7}
.endr
// Need to mask away bottoms of ACCUM1 before the TMDS data overflows into
// disparity counter. This costs 8 cycles per loop body.
#if !TMDS_FULLRES_NO_DC_BALANCE
ldr r4, [r2, #ACCUM1_OFFS]
ands r4, r3
str r4, [r2, #ACCUM1_OFFS]
ldr r4, [r2, #ACCUM1_OFFS + INTERP1]
ands r4, r3
str r4, [r2, #ACCUM1_OFFS + INTERP1]
#endif
2:
cmp r1, ip
beq 1f
@ -447,17 +435,6 @@ decl_func_y tmds_fullres_encode_loop_16bpp_y
stmia r1!, {r4, r5, r6, r7}
.endr
// Need to mask away bottoms of ACCUM1 before the TMDS data overflows into
// disparity counter
#if !TMDS_FULLRES_NO_DC_BALANCE
mov r5, r9
ldr r4, [r2, #ACCUM1_OFFS]
ands r4, r5
str r4, [r2, #ACCUM1_OFFS]
ldr r4, [r2, #ACCUM1_OFFS + INTERP1]
ands r4, r5
str r4, [r2, #ACCUM1_OFFS + INTERP1]
#endif
2:
cmp r1, ip
beq 1f

Wyświetl plik

@ -1,6 +1,6 @@
// Each entry consists of a 20 bit TMDS symbol in pseudo-differential format
// (20 LSBs) and the symbol's disparity as a 6 bit signed integer (the 6
// MSBs). There is a 6 bit gap in between them, which is actually vital for
// Each entry consists of a 10 bit TMDS symbol in pseudo-differential format
// (10 LSBs) and the symbol's disparity as a 6 bit signed integer (the 6
// MSBs). There is a 16 bit gap in between them, which is actually vital for
// the way the TMDS encode works!
//
// There are 128 1-word entries. The lookup index should be the concatenation
@ -8,132 +8,132 @@
// data.
// Non-negative running disparity:
0xe009aaaa,
0xf805aaa5,
0x0005aa95,
0xe809aa9a,
0x000955aa,
0xf009aa5a,
0xe809aa6a,
0x0005aa65,
0xf80956aa,
0xf809a95a,
0xf009a96a,
0x0009569a,
0xe809a9aa,
0x0005a9a5,
0x0009566a,
0xf0069aa9,
0xf0095aaa,
0x0009a55a,
0xf809a56a,
0xf8095a9a,
0xf009a5aa,
0x00095a5a,
0xf8095a6a,
0xf80696a9,
0xe809a6aa,
0x0005a6a5,
0x0009596a,
0x000695a9,
0xf80959aa,
0xf00a6a96,
0xe80a6aa6,
0xf0066aa9,
0xe8096aaa,
0x00056aa5,
0x0009956a,
0xf0096a9a,
0xf80995aa,
0xf8096a5a,
0xf0096a6a,
0xf006a6a9,
0xf00996aa,
0x0009695a,
0xf809696a,
0xf806a5a9,
0xf00969aa,
0x0006a569,
0xf00a5aa6,
0xf8065aa9,
0xe8099aaa,
0x00059aa5,
0x0009656a,
0xf006a9a9,
0xf80965aa,
0xf806a969,
0x0006a959,
0x000656a9,
0xf00966aa,
0xf006aa69,
0xf806aa59,
0xf00aaa56,
0xf006aa99,
0xe80aaa96,
0xe00aaaa6,
0xe806aaa9,
0xe0000100,
0xf8000303,
0x00000307,
0xe8000104,
0x000001f0,
0xf000010c,
0xe8000108,
0x0000030b,
0xf80001e0,
0xf800011c,
0xf0000118,
0x000001e4,
0xe8000110,
0x00000313,
0x000001e8,
0xf0000241,
0xf00001c0,
0x0000013c,
0xf8000138,
0xf80001c4,
0xf0000130,
0x000001cc,
0xf80001c8,
0xf8000261,
0xe8000120,
0x00000323,
0x000001d8,
0x00000271,
0xf80001d0,
0xf0000086,
0xe8000082,
0xf0000281,
0xe8000180,
0x00000383,
0x00000178,
0xf0000184,
0xf8000170,
0xf800018c,
0xf0000188,
0xf0000221,
0xf0000160,
0x0000019c,
0xf8000198,
0xf8000231,
0xf0000190,
0x00000239,
0xf00000c2,
0xf80002c1,
0xe8000140,
0x00000343,
0x000001b8,
0xf0000211,
0xf80001b0,
0xf8000219,
0x0000021d,
0x000002e1,
0xf00001a0,
0xf0000209,
0xf800020d,
0xf000000e,
0xf0000205,
0xe8000006,
0xe0000002,
0xe8000201,
// Negative running disparity:
0x28055555,
0x1009555a,
0x0809556a,
0x20055565,
0x000955aa,
0x180555a5,
0x20055595,
0x0809559a,
0x1005a955,
0x100556a5,
0x18055695,
0x0009569a,
0x20055655,
0x0809565a,
0x0009566a,
0x080a6556,
0x1805a555,
0x0009a55a,
0x10055a95,
0x1005a565,
0x18055a55,
0x00095a5a,
0x1005a595,
0x000a6956,
0x20055955,
0x0809595a,
0x0009596a,
0x000695a9,
0x1005a655,
0x08069569,
0x10069559,
0x080a9556,
0x20059555,
0x0809955a,
0x0009956a,
0x18059565,
0x10056a55,
0x100595a5,
0x18059595,
0x080a5956,
0x18056955,
0x0009695a,
0x10059695,
0x000a5a56,
0x18059655,
0x0006a569,
0x0806a559,
0x000aa556,
0x20056555,
0x0809655a,
0x0009656a,
0x080a5656,
0x10059a55,
0x000a5696,
0x0006a959,
0x000656a9,
0x18059955,
0x080a5596,
0x000a55a6,
0x080655a9,
0x080a5566,
0x10065569,
0x18065559,
0x100a5556,
0x280003ff,
0x100001fc,
0x080001f8,
0x200003fb,
0x000001f0,
0x180003f3,
0x200003f7,
0x080001f4,
0x1000031f,
0x100003e3,
0x180003e7,
0x000001e4,
0x200003ef,
0x080001ec,
0x000001e8,
0x080000be,
0x1800033f,
0x0000013c,
0x100003c7,
0x1000033b,
0x180003cf,
0x000001cc,
0x10000337,
0x0000009e,
0x200003df,
0x080001dc,
0x000001d8,
0x00000271,
0x1000032f,
0x08000279,
0x1000027d,
0x0800007e,
0x2000037f,
0x0800017c,
0x00000178,
0x1800037b,
0x1000038f,
0x10000373,
0x18000377,
0x080000de,
0x1800039f,
0x0000019c,
0x10000367,
0x000000ce,
0x1800036f,
0x00000239,
0x0800023d,
0x0000003e,
0x200003bf,
0x080001bc,
0x000001b8,
0x080000ee,
0x1000034f,
0x000000e6,
0x0000021d,
0x000002e1,
0x1800035f,
0x080000f6,
0x000000f2,
0x080002f1,
0x080000fa,
0x100002f9,
0x180002fd,
0x100000fe,

Wyświetl plik

@ -98,16 +98,16 @@ enc = TMDSEncode()
# (two pairs of dark/light colours. Creates some fairly subtle vertical
# (banding, but it's cheap.
for i in range(1 << 4):
syms = list(enc.encode((0xff if i & 1 << j else 0) ^ j & 0x01, 0, 1) for j in range(4))
print(f"0x{syms[0] | syms[1] << 10:05x}, 0x{syms[2] | syms[3] << 10:05x}")
assert(enc.imbalance == 0)
# for i in range(1 << 4):
# syms = list(enc.encode((0xff if i & 1 << j else 0) ^ j & 0x01, 0, 1) for j in range(4))
# print(f"0x{syms[0] | syms[1] << 10:05x}, 0x{syms[2] | syms[3] << 10:05x}")
# assert(enc.imbalance == 0)
###
# Fullres table stuff:
# def disptable_format(sym):
# return differentialise(sym, 10) | ((popcount(sym) * 2 - 10 & 0x3f) << 26)
# return sym | ((popcount(sym) * 2 - 10 & 0x3f) << 26)
# print("// Non-negative running disparity:")
# for i in range(0, 256, 4):