Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 3 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
View
2  software/videomixer/Makefile
@@ -1,7 +1,7 @@
M2DIR=../..
include $(M2DIR)/software/common.mak
-OBJECTS=crt0.o isr.o time.o dvisampler0.o dvisampler1.o main.o
+OBJECTS=crt0.o isr.o time.o fb.o dvisampler0.o dvisampler1.o main.o
all: videomixer.bin videomixer.fbi
View
59 software/videomixer/dvisamplerX.c
@@ -7,12 +7,13 @@
#include <hw/flags.h>
#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);
@@ -84,14 +85,30 @@ void dvisamplerX_print_status(void)
dvisamplerX_resdetection_vres_read());
}
-void dvisamplerX_calibrate_delays(void)
+static int wait_idelays(void)
+{
+ int ev;
+
+ ev = 0;
+ elapsed(&ev, 1);
+ while(dvisamplerX_data0_cap_dly_busy_read()
+ || dvisamplerX_data1_cap_dly_busy_read()
+ || dvisamplerX_data2_cap_dly_busy_read()) {
+ if(elapsed(&ev, identifier_frequency_read() >> 6) == 0) {
+ printf("IDELAY busy timeout\n");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int dvisamplerX_calibrate_delays(void)
{
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
- while(dvisamplerX_data0_cap_dly_busy_read()
- || dvisamplerX_data1_cap_dly_busy_read()
- || dvisamplerX_data2_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
@@ -99,20 +116,23 @@ void dvisamplerX_calibrate_delays(void)
dvisamplerX_data1_cap_phase_reset_write(1);
dvisamplerX_data2_cap_phase_reset_write(1);
dvisamplerX_d0 = dvisamplerX_d1 = dvisamplerX_d2 = 0;
+ return 1;
}
-void dvisamplerX_adjust_phase(void)
+int dvisamplerX_adjust_phase(void)
{
switch(dvisamplerX_data0_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- while(dvisamplerX_data0_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d0--;
dvisamplerX_data0_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- while(dvisamplerX_data0_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d0++;
dvisamplerX_data0_cap_phase_reset_write(1);
break;
@@ -120,13 +140,15 @@ void dvisamplerX_adjust_phase(void)
switch(dvisamplerX_data1_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- while(dvisamplerX_data1_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d1--;
dvisamplerX_data1_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- while(dvisamplerX_data1_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d1++;
dvisamplerX_data1_cap_phase_reset_write(1);
break;
@@ -134,17 +156,20 @@ void dvisamplerX_adjust_phase(void)
switch(dvisamplerX_data2_cap_phase_read()) {
case DVISAMPLER_TOO_LATE:
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- while(dvisamplerX_data2_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d2--;
dvisamplerX_data2_cap_phase_reset_write(1);
break;
case DVISAMPLER_TOO_EARLY:
dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- while(dvisamplerX_data2_cap_dly_busy_read());
+ if(!wait_idelays())
+ return 0;
dvisamplerX_d2++;
dvisamplerX_data2_cap_phase_reset_write(1);
break;
}
+ return 1;
}
int dvisamplerX_init_phase(void)
@@ -156,8 +181,10 @@ int dvisamplerX_init_phase(void)
o_d0 = dvisamplerX_d0;
o_d1 = dvisamplerX_d1;
o_d2 = dvisamplerX_d2;
- for(j=0;j<1000;j++)
- dvisamplerX_adjust_phase();
+ for(j=0;j<1000;j++) {
+ if(!dvisamplerX_adjust_phase())
+ return 0;
+ }
if((abs(dvisamplerX_d0 - o_d0) < 4) && (abs(dvisamplerX_d1 - o_d1) < 4) && (abs(dvisamplerX_d2 - o_d2) < 4))
return 1;
}
@@ -179,7 +206,7 @@ int dvisamplerX_phase_startup(void)
printf("dvisamplerX: phase init OK\n");
return 1;
} else {
- printf("dvisamplerX: phase did not settle\n");
+ printf("dvisamplerX: phase init failed\n");
if(attempts > 3) {
printf("dvisamplerX: giving up\n");
dvisamplerX_calibrate_delays();
View
4 software/videomixer/dvisamplerX.h
@@ -4,8 +4,8 @@
void dvisamplerX_isr(void);
void dvisamplerX_init_video(void);
void dvisamplerX_print_status(void);
-void dvisamplerX_calibrate_delays(void);
-void dvisamplerX_adjust_phase(void);
+int dvisamplerX_calibrate_delays(void);
+int dvisamplerX_adjust_phase(void);
int dvisamplerX_init_phase(void);
int dvisamplerX_phase_startup(void);
void dvisamplerX_service(void);
View
103 software/videomixer/fb.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+
+#include <hw/csr.h>
+#include <hw/flags.h>
+
+#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);
+}
View
16 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 */
View
8 software/videomixer/main.c
@@ -8,6 +8,7 @@
#include <console.h>
#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();

No commit comments for this range

Something went wrong with that request. Please try again.