2013-03-21 05:42:31 -04:00
|
|
|
#include <stdio.h>
|
2013-03-23 19:46:23 -04:00
|
|
|
#include <stdlib.h>
|
2013-03-21 05:42:31 -04:00
|
|
|
|
|
|
|
#include <irq.h>
|
|
|
|
#include <uart.h>
|
2013-04-14 10:33:00 -04:00
|
|
|
#include <hw/csr.h>
|
|
|
|
#include <hw/flags.h>
|
2013-03-21 10:32:26 -04:00
|
|
|
|
|
|
|
static int d0, d1, d2;
|
|
|
|
|
2013-03-23 19:46:23 -04:00
|
|
|
static void print_status(void)
|
|
|
|
{
|
2013-05-05 05:58:43 -04:00
|
|
|
printf("Ph: %4d %4d %4d // %d%d%d [%d %d %d] // %d // %dx%d\n", d0, d1, d2,
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_charsync_char_synced_read(),
|
|
|
|
dvisampler0_data1_charsync_char_synced_read(),
|
|
|
|
dvisampler0_data2_charsync_char_synced_read(),
|
|
|
|
dvisampler0_data0_charsync_ctl_pos_read(),
|
|
|
|
dvisampler0_data1_charsync_ctl_pos_read(),
|
|
|
|
dvisampler0_data2_charsync_ctl_pos_read(),
|
|
|
|
dvisampler0_chansync_channels_synced_read(),
|
|
|
|
dvisampler0_resdetection_hres_read(),
|
2013-05-05 05:58:43 -04:00
|
|
|
dvisampler0_resdetection_vres_read());
|
2013-03-23 19:46:23 -04:00
|
|
|
}
|
|
|
|
|
2013-03-21 10:32:26 -04:00
|
|
|
static void calibrate_delays(void)
|
|
|
|
{
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
|
|
|
|
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
|
|
|
|
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_CAL);
|
|
|
|
while(dvisampler0_data0_cap_dly_busy_read()
|
|
|
|
|| dvisampler0_data1_cap_dly_busy_read()
|
|
|
|
|| dvisampler0_data2_cap_dly_busy_read());
|
|
|
|
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
|
|
|
|
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
|
|
|
|
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_RST);
|
|
|
|
dvisampler0_data0_cap_phase_reset_write(1);
|
|
|
|
dvisampler0_data1_cap_phase_reset_write(1);
|
|
|
|
dvisampler0_data2_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
d0 = d1 = d2 = 0;
|
|
|
|
printf("Delays calibrated\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void adjust_phase(void)
|
|
|
|
{
|
2013-04-14 10:33:00 -04:00
|
|
|
switch(dvisampler0_data0_cap_phase_read()) {
|
2013-03-21 10:32:26 -04:00
|
|
|
case DVISAMPLER_TOO_LATE:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d0--;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
case DVISAMPLER_TOO_EARLY:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d0++;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data0_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
}
|
2013-04-14 10:33:00 -04:00
|
|
|
switch(dvisampler0_data1_cap_phase_read()) {
|
2013-03-21 10:32:26 -04:00
|
|
|
case DVISAMPLER_TOO_LATE:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d1--;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data1_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
case DVISAMPLER_TOO_EARLY:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d1++;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data1_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
}
|
2013-04-14 10:33:00 -04:00
|
|
|
switch(dvisampler0_data2_cap_phase_read()) {
|
2013-03-21 10:32:26 -04:00
|
|
|
case DVISAMPLER_TOO_LATE:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d2--;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data2_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
case DVISAMPLER_TOO_EARLY:
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
|
2013-03-21 10:32:26 -04:00
|
|
|
d2++;
|
2013-04-14 10:33:00 -04:00
|
|
|
dvisampler0_data2_cap_phase_reset_write(1);
|
2013-03-21 10:32:26 -04:00
|
|
|
break;
|
|
|
|
}
|
2013-03-23 19:46:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int init_phase(void)
|
|
|
|
{
|
|
|
|
int od0, od1, od2;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for(i=0;i<100;i++) {
|
|
|
|
od0 = d0;
|
|
|
|
od1 = d1;
|
|
|
|
od2 = d2;
|
|
|
|
for(j=0;j<1000;j++)
|
|
|
|
adjust_phase();
|
|
|
|
if((abs(d0 - od0) < 4) && (abs(d1 - od1) < 4) && (abs(d2 - od2) < 4))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
2013-03-21 10:32:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vmix(void)
|
|
|
|
{
|
|
|
|
unsigned int counter;
|
|
|
|
|
|
|
|
while(1) {
|
2013-04-14 10:33:00 -04:00
|
|
|
while(!dvisampler0_clocking_locked_read());
|
2013-03-21 10:32:26 -04:00
|
|
|
printf("PLL locked\n");
|
|
|
|
calibrate_delays();
|
2013-03-23 19:46:23 -04:00
|
|
|
if(init_phase())
|
|
|
|
printf("Phase init OK\n");
|
|
|
|
else
|
|
|
|
printf("Phase did not settle\n");
|
|
|
|
print_status();
|
2013-03-21 10:32:26 -04:00
|
|
|
|
|
|
|
counter = 0;
|
2013-04-14 10:33:00 -04:00
|
|
|
while(dvisampler0_clocking_locked_read()) {
|
2013-03-21 10:32:26 -04:00
|
|
|
counter++;
|
2013-03-23 19:46:23 -04:00
|
|
|
if(counter == 2000000) {
|
|
|
|
print_status();
|
2013-05-05 05:58:43 -04:00
|
|
|
adjust_phase();
|
2013-03-21 10:32:26 -04:00
|
|
|
counter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("PLL unlocked\n");
|
|
|
|
}
|
|
|
|
}
|
2013-03-21 05:42:31 -04:00
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
irq_setmask(0);
|
|
|
|
irq_setie(1);
|
|
|
|
uart_init();
|
|
|
|
|
|
|
|
puts("Minimal video mixer software built "__DATE__" "__TIME__"\n");
|
|
|
|
|
2013-03-21 10:32:26 -04:00
|
|
|
vmix();
|
2013-03-21 05:42:31 -04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|