kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Early work on Mode 7
Change-Id: I0cea302fd7ea9ea8cb3649721185c2351b7084dcissue_1022
rodzic
b9fc578bff
commit
4335d4e531
|
@ -14,31 +14,38 @@
|
|||
.text
|
||||
.global rgb_to_fb
|
||||
|
||||
// r0 = pointer to frame buffer
|
||||
// r1
|
||||
// r2
|
||||
// r3 = field offset
|
||||
// Parameter registers:
|
||||
//
|
||||
// r0 = frame buffer base
|
||||
// r1 = 8-pixel characters per line (normally 80, but 62.5 (63) in Mode 7
|
||||
// r2 = bytes per line
|
||||
//
|
||||
// Working registers:
|
||||
//
|
||||
// r3 = field offsset
|
||||
// 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
|
||||
|
||||
// r11 = pointer into frame buffer (start of line)
|
||||
// r12 = pointer into frame buffer (moves within line)
|
||||
|
||||
rgb_to_fb:
|
||||
|
||||
push {r4-r12, lr}
|
||||
|
||||
mov r3, #320
|
||||
mov r3, r2
|
||||
ldr r4, =GPLEV0
|
||||
|
||||
frame:
|
||||
// Set framebuffer address
|
||||
#ifdef LINE_DOUBLE
|
||||
mov r1, r0
|
||||
mov r11, r0
|
||||
#else
|
||||
add r1, r0, r3
|
||||
eor r3, r3, #320
|
||||
add r11, r0, r3
|
||||
eor r3, r3, r2
|
||||
#endif
|
||||
|
||||
// Wait for start of vsync
|
||||
|
@ -97,8 +104,10 @@ wait_for_hsync:
|
|||
tst r8, #HSYNC_MASK
|
||||
beq wait_for_hsync
|
||||
|
||||
// 80 8-bit characters per line
|
||||
mov r6, #80
|
||||
// number of 8-bit characters per line
|
||||
mov r6, r1
|
||||
// pointer into frame buffer
|
||||
mov r12, r11
|
||||
loop2:
|
||||
|
||||
// Initialize 8 pixel block
|
||||
|
@ -157,15 +166,15 @@ wait_psync_10:
|
|||
orr r10, r10, r9, lsl #13
|
||||
|
||||
#ifdef LINE_DOUBLE
|
||||
str r10, [r1, r3]
|
||||
str r10, [r12, r2]
|
||||
#endif
|
||||
str r10, [r1], #4
|
||||
str r10, [r12], #4
|
||||
|
||||
subs r6, r6, #1
|
||||
bne loop2
|
||||
|
||||
// Skip a whole line to maintain aspect ratio
|
||||
add r1, r1, #320
|
||||
add r11, r11, r2, lsl #1
|
||||
|
||||
subs r5, r5, #1
|
||||
bne loop1
|
||||
|
|
|
@ -11,6 +11,20 @@
|
|||
#include "rpi-mailbox-interface.h"
|
||||
#include "startup.h"
|
||||
|
||||
#define CORE_FREQ 383900000
|
||||
|
||||
// #define MODE7
|
||||
|
||||
#ifdef MODE7
|
||||
#define GPCLK_DIVISOR 24 // 48MHz
|
||||
#define CHARS_PER_LINE 63
|
||||
#define BYTES_PER_LINE 320
|
||||
#else
|
||||
#define GPCLK_DIVISOR 18 // 64MHz
|
||||
#define CHARS_PER_LINE 80
|
||||
#define BYTES_PER_LINE 320
|
||||
#endif
|
||||
|
||||
#define GZ_CLK_BUSY (1 << 7)
|
||||
|
||||
#define GP_CLK1_CTL (uint32_t *)(PERIPHERAL_BASE + 0x101078)
|
||||
|
@ -41,23 +55,26 @@
|
|||
#define COLBITS 4
|
||||
#endif
|
||||
|
||||
extern void rgb_to_fb(unsigned char *fb);
|
||||
extern void rgb_to_fb(unsigned char *fb, int chars_per_line, int bytes_per_line);
|
||||
|
||||
|
||||
void init_gpclk(int source, int divisor) {
|
||||
|
||||
|
||||
RPI_PropertyInit();
|
||||
RPI_PropertyAddTag( TAG_SET_CLOCK_RATE, CORE_CLK_ID, 383900000, 1);
|
||||
RPI_PropertyAddTag( TAG_SET_CLOCK_RATE, CORE_CLK_ID, CORE_FREQ, 1);
|
||||
RPI_PropertyProcess();
|
||||
|
||||
// Re-initialize UART, as system clock rate changed
|
||||
RPI_AuxMiniUartInit( 115200, 8 );
|
||||
|
||||
log_info("GP_CLK1_CTL = %08"PRIx32, *GP_CLK1_CTL);
|
||||
log_info("GP_CLK1_DIV = %08"PRIx32, *GP_CLK1_DIV);
|
||||
|
||||
*GP_CLK1_CTL = 0x5A000000 + source;
|
||||
|
||||
while ((*GP_CLK1_CTL) & GZ_CLK_BUSY) {} // Wait for BUSY low
|
||||
*GP_CLK1_DIV = 0x5A002000 | (divisor << 12); // set DIVI
|
||||
*GP_CLK1_DIV = 0x5A000000 | (divisor << 12); // set DIVI
|
||||
*GP_CLK1_CTL = 0x5A000010 | source; // GPCLK0 on
|
||||
|
||||
log_info("GP_CLK1_CTL = %08"PRIx32, *GP_CLK1_CTL);
|
||||
|
@ -208,10 +225,10 @@ void init_hardware() {
|
|||
|
||||
// Source 1 = OSC = 19.2MHz
|
||||
// Source 4 = PLLA = 0MHz
|
||||
// Source 5 = PLLC = core_freq * 3 (
|
||||
// Source 5 = PLLC = core_freq * 3 = (384 * 3) = 1152
|
||||
// Source 6 = PLLD = 500MHz
|
||||
|
||||
init_gpclk(5, 18);
|
||||
init_gpclk(5, GPCLK_DIVISOR);
|
||||
|
||||
|
||||
// Initialise the info system with cached values (as we break the GPU property interface)
|
||||
|
@ -254,7 +271,7 @@ void kernel_main(unsigned int r0, unsigned int r1, unsigned int atags)
|
|||
|
||||
|
||||
while (1) {
|
||||
rgb_to_fb(fb);
|
||||
rgb_to_fb(fb, CHARS_PER_LINE, BYTES_PER_LINE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,12 @@ end RGBtoHDMI;
|
|||
|
||||
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;
|
||||
|
@ -104,7 +110,7 @@ begin
|
|||
end if;
|
||||
|
||||
-- counter is used to find sampling point for first pixel
|
||||
counter <= to_unsigned(1311, counter'length);
|
||||
counter <= sample_point;
|
||||
|
||||
elsif nCSYNC1 = '0' then
|
||||
-- within the line sync pulse
|
||||
|
|
Ładowanie…
Reference in New Issue