Implemented vsync

Change-Id: I35d7dc7a0184e147faa64fadf038752e7df467b9
issue_1022
David Banks 2017-04-25 11:53:22 +01:00
rodzic 29d99e7110
commit cf17594877
2 zmienionych plików z 94 dodań i 53 usunięć

Wyświetl plik

@ -1,33 +1,68 @@
#include "rpi-base.h"
#include "defs.h"
.text
.global rgb_to_fb
// r0 = pointer to frame buffer
// r1
// r2
// r3
// r3 = field offset
// r4 = GPLEV0
// r5 = line counter
// r6 = pixel counter
// r8 = value read from GPLEV0
// r9 = extracted pixel
// r10 = block of 8 pixels, to be written to FB
// r10 = block of 8 pixels, to be written to FB
rgb_to_fb:
push {r4-r12, lr}
push {r4-r12, lr}
mov r3, #0
ldr r4, =GPLEV0
frame:
// Update field offset to alternate field
eor r3, r3, #320
// Set framebuffer address
add r1, r0, r3
// Wait for start of vsync
wait_for_vsync_a:
ldr r8, [r4]
tst r8, #VSYNC_MASK
beq wait_for_vsync_a
// Wait for end of vsync
wait_for_vsync_b:
ldr r8, [r4]
tst r8, #VSYNC_MASK
bne wait_for_vsync_b
// Skip inactive lines
mov r5, #28
loop0:
mov r1, r0
ldr r4, =GPLEV0
mov r5, #256
loop1:
wait_for_hsync_a:
ldr r8, [r4]
tst r8, #HSYNC_MASK
beq wait_for_hsync_a
wait_for_hsync_b:
ldr r8, [r4]
tst r8, #HSYNC_MASK
bne wait_for_hsync_b
subs r5, r5, #1
bne loop0
// Process active lines
mov r5, #256
loop1:
// Wait for active high hsync
wait_for_hsync:
ldr r8, [r4]
@ -40,7 +75,7 @@ loop2:
// Initialize 8 pixel block
mov r10, #0
// Wait for 0-1 edge on PSYNC
wait_psync_01:
ldr r8, [r4]
@ -51,10 +86,10 @@ wait_psync_01:
// Pixel 1 in GPIO 7.. 5 -> 3.. 0
// Pixel 2 in GPIO 10.. 8 -> 15..12
// Pixel 3 in GPIO 13..11 -> 11.. 8
and r9, r8, #(7 << PIXEL_BASE)
orr r10, r10, r9, lsl #2
and r9, r8, #(7 << (PIXEL_BASE + 3))
orr r10, r10, r9, lsr #5
@ -74,10 +109,10 @@ wait_psync_10:
// Pixel 5 in GPIO 7.. 5 -> 19..16
// Pixel 6 in GPIO 10.. 8 -> 31..28
// Pixel 7 in GPIO 13..11 -> 27..24
and r9, r8, #(7 << PIXEL_BASE)
orr r10, r10, r9, lsl #18
and r9, r8, #(7 << (PIXEL_BASE + 3))
orr r10, r10, r9, lsl #11
@ -87,43 +122,21 @@ wait_psync_10:
and r9, r8, #(7 << (PIXEL_BASE + 9))
orr r10, r10, r9, lsl #13
str r10, [r1], #4
subs r6, r6, #1
bne loop2
// Skip a whole line
subs r6, r6, #1
bne loop2
// Skip a whole line to maintain aspect ratio
add r1, r1, #320
subs r5, r5, #1
bne loop1
subs r5, r5, #1
bne loop1
b frame
// Temporary hack - skip inactive lines
ldr r5, =(312-256)
loop3:
wait_for_hsync_a:
ldr r8, [r4]
tst r8, #HSYNC_MASK
beq wait_for_hsync_a
// Return
wait_for_hsync_b:
ldr r8, [r4]
tst r8, #HSYNC_MASK
bne wait_for_hsync_b
pop {r4-r12, lr}
mov pc, lr
subs r5, r5, #1
bne loop3
b loop0
// Return
pop {r4-r12, lr}
mov pc, lr

Wyświetl plik

@ -43,6 +43,7 @@ architecture Behavorial of RGBtoHDMI is
signal shift : std_logic_vector(11 downto 0);
signal nCSYNC1 : std_logic;
signal nCSYNC2 : std_logic;
-- The counter runs at 4x pixel clock
--
@ -80,15 +81,40 @@ begin
if rising_edge(clk) then
-- synchronize nCSYNC to the sampling clock
nCSYNC1 <= nCSYNC;
nCSYNC2 <= nCSYNC1;
if nCSYNC1 = '0' then
-- within horizontal line sync pulse
if nCSYNC1 = '0' and nCSYNC2 = '1' then
-- start of horizontal line sync pulse
hsync <= '1';
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 <= to_unsigned(1311, counter'length);
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
hsync <= '0';
if counter = 31 then
counter <= to_unsigned(0, counter'length);
else
@ -110,6 +136,8 @@ begin
end if;
end process;
field <= '1';
LED1 <= not SW;
LED2 <= led_counter(led_counter'left);