From bb43171274f1847fa3bd8f40d8081f3182c70321 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 14 Jun 2013 18:17:04 +0200 Subject: [PATCH] videomixer: support different resolutions --- software/videomixer/dvisamplerX.c | 5 +- software/videomixer/fb.c | 103 ++++++++++++++++++++++++++++++ software/videomixer/fb.h | 16 +++++ software/videomixer/main.c | 8 ++- 4 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 software/videomixer/fb.c create mode 100644 software/videomixer/fb.h diff --git a/software/videomixer/dvisamplerX.c b/software/videomixer/dvisamplerX.c index 01f7e029..cf2a50f7 100644 --- a/software/videomixer/dvisamplerX.c +++ b/software/videomixer/dvisamplerX.c @@ -7,12 +7,13 @@ #include #include "time.h" +#include "fb.h" #include "dvisamplerX.h" #define FRAMEBUFFER_COUNT 4 #define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1) -static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][640*480] __attribute__((aligned(16))); +static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][800*600] __attribute__((aligned(16))); static int dvisamplerX_fb_slot_indexes[2]; static int dvisamplerX_next_fb_index; @@ -49,7 +50,7 @@ void dvisamplerX_init_video(void) mask |= 1 << DVISAMPLERX_INTERRUPT; irq_setmask(mask); - dvisamplerX_dma_frame_size_write(sizeof(dvisamplerX_framebuffers[0])); + dvisamplerX_dma_frame_size_write(fb_hres*fb_vres*4); dvisamplerX_fb_slot_indexes[0] = 0; dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[0]); dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED); diff --git a/software/videomixer/fb.c b/software/videomixer/fb.c new file mode 100644 index 00000000..58b90bca --- /dev/null +++ b/software/videomixer/fb.c @@ -0,0 +1,103 @@ +#include + +#include +#include + +#include "fb.h" + +int fb_hres = 640; +int fb_vres = 480; + +static void fb_clkgen_write(int cmd, int data) +{ + int word; + + word = (data << 2) | cmd; + crg_cmd_data_write(word); + crg_send_cmd_data_write(1); + while(crg_status_read() & CLKGEN_STATUS_BUSY); +} + +void fb_set_mode(int mode) +{ + int clock_m, clock_d; + + switch(mode) { + default: + case FB_MODE_640_480: // Pixel clock: 25MHz + fb_hres = 640; + fb_vres = 480; + clock_m = 2; + clock_d = 4; + fb_fi_hres_write(640); + fb_fi_hsync_start_write(656); + fb_fi_hsync_end_write(752); + fb_fi_hscan_write(800); + fb_fi_vres_write(480); + fb_fi_vsync_start_write(492); + fb_fi_vsync_end_write(494); + fb_fi_vscan_write(525); + break; + case FB_MODE_800_600: // Pixel clock: 50MHz + fb_hres = 800; + fb_vres = 600; + clock_m = 2; + clock_d = 2; + fb_fi_hres_write(800); + fb_fi_hsync_start_write(848); + fb_fi_hsync_end_write(976); + fb_fi_hscan_write(1040); + fb_fi_vres_write(600); + fb_fi_vsync_start_write(636); + fb_fi_vsync_end_write(642); + fb_fi_vscan_write(665); + break; + case FB_MODE_1024_768: // Pixel clock: 65MHz + fb_hres = 1024; + fb_vres = 768; + clock_m = 13; + clock_d = 10; + fb_fi_hres_write(1024); + fb_fi_hsync_start_write(1048); + fb_fi_hsync_end_write(1184); + fb_fi_hscan_write(1344); + fb_fi_vres_write(768); + fb_fi_vsync_start_write(772); + fb_fi_vsync_end_write(778); + fb_fi_vscan_write(807); + break; + case FB_MODE_1920_1080: // Pixel clock: 148MHz + fb_hres = 1920; + fb_vres = 1080; + clock_m = 74; + clock_d = 25; + fb_fi_hres_write(1920); + fb_fi_hsync_start_write(2008); + fb_fi_hsync_end_write(2052); + fb_fi_hscan_write(2200); + fb_fi_vres_write(1080); + fb_fi_vsync_start_write(1084); + fb_fi_vsync_end_write(1089); + fb_fi_vscan_write(1125); + break; + } + fb_dma0_length_write(fb_hres*fb_vres*4); + fb_dma1_length_write(fb_hres*fb_vres*4); + + fb_clkgen_write(0x1, clock_d-1); + fb_clkgen_write(0x3, clock_m-1); + crg_send_go_write(1); + printf("waiting for PROGDONE..."); + while(!(crg_status_read() & CLKGEN_STATUS_PROGDONE)); + printf("ok\n"); + printf("waiting for LOCKED..."); + while(!(crg_status_read() & CLKGEN_STATUS_LOCKED)); + printf("ok\n"); + + printf("VGA: mode set to %dx%d\n", fb_hres, fb_vres); +} + +void fb_enable(int en) +{ + fb_enable_write(!!en); +} diff --git a/software/videomixer/fb.h b/software/videomixer/fb.h new file mode 100644 index 00000000..7b9cc926 --- /dev/null +++ b/software/videomixer/fb.h @@ -0,0 +1,16 @@ +#ifndef __FB_H +#define __FB_H + +enum { + FB_MODE_640_480, + FB_MODE_800_600, + FB_MODE_1024_768, + FB_MODE_1920_1080 +}; + +extern int fb_hres, fb_vres; + +void fb_set_mode(int mode); +void fb_enable(int en); + +#endif /* __FB_H */ diff --git a/software/videomixer/main.c b/software/videomixer/main.c index aa92c0f8..4a44be7d 100644 --- a/software/videomixer/main.c +++ b/software/videomixer/main.c @@ -8,6 +8,7 @@ #include #include "time.h" +#include "fb.h" #include "dvisampler0.h" #include "dvisampler1.h" @@ -80,10 +81,10 @@ static void fb_service(void) if(readchar_nonblock()) { c = readchar(); if(c == '1') { - fb_enable_write(1); + fb_enable(1); printf("Framebuffer is ON\n"); } else if(c == '0') { - fb_enable_write(0); + fb_enable(0); printf("Framebuffer is OFF\n"); } } @@ -98,9 +99,10 @@ int main(void) puts("Minimal video mixer software built "__DATE__" "__TIME__"\n"); time_init(); + fb_set_mode(FB_MODE_640_480); dvisampler0_init_video(); dvisampler1_init_video(); - fb_enable_write(1); + fb_enable(1); while(1) { dvisampler0_service(); -- 2.30.2