kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: support both old (non-aligned) and new (aligned) deintelacing, fall back gracefully on CPLDv1
Change-Id: I253666a0fedf4cb84dbc2885d148da9328c12ed2pull/11/head
rodzic
f3a7b47bff
commit
369313fbeb
|
@ -10,8 +10,8 @@
|
|||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const int min;
|
||||
const int max;
|
||||
int min;
|
||||
int max;
|
||||
} param_t;
|
||||
|
||||
// Define a common interface to abstract the calibration code
|
||||
|
|
60
src/defs.h
60
src/defs.h
|
@ -21,42 +21,44 @@
|
|||
|
||||
#define VSYNCINT 16
|
||||
|
||||
// Field State bits (maintained in r3)
|
||||
//
|
||||
// bit 0 indicates mode 7
|
||||
// bit 1 is the buffer being written to
|
||||
// bit 2 is the buffer being displayed
|
||||
// bit 3 is the field type (0 = odd, 1 = even) of the last field
|
||||
// Control bits (maintained in r3)
|
||||
|
||||
#define BIT_MODE7 0x01
|
||||
#define BIT_PROBE 0x02
|
||||
#define BIT_CALIBRATE 0x04
|
||||
#define BIT_NO_DEINT 0x08
|
||||
#define BIT_OSD 0x10
|
||||
#define BIT_INITIALIZE 0x20
|
||||
#define BIT_ELK 0x40
|
||||
#define BIT_SCANLINES 0x80
|
||||
#define BIT_FIELD_TYPE 0x100
|
||||
#define BIT_CLEAR 0x200
|
||||
#define BIT_VSYNC 0x400
|
||||
#define BIT_CAL_COUNT 0x800
|
||||
#define BIT_DEINT_MODE_0 0x100000
|
||||
#define BIT_DEINT_MODE_1 0x200000
|
||||
#define BIT_DEBUG 0x400000
|
||||
|
||||
// Note, due to a hack, bits 16, 19 and 26 are unavailale
|
||||
// as the are used for switch change detection
|
||||
|
||||
#define OFFSET_LAST_BUFFER 12
|
||||
#define OFFSET_CURR_BUFFER 14
|
||||
#define OFFSET_NBUFFERS 17
|
||||
#define OFFSET_INTERLACE 20
|
||||
#define BIT_MODE7 0x01 // bit 0, indicates mode 7
|
||||
#define BIT_PROBE 0x02 // bit 1, indicates the mode is being determined
|
||||
#define BIT_CALIBRATE 0x04 // bit 2, indicates calibration is happening
|
||||
#define BIT_NO_DEINT 0x08 // bit 3, indicates all deinterlacing should be disabled
|
||||
#define BIT_OSD 0x10 // bit 4, indicated the OSD is visible
|
||||
#define BIT_INITIALIZE 0x20 // bit 5, indicates we should sync to an even frame
|
||||
#define BIT_ELK 0x40 // bit 6, indicated we are an Electron
|
||||
#define BIT_SCANLINES 0x80 // bit 7, indicates scan lines should be made visible
|
||||
#define BIT_FIELD_TYPE 0x100 // bit 8, indicates the field type (0 = odd, 1 = even) of the last field
|
||||
#define BIT_CLEAR 0x200 // bit 9, indicates the frame buffer should be cleared
|
||||
#define BIT_VSYNC 0x400 // bit 10, indicates the vsync frequency is being probed
|
||||
#define BIT_CAL_COUNT 0x800 // bit 11, indicates how many fields to capture during calibration (1 or 2)
|
||||
|
||||
#define OFFSET_LAST_BUFFER 12 // bit 12-13 LAST_BUFFER
|
||||
#define MASK_LAST_BUFFER (3 << OFFSET_LAST_BUFFER)
|
||||
|
||||
#define OFFSET_CURR_BUFFER 14 // bit 14-15 CURR_BUFFER
|
||||
#define MASK_CURR_BUFFER (3 << OFFSET_CURR_BUFFER)
|
||||
|
||||
// bit 16 unavailable (used for switch detection)
|
||||
|
||||
#define OFFSET_NBUFFERS 17 // bit 17-18 NBUFFERS
|
||||
#define MASK_NBUFFERS (3 << OFFSET_NBUFFERS)
|
||||
|
||||
// bit 19 unavailable (used for switch detection)
|
||||
|
||||
#define OFFSET_INTERLACE 20 // bit 20-21 INTERFACE
|
||||
#define MASK_INTERLACE (3 << OFFSET_INTERLACE)
|
||||
|
||||
#define BIT_NEW_DEINT 0x400000 // bit 22, indicates the new deinterlace algorithm should be used
|
||||
#define BIT_DEBUG 0x800000 // bit 23, indicated the debug grid should be displayed
|
||||
|
||||
// bit 24-25 unused
|
||||
// bit 26 unavailable (used for switch detection)
|
||||
// bit 27-31 unused
|
||||
|
||||
// R0 return value bits
|
||||
#define RET_SW1 0x02
|
||||
#define RET_SW2 0x04
|
||||
|
|
25
src/osd.c
25
src/osd.c
|
@ -75,15 +75,6 @@ enum {
|
|||
NUM_INFOS
|
||||
};
|
||||
|
||||
enum {
|
||||
DEINTERLACE_NONE,
|
||||
DEINTERLACE_MA1,
|
||||
DEINTERLACE_MA2,
|
||||
DEINTERLACE_MA3,
|
||||
DEINTERLACE_MA4,
|
||||
NUM_DEINTERLACES
|
||||
};
|
||||
|
||||
static const char *info_names[] = {
|
||||
"Firmware Version",
|
||||
"Calibration Summary",
|
||||
|
@ -107,10 +98,14 @@ static const char *pllh_names[] = {
|
|||
|
||||
static const char *deinterlace_names[] = {
|
||||
"None",
|
||||
"Motion Adaptive 1 field",
|
||||
"Motion Adaptive 2 fields",
|
||||
"Motion Adaptive 3 fields",
|
||||
"Motion Adaptive 4 fields",
|
||||
"Motion Adaptive 1",
|
||||
"Motion Adaptive 2",
|
||||
"Motion Adaptive 3",
|
||||
"Motion Adaptive 4",
|
||||
"Aligned Motion Adaptive 1",
|
||||
"Aligned Motion Adaptive 2",
|
||||
"Aligned Motion Adaptive 3",
|
||||
"Aligned Motion Adaptive 4"
|
||||
};
|
||||
|
||||
#ifdef MULTI_BUFFER
|
||||
|
@ -674,6 +669,10 @@ void osd_init() {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Disable CPLDv2 specific features for CPLDv1
|
||||
if (((cpld->get_version() >> VERSION_MAJOR_BIT) & 0x0F) < 2) {
|
||||
features[F_DEINTERLACE].max = DEINTERLACE_MA4;
|
||||
}
|
||||
}
|
||||
|
||||
void osd_update(uint32_t *osd_base, int bytes_per_line) {
|
||||
|
|
13
src/osd.h
13
src/osd.h
|
@ -9,6 +9,19 @@
|
|||
|
||||
extern int clock_error_ppm;
|
||||
|
||||
enum {
|
||||
DEINTERLACE_NONE,
|
||||
DEINTERLACE_MA1,
|
||||
DEINTERLACE_MA2,
|
||||
DEINTERLACE_MA3,
|
||||
DEINTERLACE_MA4,
|
||||
DEINTERLACE_MA1_NEW,
|
||||
DEINTERLACE_MA2_NEW,
|
||||
DEINTERLACE_MA3_NEW,
|
||||
DEINTERLACE_MA4_NEW,
|
||||
NUM_DEINTERLACES
|
||||
};
|
||||
|
||||
void osd_init();
|
||||
void osd_clear();
|
||||
void osd_set(int line, int attr, char *text);
|
||||
|
|
|
@ -317,7 +317,27 @@ process_chars_loop_7\@:
|
|||
tst r3, #(BIT_CALIBRATE | BIT_NO_DEINT)
|
||||
bne skip_deinterlace\@
|
||||
|
||||
tst r3, #BIT_NEW_DEINT // use the new deinterlace algorithm?
|
||||
bne new_deint\@
|
||||
|
||||
// The old deinterlace algorithm only compares odd with odd, and even with even
|
||||
// It will work with CPLD v1 and CPLD v2, as it requires no character alignment
|
||||
tst r1, #0x88000000 // test motion flag in last field (R1 finished with after this)
|
||||
orrne r10, #0x00880000 // set 2nd flag if other field had motion
|
||||
tst r0, #0x88000000
|
||||
orrne r10, #0x00008800 // set 3rd flag as old 1st flag
|
||||
tst r0, #0x00880000
|
||||
orrne r10, #0x00000088 // set 4th flag as old 2nd flag
|
||||
|
||||
eor r0, r0, r10 // compare odd with odd and even with even fields
|
||||
ands r0, r0, r8 // mask out old flag bits
|
||||
orrne r10, #0x88000000 // set 1st flag upper and lower half words if different.
|
||||
|
||||
b completed_word\@
|
||||
|
||||
new_deint\@:
|
||||
// The new deinterlace algorithm requires mode 7 characters to be word-aligned
|
||||
// which will only be the case with the CPLD v2 that has the configurable delay
|
||||
|
||||
tst r1, #0x80000000 // test motion flag in last field
|
||||
orrne r10, #0x00800000 // set 2nd flag if other field had motion upper half word
|
||||
|
|
|
@ -998,10 +998,13 @@ void rgb_to_hdmi_main() {
|
|||
if (osd_active()) {
|
||||
flags |= BIT_OSD;
|
||||
}
|
||||
if (deinterlace == 0) {
|
||||
flags |= BIT_NO_DEINT;
|
||||
if (deinterlace >= DEINTERLACE_MA1 && deinterlace <= DEINTERLACE_MA4) {
|
||||
flags |= (deinterlace - DEINTERLACE_MA1) << OFFSET_INTERLACE;
|
||||
} else if (deinterlace >= DEINTERLACE_MA1_NEW && deinterlace <= DEINTERLACE_MA4_NEW) {
|
||||
flags |= (deinterlace - DEINTERLACE_MA1_NEW) << OFFSET_INTERLACE;
|
||||
flags |= BIT_NEW_DEINT;
|
||||
} else {
|
||||
flags |= (deinterlace - 1) << OFFSET_INTERLACE;
|
||||
flags |= BIT_NO_DEINT;
|
||||
}
|
||||
#ifdef MULTI_BUFFER
|
||||
flags |= nbuffers << OFFSET_NBUFFERS;
|
||||
|
|
Ładowanie…
Reference in New Issue