Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 3 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
2  software/videomixer/Makefile
... ...
@@ -1,7 +1,7 @@
1 1
 M2DIR=../..
2 2
 include $(M2DIR)/software/common.mak
3 3
 
4  
-OBJECTS=crt0.o isr.o time.o dvisampler0.o dvisampler1.o main.o
  4
+OBJECTS=crt0.o isr.o time.o fb.o dvisampler0.o dvisampler1.o main.o
5 5
 
6 6
 all: videomixer.bin videomixer.fbi
7 7
 
59  software/videomixer/dvisamplerX.c
@@ -7,12 +7,13 @@
7 7
 #include <hw/flags.h>
8 8
 
9 9
 #include "time.h"
  10
+#include "fb.h"
10 11
 #include "dvisamplerX.h"
11 12
 
12 13
 #define FRAMEBUFFER_COUNT 4
13 14
 #define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)
14 15
 
15  
-static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][640*480] __attribute__((aligned(16)));
  16
+static unsigned int dvisamplerX_framebuffers[FRAMEBUFFER_COUNT][800*600] __attribute__((aligned(16)));
16 17
 static int dvisamplerX_fb_slot_indexes[2];
17 18
 static int dvisamplerX_next_fb_index;
18 19
 
@@ -49,7 +50,7 @@ void dvisamplerX_init_video(void)
49 50
 	mask |= 1 << DVISAMPLERX_INTERRUPT;
50 51
 	irq_setmask(mask);
51 52
 
52  
-	dvisamplerX_dma_frame_size_write(sizeof(dvisamplerX_framebuffers[0]));
  53
+	dvisamplerX_dma_frame_size_write(fb_hres*fb_vres*4);
53 54
 	dvisamplerX_fb_slot_indexes[0] = 0;
54 55
 	dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[0]);
55 56
 	dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
@@ -84,14 +85,30 @@ void dvisamplerX_print_status(void)
84 85
 		dvisamplerX_resdetection_vres_read());
85 86
 }
86 87
 
87  
-void dvisamplerX_calibrate_delays(void)
  88
+static int wait_idelays(void)
  89
+{
  90
+	int ev;
  91
+
  92
+	ev = 0;
  93
+	elapsed(&ev, 1);
  94
+	while(dvisamplerX_data0_cap_dly_busy_read()
  95
+	  || dvisamplerX_data1_cap_dly_busy_read()
  96
+	  || dvisamplerX_data2_cap_dly_busy_read()) {
  97
+		if(elapsed(&ev, identifier_frequency_read() >> 6) == 0) {
  98
+			printf("IDELAY busy timeout\n");
  99
+			return 0;
  100
+		}
  101
+	}
  102
+	return 1;
  103
+}
  104
+
  105
+int dvisamplerX_calibrate_delays(void)
88 106
 {
89 107
 	dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
90 108
 	dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
91 109
 	dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
92  
-	while(dvisamplerX_data0_cap_dly_busy_read()
93  
-		|| dvisamplerX_data1_cap_dly_busy_read()
94  
-		|| dvisamplerX_data2_cap_dly_busy_read());
  110
+	if(!wait_idelays())
  111
+		return 0;
95 112
 	dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
96 113
 	dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
97 114
 	dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
@@ -99,20 +116,23 @@ void dvisamplerX_calibrate_delays(void)
99 116
 	dvisamplerX_data1_cap_phase_reset_write(1);
100 117
 	dvisamplerX_data2_cap_phase_reset_write(1);
101 118
 	dvisamplerX_d0 = dvisamplerX_d1 = dvisamplerX_d2 = 0;
  119
+	return 1;
102 120
 }
103 121
 
104  
-void dvisamplerX_adjust_phase(void)
  122
+int dvisamplerX_adjust_phase(void)
105 123
 {
106 124
 	switch(dvisamplerX_data0_cap_phase_read()) {
107 125
 		case DVISAMPLER_TOO_LATE:
108 126
 			dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
109  
-			while(dvisamplerX_data0_cap_dly_busy_read());
  127
+			if(!wait_idelays())
  128
+				return 0;
110 129
 			dvisamplerX_d0--;
111 130
 			dvisamplerX_data0_cap_phase_reset_write(1);
112 131
 			break;
113 132
 		case DVISAMPLER_TOO_EARLY:
114 133
 			dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
115  
-			while(dvisamplerX_data0_cap_dly_busy_read());
  134
+			if(!wait_idelays())
  135
+				return 0;
116 136
 			dvisamplerX_d0++;
117 137
 			dvisamplerX_data0_cap_phase_reset_write(1);
118 138
 			break;
@@ -120,13 +140,15 @@ void dvisamplerX_adjust_phase(void)
120 140
 	switch(dvisamplerX_data1_cap_phase_read()) {
121 141
 		case DVISAMPLER_TOO_LATE:
122 142
 			dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
123  
-			while(dvisamplerX_data1_cap_dly_busy_read());
  143
+			if(!wait_idelays())
  144
+				return 0;
124 145
 			dvisamplerX_d1--;
125 146
 			dvisamplerX_data1_cap_phase_reset_write(1);
126 147
 			break;
127 148
 		case DVISAMPLER_TOO_EARLY:
128 149
 			dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
129  
-			while(dvisamplerX_data1_cap_dly_busy_read());
  150
+			if(!wait_idelays())
  151
+				return 0;
130 152
 			dvisamplerX_d1++;
131 153
 			dvisamplerX_data1_cap_phase_reset_write(1);
132 154
 			break;
@@ -134,17 +156,20 @@ void dvisamplerX_adjust_phase(void)
134 156
 	switch(dvisamplerX_data2_cap_phase_read()) {
135 157
 		case DVISAMPLER_TOO_LATE:
136 158
 			dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
137  
-			while(dvisamplerX_data2_cap_dly_busy_read());
  159
+			if(!wait_idelays())
  160
+				return 0;
138 161
 			dvisamplerX_d2--;
139 162
 			dvisamplerX_data2_cap_phase_reset_write(1);
140 163
 			break;
141 164
 		case DVISAMPLER_TOO_EARLY:
142 165
 			dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
143  
-			while(dvisamplerX_data2_cap_dly_busy_read());
  166
+			if(!wait_idelays())
  167
+				return 0;
144 168
 			dvisamplerX_d2++;
145 169
 			dvisamplerX_data2_cap_phase_reset_write(1);
146 170
 			break;
147 171
 	}
  172
+	return 1;
148 173
 }
149 174
 
150 175
 int dvisamplerX_init_phase(void)
@@ -156,8 +181,10 @@ int dvisamplerX_init_phase(void)
156 181
 		o_d0 = dvisamplerX_d0;
157 182
 		o_d1 = dvisamplerX_d1;
158 183
 		o_d2 = dvisamplerX_d2;
159  
-		for(j=0;j<1000;j++)
160  
-			dvisamplerX_adjust_phase();
  184
+		for(j=0;j<1000;j++) {
  185
+			if(!dvisamplerX_adjust_phase())
  186
+				return 0;
  187
+		}
161 188
 		if((abs(dvisamplerX_d0 - o_d0) < 4) && (abs(dvisamplerX_d1 - o_d1) < 4) && (abs(dvisamplerX_d2 - o_d2) < 4))
162 189
 			return 1;
163 190
 	}
@@ -179,7 +206,7 @@ int dvisamplerX_phase_startup(void)
179 206
 			printf("dvisamplerX: phase init OK\n");
180 207
 			return 1;
181 208
 		} else {
182  
-			printf("dvisamplerX: phase did not settle\n");
  209
+			printf("dvisamplerX: phase init failed\n");
183 210
 			if(attempts > 3) {
184 211
 				printf("dvisamplerX: giving up\n");
185 212
 				dvisamplerX_calibrate_delays();
4  software/videomixer/dvisamplerX.h
@@ -4,8 +4,8 @@
4 4
 void dvisamplerX_isr(void);
5 5
 void dvisamplerX_init_video(void);
6 6
 void dvisamplerX_print_status(void);
7  
-void dvisamplerX_calibrate_delays(void);
8  
-void dvisamplerX_adjust_phase(void);
  7
+int dvisamplerX_calibrate_delays(void);
  8
+int dvisamplerX_adjust_phase(void);
9 9
 int dvisamplerX_init_phase(void);
10 10
 int dvisamplerX_phase_startup(void);
11 11
 void dvisamplerX_service(void);
103  software/videomixer/fb.c
... ...
@@ -0,0 +1,103 @@
  1
+#include <stdio.h>
  2
+
  3
+#include <hw/csr.h>
  4
+#include <hw/flags.h>
  5
+
  6
+#include "fb.h"
  7
+
  8
+int fb_hres = 640;
  9
+int fb_vres = 480;
  10
+
  11
+static void fb_clkgen_write(int cmd, int data)
  12
+{
  13
+	int word;
  14
+
  15
+	word = (data << 2) | cmd;
  16
+	crg_cmd_data_write(word);
  17
+	crg_send_cmd_data_write(1);
  18
+	while(crg_status_read() & CLKGEN_STATUS_BUSY);
  19
+}
  20
+
  21
+void fb_set_mode(int mode)
  22
+{
  23
+	int clock_m, clock_d;
  24
+
  25
+	switch(mode) {
  26
+		default:
  27
+		case FB_MODE_640_480: // Pixel clock: 25MHz
  28
+			fb_hres = 640;
  29
+			fb_vres = 480;
  30
+			clock_m = 2;
  31
+			clock_d = 4;
  32
+			fb_fi_hres_write(640);
  33
+			fb_fi_hsync_start_write(656);
  34
+			fb_fi_hsync_end_write(752);
  35
+			fb_fi_hscan_write(800);
  36
+			fb_fi_vres_write(480);
  37
+			fb_fi_vsync_start_write(492);
  38
+			fb_fi_vsync_end_write(494);
  39
+			fb_fi_vscan_write(525);
  40
+			break;
  41
+		case FB_MODE_800_600: // Pixel clock: 50MHz
  42
+			fb_hres = 800;
  43
+			fb_vres = 600;
  44
+			clock_m = 2;
  45
+			clock_d = 2;
  46
+			fb_fi_hres_write(800);
  47
+			fb_fi_hsync_start_write(848);
  48
+			fb_fi_hsync_end_write(976);
  49
+			fb_fi_hscan_write(1040);
  50
+			fb_fi_vres_write(600);
  51
+			fb_fi_vsync_start_write(636);
  52
+			fb_fi_vsync_end_write(642);
  53
+			fb_fi_vscan_write(665);
  54
+			break;
  55
+		case FB_MODE_1024_768: // Pixel clock: 65MHz
  56
+			fb_hres = 1024;
  57
+			fb_vres = 768;
  58
+			clock_m = 13;
  59
+			clock_d = 10;
  60
+			fb_fi_hres_write(1024);
  61
+			fb_fi_hsync_start_write(1048);
  62
+			fb_fi_hsync_end_write(1184);
  63
+			fb_fi_hscan_write(1344);
  64
+			fb_fi_vres_write(768);
  65
+			fb_fi_vsync_start_write(772);
  66
+			fb_fi_vsync_end_write(778);
  67
+			fb_fi_vscan_write(807);
  68
+			break;
  69
+		case FB_MODE_1920_1080: // Pixel clock: 148MHz
  70
+			fb_hres = 1920;
  71
+			fb_vres = 1080;
  72
+			clock_m = 74;
  73
+			clock_d = 25;
  74
+			fb_fi_hres_write(1920);
  75
+			fb_fi_hsync_start_write(2008);
  76
+			fb_fi_hsync_end_write(2052);
  77
+			fb_fi_hscan_write(2200);
  78
+			fb_fi_vres_write(1080);
  79
+			fb_fi_vsync_start_write(1084);
  80
+			fb_fi_vsync_end_write(1089);
  81
+			fb_fi_vscan_write(1125);
  82
+			break;
  83
+	}
  84
+	fb_dma0_length_write(fb_hres*fb_vres*4);
  85
+	fb_dma1_length_write(fb_hres*fb_vres*4);
  86
+
  87
+	fb_clkgen_write(0x1, clock_d-1);
  88
+	fb_clkgen_write(0x3, clock_m-1);
  89
+	crg_send_go_write(1);
  90
+	printf("waiting for PROGDONE...");
  91
+	while(!(crg_status_read() & CLKGEN_STATUS_PROGDONE));
  92
+	printf("ok\n");
  93
+	printf("waiting for LOCKED...");
  94
+	while(!(crg_status_read() & CLKGEN_STATUS_LOCKED));
  95
+	printf("ok\n");
  96
+
  97
+	printf("VGA: mode set to %dx%d\n", fb_hres, fb_vres);
  98
+}
  99
+
  100
+void fb_enable(int en)
  101
+{
  102
+	fb_enable_write(!!en);
  103
+}
16  software/videomixer/fb.h
... ...
@@ -0,0 +1,16 @@
  1
+#ifndef __FB_H
  2
+#define __FB_H
  3
+
  4
+enum {
  5
+    FB_MODE_640_480,
  6
+    FB_MODE_800_600,
  7
+    FB_MODE_1024_768,
  8
+    FB_MODE_1920_1080
  9
+};
  10
+
  11
+extern int fb_hres, fb_vres;
  12
+
  13
+void fb_set_mode(int mode);
  14
+void fb_enable(int en);
  15
+
  16
+#endif /* __FB_H */
8  software/videomixer/main.c
@@ -8,6 +8,7 @@
8 8
 #include <console.h>
9 9
 
10 10
 #include "time.h"
  11
+#include "fb.h"
11 12
 #include "dvisampler0.h"
12 13
 #include "dvisampler1.h"
13 14
 
@@ -80,10 +81,10 @@ static void fb_service(void)
80 81
 	if(readchar_nonblock()) {
81 82
 		c = readchar();
82 83
 		if(c == '1') {
83  
-			fb_enable_write(1);
  84
+			fb_enable(1);
84 85
 			printf("Framebuffer is ON\n");
85 86
 		} else if(c == '0') {
86  
-			fb_enable_write(0);
  87
+			fb_enable(0);
87 88
 			printf("Framebuffer is OFF\n");
88 89
 		}
89 90
 	}
@@ -98,9 +99,10 @@ int main(void)
98 99
 	puts("Minimal video mixer software built "__DATE__" "__TIME__"\n");
99 100
 	
100 101
 	time_init();
  102
+	fb_set_mode(FB_MODE_640_480);
101 103
 	dvisampler0_init_video();
102 104
 	dvisampler1_init_video();
103  
-	fb_enable_write(1);
  105
+	fb_enable(1);
104 106
 
105 107
 	while(1) {
106 108
 		dvisampler0_service();

No commit comments for this range

Something went wrong with that request. Please try again.