First attempt at vertical genlock

pull/12/head
IanSB 2018-11-29 04:49:12 +00:00
rodzic f8c3da4360
commit ff36d8fd5a
5 zmienionych plików z 93 dodań i 8 usunięć

Wyświetl plik

@ -104,7 +104,8 @@ enum {
F_NBUFFERS, F_NBUFFERS,
#endif #endif
F_M7DISABLE, F_M7DISABLE,
F_DEBUG F_DEBUG,
F_VLOCK
}; };
static param_t features[] = { static param_t features[] = {
@ -120,6 +121,7 @@ static param_t features[] = {
#endif #endif
{ F_M7DISABLE, "Mode7 Disable", 0, 1, 1 }, { F_M7DISABLE, "Mode7 Disable", 0, 1, 1 },
{ F_DEBUG, "Debug", 0, 1, 1 }, { F_DEBUG, "Debug", 0, 1, 1 },
{ F_VLOCK, "Vertical Lock", 1, 100, 1 },
{ -1, NULL, 0, 0, 0 }, { -1, NULL, 0, 0, 0 },
}; };
@ -203,6 +205,7 @@ static param_menu_item_t nbuffers_ref = { I_FEATURE, &features[F_NBUFFERS]
#endif #endif
static param_menu_item_t m7disable_ref = { I_FEATURE, &features[F_M7DISABLE] }; static param_menu_item_t m7disable_ref = { I_FEATURE, &features[F_M7DISABLE] };
static param_menu_item_t debug_ref = { I_FEATURE, &features[F_DEBUG] }; static param_menu_item_t debug_ref = { I_FEATURE, &features[F_DEBUG] };
static param_menu_item_t vlock_ref = { I_FEATURE, &features[F_VLOCK] };
static menu_t processing_menu = { static menu_t processing_menu = {
"Processing Menu", "Processing Menu",
@ -215,7 +218,6 @@ static menu_t processing_menu = {
} }
}; };
static menu_t settings_menu = { static menu_t settings_menu = {
"Settings Menu", "Settings Menu",
{ {
@ -227,6 +229,7 @@ static menu_t settings_menu = {
(base_menu_item_t *) &vsync_ref, (base_menu_item_t *) &vsync_ref,
(base_menu_item_t *) &pllh_ref, (base_menu_item_t *) &pllh_ref,
(base_menu_item_t *) &nbuffers_ref, (base_menu_item_t *) &nbuffers_ref,
(base_menu_item_t *) &vlock_ref,
NULL NULL
} }
}; };
@ -416,6 +419,8 @@ static int get_feature(int num) {
return get_debug(); return get_debug();
case F_M7DISABLE: case F_M7DISABLE:
return get_m7disable(); return get_m7disable();
case F_VLOCK:
return get_vlockline();
} }
return -1; return -1;
} }
@ -457,6 +462,9 @@ static void set_feature(int num, int value) {
case F_M7DISABLE: case F_M7DISABLE:
set_m7disable(value); set_m7disable(value);
break; break;
case F_VLOCK:
set_vlockline(value);
break;
} }
} }

Wyświetl plik

@ -82,6 +82,8 @@ void set_vsync(int on);
int get_vsync(); int get_vsync();
void set_pllh(int val); void set_pllh(int val);
int get_pllh(); int get_pllh();
void set_vlockline(int val);
int get_vlockline();
#ifdef MULTI_BUFFER #ifdef MULTI_BUFFER
void set_nbuffers(int val); void set_nbuffers(int val);
int get_nbuffers(); int get_nbuffers();

Wyświetl plik

@ -11,6 +11,8 @@
.global sw1counter .global sw1counter
.global sw2counter .global sw2counter
.global sw3counter .global sw3counter
.global vsync_line
// ====================================================================== // ======================================================================
// Macros // Macros
@ -59,6 +61,7 @@
CLEAR_VSYNC CLEAR_VSYNC
// Mark the next line in red // Mark the next line in red
orr r3, r3, #BIT_VSYNC_MARKER orr r3, r3, #BIT_VSYNC_MARKER
str r5, vsync_line
novsync\@: novsync\@:
.endm .endm
@ -456,6 +459,10 @@ skip_osd_update:
FLIP_BUFFER FLIP_BUFFER
#endif #endif
push {r0-r12, lr}
bl recalculate_hdmi_clock_line_locked_update
pop {r0-r12, lr}
// Loop back if required number of fields has not been reached // Loop back if required number of fields has not been reached
// or if negative (capture forever) // or if negative (capture forever)
ldr r5, param_ncapture ldr r5, param_ncapture
@ -674,3 +681,9 @@ param_capture_line:
linecountmod10: linecountmod10:
.word 0 .word 0
vsync_line:
.word 0

Wyświetl plik

@ -25,4 +25,8 @@ extern int capture_line_default_8bpp();
extern int capture_line_mode7_4bpp(); extern int capture_line_mode7_4bpp();
extern int vsync_line;
void recalculate_hdmi_clock_line_locked_update();
#endif #endif

Wyświetl plik

@ -67,6 +67,7 @@ static int clear;
static volatile int delay; static volatile int delay;
static double pllh_clock = 0; static double pllh_clock = 0;
// ============================================================= // =============================================================
// OSD parameters // OSD parameters
// ============================================================= // =============================================================
@ -79,10 +80,13 @@ static int scanlines = 0;
static int deinterlace = 0; static int deinterlace = 0;
static int vsync = 0; static int vsync = 0;
static int pllh = 0; static int pllh = 0;
static int vlockline = 40;
#ifdef MULTI_BUFFER #ifdef MULTI_BUFFER
static int nbuffers = 0; static int nbuffers = 0;
#endif #endif
static int current_pllh = 0xffffffff;
// Calculated so that the constants from librpitx work // Calculated so that the constants from librpitx work
static volatile uint32_t *gpioreg = (volatile uint32_t *)(PERIPHERAL_BASE + 0x101000UL); static volatile uint32_t *gpioreg = (volatile uint32_t *)(PERIPHERAL_BASE + 0x101000UL);
@ -359,7 +363,9 @@ static int calibrate_sampling_clock() {
return a; return a;
} }
static void recalculate_hdmi_clock() {
static void recalculate_hdmi_clock(int pllh) { // use local pllh, not global
// The very first time we get called, vsync_time_ns has not been set // The very first time we get called, vsync_time_ns has not been set
// so exit gracefully // so exit gracefully
@ -468,6 +474,50 @@ static void recalculate_hdmi_clock() {
gpioreg[PLLH_STS]); gpioreg[PLLH_STS]);
} }
static void recalculate_hdmi_clock_once(int pllh) {
if (current_pllh != pllh){
current_pllh = pllh;
recalculate_hdmi_clock(pllh);
}
}
void recalculate_hdmi_clock_line_locked_update() {
if (pllh != HDMI_EXACT) {
recalculate_hdmi_clock_once(pllh);
}
else {
signed int difference = 0;
if (vsync_line > (capinfo->height/4))
difference = vsync_line - vlockline - capinfo->height/2;
else
difference = vsync_line - vlockline;
if (abs(difference) > 1) {
if (difference >=0) {
if (difference < 20)
recalculate_hdmi_clock_once(HDMI_SLOW_1000PPM);
else
recalculate_hdmi_clock_once(HDMI_SLOW_2000PPM);
}
else {
if (difference > -20)
recalculate_hdmi_clock_once(HDMI_FAST_1000PPM);
else
recalculate_hdmi_clock_once(HDMI_FAST_2000PPM);
}
}
else
recalculate_hdmi_clock_once(HDMI_EXACT);
}
}
static void init_hardware() { static void init_hardware() {
int i; int i;
for (i = 0; i < 12; i++) { for (i = 0; i < 12; i++) {
@ -1012,7 +1062,15 @@ int get_m7disable() {
return m7disable; return m7disable;
} }
void set_vsync(int on) { void set_vlockline(int val) {
vlockline = val;
}
int get_vlockline() {
return vlockline;
}
void set_vsync(int on) {
vsync = on; vsync = on;
} }
@ -1026,7 +1084,7 @@ int get_pllh() {
void set_pllh(int val) { void set_pllh(int val) {
pllh = val; pllh = val;
recalculate_hdmi_clock(); recalculate_hdmi_clock_line_locked_update();
} }
void set_scanlines(int on) { void set_scanlines(int on) {
@ -1136,7 +1194,7 @@ void rgb_to_hdmi_main() {
calibrate_sampling_clock(); calibrate_sampling_clock();
// Recalculate the HDMI clock (if the pllh property requires this) // Recalculate the HDMI clock (if the pllh property requires this)
recalculate_hdmi_clock(); recalculate_hdmi_clock_line_locked_update();
clear = BIT_CLEAR; clear = BIT_CLEAR;