Pi Firmware: implemented h_width and v_height

Change-Id: I15bd6f1ec62a645643275bee2bf6dbd5d54dc1dc
pull/11/head
David Banks 2018-11-11 18:06:55 +00:00
rodzic cb5a8461b6
commit 1fa198a423
5 zmienionych plików z 84 dodań i 59 usunięć

Wyświetl plik

@ -27,7 +27,7 @@ typedef struct {
int (*get_value)(int num);
void (*set_value)(int num, int value);
// Support for filling in framebuffer params
int (*get_fb_params)(capture_info_t *capinfo);
void (*get_fb_params)(capture_info_t *capinfo);
// Support for info page
void (*show_cal_summary)(int line);
void (*show_cal_details)(int line);

Wyświetl plik

@ -307,12 +307,13 @@ static void cpld_set_mode(int mode) {
write_config(config);
}
static int cpld_get_fb_params(capture_info_t *capinfo) {
capinfo->h_offset = 0;
capinfo->v_offset = 21;
capinfo->width = mode7 ? 504 : 672;
capinfo->height = 540;
return 0;
static void cpld_get_fb_params(capture_info_t *capinfo) {
capinfo->h_offset = 0;
capinfo->v_offset = 21;
capinfo->chars_per_line = mode7 ? 63 : 83;
capinfo->nlines = 270;
capinfo->width = mode7 ? 504 : 672;
capinfo->height = 540;
}
static param_t *cpld_get_params() {

Wyświetl plik

@ -16,10 +16,12 @@ typedef struct {
int sp_offset[NUM_OFFSETS];
int half_px_delay; // 0 = off, 1 = on, all modes
int full_px_delay; // 0..15, mode 7 only
int h_offset; // horizontal offset (in psync clocks)
int v_offset; // vertical offset (in lines)
int fb_width; // framebuffer width in pixels
int fb_height; // framebuffer height in pixels
int h_offset; // horizontal offset (in psync clocks)
int v_offset; // vertical offset (in lines)
int h_width; // active horizontal width (in 8-bit characters)
int v_height; // active vertical height (in lines)
int fb_width; // framebuffer width in pixels
int fb_height; // framebuffer height in pixels
} config_t;
// Current calibration state for mode 0..6
@ -74,6 +76,8 @@ enum {
HALF,
H_OFFSET,
V_OFFSET,
H_WIDTH,
V_HEIGHT,
FB_WIDTH,
FB_HEIGHT,
DELAY
@ -90,8 +94,10 @@ static param_t default_params[] = {
{ "Half", 0, 1 },
{ "H offset", 0, 59 },
{ "V offset", 0, 39 },
{ "H width", 50, 99 },
{ "V height", 150, 300 },
{ "FB width", 400, 800 },
{ "FB height", 540, 540 },
{ "FB height", 480, 600 },
{ "Delay", 0, 15 },
{ NULL, 0, 0 },
};
@ -107,8 +113,10 @@ static param_t mode7_params[] = {
{ "Half", 0, 1 },
{ "H offset", 0, 39 },
{ "V offset", 0, 39 },
{ "H width", 50, 99 },
{ "V height", 150, 300 },
{ "FB width", 400, 800 },
{ "FB height", 540, 540 },
{ "FB height", 480, 600 },
{ "Delay", 0, 15 },
{ NULL, 0, 0 },
};
@ -207,12 +215,20 @@ static void log_sp(config_t *config) {
static void cpld_init(int version) {
cpld_version = version;
// Setup default frame buffer params
mode7_config.h_offset = 24;
mode7_config.v_offset = 21;
//
// Nominal width should be 640x512 or 480x504, but making this a bit larger deals with two problems:
// 1. Slight differences in the horizontal placement in the different screen modes
// 2. Slight differences in the vertical placement due to *TV settings
mode7_config.h_offset = 24;
mode7_config.v_offset = 21;
mode7_config.h_width = 63;
mode7_config.v_height = 270;
mode7_config.fb_width = 504;
mode7_config.fb_height = 540;
default_config.h_offset = 32;
default_config.v_offset = 21;
default_config.h_offset = 32;
default_config.v_offset = 21;
default_config.h_width = 83;
default_config.v_height = 270;
default_config.fb_width = 672;
default_config.fb_height = 540;
// Version 2 CPLD supports the delay parameter, and starts sampling earlier
@ -402,14 +418,13 @@ static void cpld_set_mode(int mode) {
write_config(config);
}
static int cpld_get_fb_params(capture_info_t *capinfo) {
int old_fb_width = capinfo->width;
int old_fb_height = capinfo->height;
capinfo->h_offset = config->h_offset;
capinfo->v_offset = config->v_offset;
capinfo->width = config->fb_width;
capinfo->height = config->fb_height;
return (old_fb_width != config->fb_width) || (old_fb_height != config->fb_height);
static void cpld_get_fb_params(capture_info_t *capinfo) {
capinfo->h_offset = config->h_offset;
capinfo->v_offset = config->v_offset;
capinfo->chars_per_line = config->h_width;
capinfo->nlines = config->v_height;
capinfo->width = config->fb_width;
capinfo->height = config->fb_height;
}
static param_t *cpld_get_params() {
@ -442,6 +457,10 @@ static int cpld_get_value(int num) {
return config->h_offset;
case V_OFFSET:
return config->v_offset;
case H_WIDTH:
return config->h_width;
case V_HEIGHT:
return config->v_height;
case FB_WIDTH:
return config->fb_width;
case FB_HEIGHT:
@ -489,6 +508,12 @@ static void cpld_set_value(int num, int value) {
case V_OFFSET:
config->v_offset = value;
break;
case H_WIDTH:
config->h_width = value;
break;
case V_HEIGHT:
config->v_height = value;
break;
case FB_WIDTH:
config->fb_width = value;
break;

Wyświetl plik

@ -642,9 +642,23 @@ rgb_to_fb:
ldr r2, [r0, #O_FB_BASE]
str r2, param_framebuffer0
// Sanity check chars_per_line <= fb_width / 8
ldr r2, param_chars_per_line
ldr r3, param_fb_width
lsr r3, r3, #3
cmp r2, r3
strgt r3, param_chars_per_line
// Sanity check nlines <= fb_height / 2
ldr r2, param_nlines
ldr r3, param_fb_height
lsr r3, r3, #1
cmp r2, r3
strgt r3, param_nlines
#ifdef MULTI_BUFFER
// Calculate the base address of each of the 4 frame buffers
// Calculate the base address of each of the 4 frame buffers
ldr r2, param_framebuffer0
ldr r10, param_fb_height
ldr r11, param_fb_pitch
mul r10, r10, r11
@ -667,13 +681,13 @@ skip_swap:
ldr r4, =GPLEV0
// Setup r3 with the flags/options parameter (as per before)
mov r3, r1
mov r3, r1
// Setup r2 with the framebuffer pitch (as per before)
ldr r2, param_fb_pitch
ldr r2, param_fb_pitch
// Setup r2 with the number of active characters per line (as per before)
ldr r1, param_chars_per_line
ldr r1, param_chars_per_line
tst r3, #BIT_CLEAR
blne clear_screen

Wyświetl plik

@ -962,37 +962,13 @@ void rgb_to_hdmi_main() {
int result;
int last_mode7;
int size_changed;
int fb_size_changed;
int active_size_changed;
capture_info_t last_capinfo;
capinfo = &default_capinfo;
// Define the size of the Pi Framebuffer
//
// Nominal width should be 640x512 or 480x504, but making this a bit larger deals with two problems:
// 1. Slight differences in the horizontal placement in the different screen modes
// 2. Slight differences in the vertical placement due to *TV settings
// Setup the default capture info values
default_capinfo.fb = NULL; // filled in by init_framebuffer
default_capinfo.pitch = 0; // filled in by init_framebuffer
default_capinfo.width = 672;
default_capinfo.height = 540;
default_capinfo.chars_per_line = 83;
default_capinfo.nlines = 270;
default_capinfo.h_offset = 0; // for compatibility with CPLDv1
default_capinfo.v_offset = 21;
// Setup the mode7 capture info values
mode7_capinfo.fb = NULL; // filled in by init_framebuffer
mode7_capinfo.pitch = 0; // filled in by init_framebuffer
mode7_capinfo.width = 504;
mode7_capinfo.height = 540;
mode7_capinfo.chars_per_line = 63;
mode7_capinfo.nlines = 270;
mode7_capinfo.h_offset = 0; // for compatibility with CPLDv1
mode7_capinfo.v_offset = 21;
// Initialize the cpld after the gpclk generator has been started
cpld_init();
@ -1068,12 +1044,21 @@ void rgb_to_hdmi_main() {
}
// Possibly the size or offset has been adjusted, so update these
size_changed = cpld->get_fb_params(capinfo);
memcpy(&last_capinfo, capinfo, sizeof last_capinfo);
cpld->get_fb_params(capinfo);
fb_size_changed = (capinfo->width != last_capinfo.width) || (capinfo->height != last_capinfo.height);
active_size_changed = (capinfo->chars_per_line != last_capinfo.chars_per_line) || (capinfo->nlines != last_capinfo.nlines);
last_mode7 = mode7;
mode7 = result & BIT_MODE7;
} while (mode7 == last_mode7 && !size_changed);
if (active_size_changed) {
clear = BIT_CLEAR;
}
} while (mode7 == last_mode7 && !fb_size_changed);
osd_clear();
}