kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Extended clock calibration to correctly handle 624-line non-interlaced modes
Change-Id: I6aaf957512e0f9d77df89d835f8cf40b4d801506issue_1022
rodzic
4cf99c2a91
commit
127c804a5e
|
@ -30,4 +30,6 @@
|
|||
#define CSYNC_MASK (1 << CSYNC_PIN)
|
||||
#define MODE7_MASK (1 << MODE7_PIN)
|
||||
|
||||
#define INTERLACED_FLAG (1 << 31)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#include "rpi-base.h"
|
||||
#include "defs.h"
|
||||
|
||||
// TODO:
|
||||
// - calibration gives incorrect result in non-interlaced modes
|
||||
|
||||
.text
|
||||
.global rgb_to_fb
|
||||
.global measure_vsync
|
||||
|
@ -307,26 +304,42 @@ measure_vsync:
|
|||
// Initialize the cycle counter, and set r4=GPLEV0
|
||||
bl init_timer_and_io
|
||||
|
||||
// wait for vsync, r6 contains the time of the subsequenct hsync rising edge
|
||||
// wait for vsync, r6 contains the time of the subsequent hsync rising edge
|
||||
bl wait_for_vsync
|
||||
mov r0, r6
|
||||
|
||||
// Wait for a complete frame
|
||||
// Wait for a first field of frame
|
||||
bl wait_for_vsync
|
||||
|
||||
// Record field type
|
||||
sub r6, r6, r7
|
||||
cmp r6, #32768
|
||||
movlt r3, #0 // Odd
|
||||
movge r3, #1 // Even
|
||||
|
||||
// Wait for a second field of frame
|
||||
bl wait_for_vsync
|
||||
|
||||
// Return the time for a complete frame (should be 40ms)
|
||||
sub r0, r6, r0
|
||||
|
||||
// Test for non-interlaced by looking for two successive fields of the same type
|
||||
sub r6, r6, r7
|
||||
cmp r6, #32768
|
||||
eorlt r3, r3, #1 // Odd
|
||||
tst r3, #1
|
||||
// Set bit 31 of result if frame was interlaced
|
||||
orreq r0, r0, #INTERLACED_FLAG
|
||||
|
||||
pop {r4-r12, lr}
|
||||
mov pc, lr
|
||||
|
||||
clear_screen:
|
||||
mov r11, r0 // r0 is the start of the frame buffer
|
||||
mov r11, r0 // r0 is the start of the frame buffer
|
||||
mov r7, #0
|
||||
mov r5, #512 // fixed 512 lines
|
||||
mov r5, #512 // fixed 512 lines
|
||||
clear_loop1:
|
||||
mov r6, r2 // r2 is bytes per line
|
||||
mov r6, r2 // r2 is bytes per line
|
||||
clear_loop2:
|
||||
str r7, [r11], #4
|
||||
subs r6, r6, #4
|
||||
|
|
|
@ -199,16 +199,28 @@ int delay;
|
|||
|
||||
int calibrate_clock() {
|
||||
int a = 13;
|
||||
log_info("Nominal clock = %d", CORE_FREQ);
|
||||
unsigned int frame_ref;
|
||||
|
||||
int frame_time = measure_vsync();
|
||||
log_info(" Frame time = %dns", frame_time);
|
||||
log_info(" Nominal clock = %d Hz", CORE_FREQ);
|
||||
|
||||
double error = (double) frame_time / (double) 40000000;
|
||||
log_info(" Frame error = %d PPM", (int) ((error - 1.0) * 1e6));
|
||||
unsigned int frame_time = measure_vsync();
|
||||
|
||||
if (frame_time & INTERLACED_FLAG) {
|
||||
frame_ref = 40000000;
|
||||
log_info("Nominal frame time = %d ns (interlaced)", frame_ref);
|
||||
} else {
|
||||
frame_ref = 40000000 - 64000;
|
||||
log_info("Nominal frame time = %d ns (non-interlaced)", frame_ref);
|
||||
}
|
||||
frame_time &= ~INTERLACED_FLAG;
|
||||
|
||||
log_info(" Actual frame time = %d ns", frame_time);
|
||||
|
||||
double error = (double) frame_time / (double) frame_ref;
|
||||
log_info(" Frame time error = %d PPM", (int) ((error - 1.0) * 1e6));
|
||||
|
||||
int new_clock = (int) (((double) CORE_FREQ) / error);
|
||||
log_info(" Ideal clock = %d", new_clock);
|
||||
log_info(" Optimal clock = %d Hz", new_clock);
|
||||
|
||||
// Sanity check clock
|
||||
if (new_clock < 380000000 || new_clock > 388000000) {
|
||||
|
@ -231,7 +243,7 @@ int calibrate_clock() {
|
|||
|
||||
// Check the new clock
|
||||
int actual_clock = get_clock_rate(CORE_CLK_ID);
|
||||
log_info(" New clock = %d", actual_clock);
|
||||
log_info(" Final clock = %d Hz", actual_clock);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue