kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
First attempt at vertical genlock
rodzic
f8c3da4360
commit
ff36d8fd5a
12
src/osd.c
12
src/osd.c
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue