kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Removed obsolete VSYNC logic from CPLD, pass through CSYNC to ARM
Change-Id: I01c855dfd71e225bafbc5a03841581e9ff5c33cbissue_1022
rodzic
1bf8ebb272
commit
6d0263f280
|
@ -20,16 +20,12 @@
|
|||
#define PIXEL_BASE (2)
|
||||
|
||||
#define PSYNC_PIN (17)
|
||||
#define HSYNC_PIN (18)
|
||||
#define VSYNC_PIN (19)
|
||||
#define FIELD_PIN (20)
|
||||
#define CSYNC_PIN (18)
|
||||
#define GPCLK_PIN (21)
|
||||
|
||||
#define LED_PIN (47)
|
||||
|
||||
#define PSYNC_MASK (1 << PSYNC_PIN)
|
||||
#define HSYNC_MASK (1 << HSYNC_PIN)
|
||||
#define VSYNC_MASK (1 << VSYNC_PIN)
|
||||
#define FIELD_MASK (1 << FIELD_PIN)
|
||||
#define CSYNC_MASK (1 << CSYNC_PIN)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#include "rpi-base.h"
|
||||
#include "defs.h"
|
||||
|
||||
// If LINE_DOUBLE is set, then each line in the field
|
||||
// is written to two adjacent lines. This greatly
|
||||
// improved the look of 50Hz games like Rocket Raid.
|
||||
//
|
||||
// At the moment, this only works with non-interlace
|
||||
// video, as there is a bug in the CPLD that introduces
|
||||
// line jitter with interlaced video.
|
||||
|
||||
// #define LINE_DOUBLE
|
||||
// TODO:
|
||||
// - detection of none-interlaced video and auto line double
|
||||
// - fix slight horizontal offset in the different modes
|
||||
// - somehow autodetect Mode 7
|
||||
// - switch clock and sampling point dynamically betweem modes Modes 0-6 and Mode 7
|
||||
|
||||
.text
|
||||
.global rgb_to_fb
|
||||
|
@ -22,37 +18,28 @@
|
|||
// r3 = unused
|
||||
//
|
||||
|
||||
// Note, in this version we are using HSYNC which is the inverse of CSYNC
|
||||
|
||||
.macro WAIT_FOR_CSYNC_0
|
||||
WAIT_FOR_HSYNC_1
|
||||
wait\@:
|
||||
// Read the GPLEV0
|
||||
ldr r8, [r4]
|
||||
tst r8, #CSYNC_MASK
|
||||
bne wait\@
|
||||
// Check again in case of noise
|
||||
ldr r8, [r4]
|
||||
tst r8, #CSYNC_MASK
|
||||
bne wait\@
|
||||
.endm
|
||||
|
||||
.macro WAIT_FOR_CSYNC_1
|
||||
WAIT_FOR_HSYNC_0
|
||||
.endm
|
||||
|
||||
.macro WAIT_FOR_HSYNC_0
|
||||
wait\@:
|
||||
// Read the GPLEV0
|
||||
ldr r8, [r4]
|
||||
tst r8, #HSYNC_MASK
|
||||
bne wait\@
|
||||
// Check again in case of noise
|
||||
ldr r8, [r4]
|
||||
tst r8, #HSYNC_MASK
|
||||
bne wait\@
|
||||
.endm
|
||||
|
||||
.macro WAIT_FOR_HSYNC_1
|
||||
wait\@:
|
||||
// Read the GPLEV0
|
||||
ldr r8, [r4]
|
||||
tst r8, #HSYNC_MASK
|
||||
tst r8, #CSYNC_MASK
|
||||
beq wait\@
|
||||
// Check again in case of noise
|
||||
ldr r8, [r4]
|
||||
tst r8, #HSYNC_MASK
|
||||
tst r8, #CSYNC_MASK
|
||||
beq wait\@
|
||||
.endm
|
||||
|
||||
|
@ -234,9 +221,6 @@ process_chars_loop:
|
|||
and r9, r8, #(7 << (PIXEL_BASE + 9))
|
||||
orr r10, r10, r9, lsl #13
|
||||
|
||||
#ifdef LINE_DOUBLE
|
||||
str r10, [r12, r2]
|
||||
#endif
|
||||
str r10, [r12], #4
|
||||
|
||||
subs r6, r6, #1
|
||||
|
|
|
@ -204,9 +204,7 @@ void init_hardware() {
|
|||
RPI_SetGpioPinFunction(PIXEL_BASE + i, FS_INPUT);
|
||||
}
|
||||
RPI_SetGpioPinFunction(PSYNC_PIN, FS_INPUT);
|
||||
RPI_SetGpioPinFunction(HSYNC_PIN, FS_INPUT);
|
||||
RPI_SetGpioPinFunction(VSYNC_PIN, FS_INPUT);
|
||||
RPI_SetGpioPinFunction(FIELD_PIN, FS_INPUT);
|
||||
RPI_SetGpioPinFunction(CSYNC_PIN, FS_INPUT);
|
||||
|
||||
// Configure the GPCLK to 64MHz
|
||||
RPI_SetGpioPinFunction(GPCLK_PIN, FS_ALT5);
|
||||
|
|
|
@ -10,7 +10,7 @@ NET "clk" LOC = "P43"; # input
|
|||
NET "R" LOC = "P12"; # input
|
||||
NET "G" LOC = "P13"; # input
|
||||
NET "B" LOC = "P14"; # input
|
||||
NET "nCSYNC" LOC = "P16"; # input
|
||||
NET "S" LOC = "P16"; # input
|
||||
NET "SW" LOC = "P18"; # input
|
||||
|
||||
NET "quad(0)" LOC = "P37"; # output
|
||||
|
@ -26,9 +26,7 @@ NET "quad(9)" LOC = "P29"; # output
|
|||
NET "quad(10)" LOC = "P21"; # output
|
||||
NET "quad(11)" LOC = "P20"; # output
|
||||
NET "psync" LOC = "P33"; # output
|
||||
NET "hsync" LOC = "P32"; # output
|
||||
NET "vsync" LOC = "P19"; # output
|
||||
NET "field" LOC = "P2"; # output
|
||||
NET "csync" LOC = "P32"; # output
|
||||
NET "LED1" LOC = "P39"; # output
|
||||
NET "LED2" LOC = "P38"; # output
|
||||
|
||||
|
@ -45,8 +43,6 @@ NET "quad(9)" SLOW;
|
|||
NET "quad(10)" SLOW;
|
||||
NET "quad(11)" SLOW;
|
||||
NET "psync" SLOW;
|
||||
NET "hsync" SLOW;
|
||||
NET "vsync" SLOW;
|
||||
NET "field" SLOW;
|
||||
NET "csync" SLOW;
|
||||
NET "LED1" SLOW;
|
||||
NET "LED2" SLOW;
|
||||
|
|
|
@ -19,7 +19,7 @@ entity RGBtoHDMI is
|
|||
R: in std_logic;
|
||||
G: in std_logic;
|
||||
B: in std_logic;
|
||||
nCSYNC: in std_logic;
|
||||
S: in std_logic;
|
||||
|
||||
-- From Pi
|
||||
clk: in std_logic;
|
||||
|
@ -27,9 +27,7 @@ entity RGBtoHDMI is
|
|||
-- To PI GPIO
|
||||
quad: out std_logic_vector(11 downto 0);
|
||||
psync: out std_logic;
|
||||
hsync: out std_logic;
|
||||
vsync: out std_logic;
|
||||
field: out std_logic;
|
||||
csync: out std_logic;
|
||||
|
||||
-- Test
|
||||
SW: in std_logic;
|
||||
|
@ -42,14 +40,13 @@ architecture Behavorial of RGBtoHDMI is
|
|||
|
||||
-- For Mode 7
|
||||
-- constant sample_point : unsigned(10 downto 0) := to_unsigned(2048 - 48 * 2 + 3, 11);
|
||||
|
||||
|
||||
-- For Modes 6..0
|
||||
constant sample_point : unsigned(10 downto 0) := to_unsigned(2048 - 32 * 23 + 3, 11);
|
||||
|
||||
signal shift : std_logic_vector(11 downto 0);
|
||||
|
||||
signal nCSYNC1 : std_logic;
|
||||
signal nCSYNC2 : std_logic;
|
||||
signal CSYNC1 : std_logic;
|
||||
|
||||
-- The counter runs at 4x pixel clock
|
||||
--
|
||||
|
@ -75,9 +72,9 @@ architecture Behavorial of RGBtoHDMI is
|
|||
|
||||
begin
|
||||
|
||||
process(nCSYNC)
|
||||
process(S)
|
||||
begin
|
||||
if rising_edge(nCSYNC) then
|
||||
if rising_edge(S) then
|
||||
led_counter <= led_counter + 1;
|
||||
end if;
|
||||
end process;
|
||||
|
@ -85,40 +82,14 @@ begin
|
|||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-- synchronize nCSYNC to the sampling clock
|
||||
nCSYNC1 <= nCSYNC;
|
||||
nCSYNC2 <= nCSYNC1;
|
||||
-- synchronize CSYNC to the sampling clock
|
||||
CSYNC1 <= S;
|
||||
|
||||
if nCSYNC1 = '0' and nCSYNC2 = '1' then
|
||||
-- start of horizontal line sync pulse
|
||||
hsync <= '1';
|
||||
if CSYNC1 = '0' then
|
||||
-- in the line sync
|
||||
psync <= '0';
|
||||
-- counter is used to measure how long the pulse is
|
||||
counter <= to_unsigned(0, counter'length);
|
||||
|
||||
elsif nCSYNC1 = '1' and nCSYNC2 = '0' then
|
||||
-- end of horizontal line sync pulse
|
||||
hsync <= '0';
|
||||
|
||||
-- test for vertical sync
|
||||
-- a normal line sync pulse is 4us
|
||||
-- a saturated counter (512 == 8us) value can only happen during vsync
|
||||
if counter = 512 then
|
||||
vsync <= '1';
|
||||
else
|
||||
vsync <= '0';
|
||||
end if;
|
||||
|
||||
-- counter is used to find sampling point for first pixel
|
||||
counter <= sample_point;
|
||||
|
||||
elsif nCSYNC1 = '0' then
|
||||
-- within the line sync pulse
|
||||
-- saturate counter at 8us.
|
||||
if counter < 512 then
|
||||
counter <= counter + 1;
|
||||
end if;
|
||||
|
||||
else
|
||||
-- within the line
|
||||
if counter = 31 then
|
||||
|
@ -142,8 +113,8 @@ begin
|
|||
end if;
|
||||
end process;
|
||||
|
||||
field <= '1';
|
||||
|
||||
csync <= CSYNC1;
|
||||
|
||||
LED1 <= not SW;
|
||||
|
||||
LED2 <= led_counter(led_counter'left);
|
||||
|
|
Ładowanie…
Reference in New Issue