M2DIR=../..
include $(M2DIR)/software/common.mak
-OBJECTS=crt0.o isr.o main.o
+OBJECTS=crt0.o isr.o dvisampler0.o dvisampler1.o main.o
all: videomixer.bin
%.o: %.S
$(assemble)
+define gen0
+@echo " GEN " $@
+@sed -e "s/dvisamplerX/dvisampler0/g;s/DVISAMPLERX/DVISAMPLER0/g" $< > $@
+endef
+
+define gen1
+@echo " GEN " $@
+@sed -e "s/dvisamplerX/dvisampler1/g;s/DVISAMPLERX/DVISAMPLER1/g" $< > $@
+endef
+
+dvisampler0.c: dvisamplerX.c
+ $(gen0)
+dvisampler0.h: dvisamplerX.h
+ $(gen0)
+dvisampler1.c: dvisamplerX.c
+ $(gen1)
+dvisampler1.h: dvisamplerX.h
+ $(gen1)
+
+isr.o: dvisampler0.h dvisampler1.h
+main.o: dvisampler0.h dvisampler1.h
+dvisampler0.o: dvisampler0.h
+dvisampler1.o: dvisampler1.h
+
libs:
make -C $(M2DIR)/software/libcompiler-rt
make -C $(M2DIR)/software/libbase
clean:
rm -f $(OBJECTS) $(OBJECTS:.o=.d) videomixer.elf videomixer.bin .*~ *~
+ rm -f dvisampler0.h dvisampler0.c dvisampler1.h dvisampler1.c
.PHONY: main.o clean libs load
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <irq.h>
+#include <uart.h>
+#include <hw/csr.h>
+#include <hw/flags.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 int dvisamplerX_fb_slot_indexes[2];
+static int dvisamplerX_next_fb_index;
+
+void dvisamplerX_isr(void)
+{
+ int fb_index = -1;
+
+ if(dvisamplerX_dma_slot0_status_read() == DVISAMPLER_SLOT_PENDING) {
+ fb_index = dvisamplerX_fb_slot_indexes[0];
+ dvisamplerX_fb_slot_indexes[0] = dvisamplerX_next_fb_index;
+ dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[dvisamplerX_next_fb_index]);
+ dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
+ dvisamplerX_next_fb_index = (dvisamplerX_next_fb_index + 1) & FRAMEBUFFER_MASK;
+ }
+ if(dvisamplerX_dma_slot1_status_read() == DVISAMPLER_SLOT_PENDING) {
+ fb_index = dvisamplerX_fb_slot_indexes[1];
+ dvisamplerX_fb_slot_indexes[1] = dvisamplerX_next_fb_index;
+ dvisamplerX_dma_slot1_address_write((unsigned int)dvisamplerX_framebuffers[dvisamplerX_next_fb_index]);
+ dvisamplerX_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
+ dvisamplerX_next_fb_index = (dvisamplerX_next_fb_index + 1) & FRAMEBUFFER_MASK;
+ }
+
+ if(fb_index != -1)
+ fb_base_write((unsigned int)dvisamplerX_framebuffers[fb_index]);
+}
+
+void dvisamplerX_init_video(void)
+{
+ unsigned int mask;
+
+ dvisamplerX_dma_ev_pending_write(dvisamplerX_dma_ev_pending_read());
+ dvisamplerX_dma_ev_enable_write(0x3);
+ mask = irq_getmask();
+ mask |= 1 << DVISAMPLERX_INTERRUPT;
+ irq_setmask(mask);
+
+ dvisamplerX_dma_frame_size_write(sizeof(dvisamplerX_framebuffers[0]));
+ dvisamplerX_fb_slot_indexes[0] = 0;
+ dvisamplerX_dma_slot0_address_write((unsigned int)dvisamplerX_framebuffers[0]);
+ dvisamplerX_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
+ dvisamplerX_fb_slot_indexes[1] = 1;
+ dvisamplerX_dma_slot1_address_write((unsigned int)dvisamplerX_framebuffers[1]);
+ dvisamplerX_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
+ dvisamplerX_next_fb_index = 2;
+
+ fb_base_write((unsigned int)dvisamplerX_framebuffers[3]);
+}
+
+static int dvisamplerX_d0, dvisamplerX_d1, dvisamplerX_d2;
+
+void dvisamplerX_print_status(void)
+{
+ printf("dvisamplerX ph:%4d %4d %4d // charsync:%d%d%d [%d %d %d] // chansync:%d // res:%dx%d\n",
+ dvisamplerX_d0, dvisamplerX_d1, dvisamplerX_d2,
+ dvisamplerX_data0_charsync_char_synced_read(),
+ dvisamplerX_data1_charsync_char_synced_read(),
+ dvisamplerX_data2_charsync_char_synced_read(),
+ dvisamplerX_data0_charsync_ctl_pos_read(),
+ dvisamplerX_data1_charsync_ctl_pos_read(),
+ dvisamplerX_data2_charsync_ctl_pos_read(),
+ dvisamplerX_chansync_channels_synced_read(),
+ dvisamplerX_resdetection_hres_read(),
+ dvisamplerX_resdetection_vres_read());
+}
+
+void 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());
+ 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);
+ dvisamplerX_data0_cap_phase_reset_write(1);
+ dvisamplerX_data1_cap_phase_reset_write(1);
+ dvisamplerX_data2_cap_phase_reset_write(1);
+ dvisamplerX_d0 = dvisamplerX_d1 = dvisamplerX_d2 = 0;
+}
+
+void dvisamplerX_adjust_phase(void)
+{
+ switch(dvisamplerX_data0_cap_phase_read()) {
+ case DVISAMPLER_TOO_LATE:
+ dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
+ dvisamplerX_d0--;
+ dvisamplerX_data0_cap_phase_reset_write(1);
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ dvisamplerX_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
+ dvisamplerX_d0++;
+ dvisamplerX_data0_cap_phase_reset_write(1);
+ break;
+ }
+ switch(dvisamplerX_data1_cap_phase_read()) {
+ case DVISAMPLER_TOO_LATE:
+ dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
+ dvisamplerX_d1--;
+ dvisamplerX_data1_cap_phase_reset_write(1);
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ dvisamplerX_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
+ dvisamplerX_d1++;
+ dvisamplerX_data1_cap_phase_reset_write(1);
+ break;
+ }
+ switch(dvisamplerX_data2_cap_phase_read()) {
+ case DVISAMPLER_TOO_LATE:
+ dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
+ dvisamplerX_d2--;
+ dvisamplerX_data2_cap_phase_reset_write(1);
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ dvisamplerX_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
+ dvisamplerX_d2++;
+ dvisamplerX_data2_cap_phase_reset_write(1);
+ break;
+ }
+}
+
+int dvisamplerX_init_phase(void)
+{
+ int o_d0, o_d1, o_d2;
+ int i, j;
+
+ for(i=0;i<100;i++) {
+ o_d0 = dvisamplerX_d0;
+ o_d1 = dvisamplerX_d1;
+ o_d2 = dvisamplerX_d2;
+ for(j=0;j<1000;j++)
+ dvisamplerX_adjust_phase();
+ if((abs(dvisamplerX_d0 - o_d0) < 4) && (abs(dvisamplerX_d1 - o_d1) < 4) && (abs(dvisamplerX_d2 - o_d2) < 4))
+ return 1;
+ }
+ return 0;
+}
+
+static int dvisamplerX_locked;
+
+void dvisamplerX_service(void)
+{
+ int ret;
+
+ if(dvisamplerX_locked) {
+ if(dvisamplerX_clocking_locked_read()) {
+ dvisamplerX_adjust_phase();
+ dvisamplerX_print_status();
+ } else {
+ printf("dvisamplerX: lost PLL lock\n");
+ dvisamplerX_locked = 0;
+ }
+ } else {
+ if(dvisamplerX_clocking_locked_read()) {
+ printf("dvisamplerX: PLL locked\n");
+ dvisamplerX_calibrate_delays();
+ printf("dvisamplerX: delays calibrated\n");
+ ret = dvisamplerX_init_phase();
+ if(ret)
+ printf("dvisamplerX: phase init OK\n");
+ else
+ printf("dvisamplerX: phase did not settle\n");
+ dvisamplerX_print_status();
+ dvisamplerX_locked = 1;
+ }
+ }
+}
--- /dev/null
+#ifndef __DVISAMPLERX_H
+#define __DVISAMPLERX_H
+
+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_init_phase(void);
+void dvisamplerX_service(void);
+
+#endif
#include <irq.h>
#include <uart.h>
-void dvisampler0_isr(void); // FIXME
+#include "dvisampler0.h"
+#include "dvisampler1.h"
void isr(void);
void isr(void)
uart_isr();
if(irqs & (1 << DVISAMPLER0_INTERRUPT))
dvisampler0_isr();
+ if(irqs & (1 << DVISAMPLER1_INTERRUPT))
+ dvisampler1_isr();
}
#include <irq.h>
#include <uart.h>
-#include <console.h>
#include <hw/csr.h>
#include <hw/flags.h>
-static int dvisampler0_d0, dvisampler0_d1, dvisampler0_d2;
-
-static void print_status(void)
-{
- printf("dvisampler0 ph: %4d %4d %4d // %d%d%d [%d %d %d] // %d // %dx%d\n", dvisampler0_d0, dvisampler0_d1, dvisampler0_d2,
- 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(),
- dvisampler0_resdetection_vres_read());
-}
-
-static void calibrate_delays(void)
-{
- 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);
- dvisampler0_d0 = dvisampler0_d1 = dvisampler0_d2 = 0;
- printf("Delays calibrated\n");
-}
-
-static void adjust_phase(void)
-{
- switch(dvisampler0_data0_cap_phase_read()) {
- case DVISAMPLER_TOO_LATE:
- dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- dvisampler0_d0--;
- dvisampler0_data0_cap_phase_reset_write(1);
- break;
- case DVISAMPLER_TOO_EARLY:
- dvisampler0_data0_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- dvisampler0_d0++;
- dvisampler0_data0_cap_phase_reset_write(1);
- break;
- }
- switch(dvisampler0_data1_cap_phase_read()) {
- case DVISAMPLER_TOO_LATE:
- dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- dvisampler0_d1--;
- dvisampler0_data1_cap_phase_reset_write(1);
- break;
- case DVISAMPLER_TOO_EARLY:
- dvisampler0_data1_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- dvisampler0_d1++;
- dvisampler0_data1_cap_phase_reset_write(1);
- break;
- }
- switch(dvisampler0_data2_cap_phase_read()) {
- case DVISAMPLER_TOO_LATE:
- dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_DEC);
- dvisampler0_d2--;
- dvisampler0_data2_cap_phase_reset_write(1);
- break;
- case DVISAMPLER_TOO_EARLY:
- dvisampler0_data2_cap_dly_ctl_write(DVISAMPLER_DELAY_INC);
- dvisampler0_d2++;
- dvisampler0_data2_cap_phase_reset_write(1);
- break;
- }
-}
-
-static int init_phase(void)
-{
- int o_d0, o_d1, o_d2;
- int i, j;
-
- for(i=0;i<100;i++) {
- o_d0 = dvisampler0_d0;
- o_d1 = dvisampler0_d1;
- o_d2 = dvisampler0_d2;
- for(j=0;j<1000;j++)
- adjust_phase();
- if((abs(dvisampler0_d0 - o_d0) < 4) && (abs(dvisampler0_d1 - o_d1) < 4) && (abs(dvisampler0_d2 - o_d2) < 4))
- return 1;
- }
- return 0;
-}
-
-#define FRAMEBUFFER_COUNT 4
-#define FRAMEBUFFER_MASK (FRAMEBUFFER_COUNT - 1)
-
-static unsigned int dvisampler0_framebuffers[FRAMEBUFFER_COUNT][640*480] __attribute__((aligned(16)));
-static int dvisampler0_fb_slot_indexes[2];
-static int dvisampler0_next_fb_index;
-
-static void dvisampler0_init_video(void)
-{
- unsigned int mask;
-
- dvisampler0_dma_ev_pending_write(dvisampler0_dma_ev_pending_read());
- dvisampler0_dma_ev_enable_write(0x3);
- mask = irq_getmask();
- mask |= 1 << DVISAMPLER0_INTERRUPT;
- irq_setmask(mask);
-
- dvisampler0_dma_frame_size_write(sizeof(dvisampler0_framebuffers[0]));
- dvisampler0_fb_slot_indexes[0] = 0;
- dvisampler0_dma_slot0_address_write((unsigned int)dvisampler0_framebuffers[0]);
- dvisampler0_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
- dvisampler0_fb_slot_indexes[1] = 1;
- dvisampler0_dma_slot1_address_write((unsigned int)dvisampler0_framebuffers[1]);
- dvisampler0_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
- dvisampler0_next_fb_index = 2;
-
- fb_base_write((unsigned int)dvisampler0_framebuffers[0]);
-}
-
-void dvisampler0_isr(void)
-{
- int fb_index = -1;
-
- if(dvisampler0_dma_slot0_status_read() == DVISAMPLER_SLOT_PENDING) {
- fb_index = dvisampler0_fb_slot_indexes[0];
- dvisampler0_fb_slot_indexes[0] = dvisampler0_next_fb_index;
- dvisampler0_dma_slot0_address_write((unsigned int)dvisampler0_framebuffers[dvisampler0_next_fb_index]);
- dvisampler0_dma_slot0_status_write(DVISAMPLER_SLOT_LOADED);
- dvisampler0_next_fb_index = (dvisampler0_next_fb_index + 1) & FRAMEBUFFER_MASK;
- }
- if(dvisampler0_dma_slot1_status_read() == DVISAMPLER_SLOT_PENDING) {
- fb_index = dvisampler0_fb_slot_indexes[1];
- dvisampler0_fb_slot_indexes[1] = dvisampler0_next_fb_index;
- dvisampler0_dma_slot1_address_write((unsigned int)dvisampler0_framebuffers[dvisampler0_next_fb_index]);
- dvisampler0_dma_slot1_status_write(DVISAMPLER_SLOT_LOADED);
- dvisampler0_next_fb_index = (dvisampler0_next_fb_index + 1) & FRAMEBUFFER_MASK;
- }
-
- if(fb_index != -1)
- fb_base_write((unsigned int)dvisampler0_framebuffers[fb_index]);
-}
-
-static void vmix(void)
-{
- unsigned int counter;
-
- while(1) {
- while(!dvisampler0_clocking_locked_read());
- printf("PLL locked\n");
- calibrate_delays();
- if(init_phase())
- printf("Phase init OK\n");
- else
- printf("Phase did not settle\n");
- print_status();
-
- counter = 0;
- while(dvisampler0_clocking_locked_read()) {
- counter++;
- if(counter == 2000000) {
- print_status();
- adjust_phase();
- counter = 0;
- }
- }
- printf("PLL unlocked\n");
- }
-}
+#include "dvisampler0.h"
+#include "dvisampler1.h"
int main(void)
{
dvisampler0_init_video();
fb_enable_write(1);
- vmix();
+ while(1) dvisampler0_service();
return 0;
}