software/dvimixer: support two channels
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 9 May 2013 11:41:21 +0000 (13:41 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 9 May 2013 11:41:21 +0000 (13:41 +0200)
software/videomixer/Makefile
software/videomixer/dvisamplerX.c [new file with mode: 0644]
software/videomixer/dvisamplerX.h [new file with mode: 0644]
software/videomixer/isr.c
software/videomixer/main.c

index 4b6bf278f22f5420c96575c4d408fd2d84c2eb8f..dca4c3a18bb9affdb9942fd59ed94fb8ee51413b 100644 (file)
@@ -1,7 +1,7 @@
 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
 
@@ -30,6 +30,30 @@ main.o: main.c
 %.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
@@ -40,5 +64,6 @@ load: videomixer.bin
 
 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
diff --git a/software/videomixer/dvisamplerX.c b/software/videomixer/dvisamplerX.c
new file mode 100644 (file)
index 0000000..d7ac2a8
--- /dev/null
@@ -0,0 +1,182 @@
+#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;
+               }
+       }
+}
diff --git a/software/videomixer/dvisamplerX.h b/software/videomixer/dvisamplerX.h
new file mode 100644 (file)
index 0000000..7d02b42
--- /dev/null
@@ -0,0 +1,12 @@
+#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
index 19d641ec63d632708db650e1f138e1117a7a01bb..aa1139f805ceb3300f7db55e11b965064683e265 100644 (file)
@@ -2,7 +2,8 @@
 #include <irq.h>
 #include <uart.h>
 
-void dvisampler0_isr(void); // FIXME
+#include "dvisampler0.h"
+#include "dvisampler1.h"
 
 void isr(void);
 void isr(void)
@@ -15,4 +16,6 @@ void isr(void)
                uart_isr();
        if(irqs & (1 << DVISAMPLER0_INTERRUPT))
                dvisampler0_isr();
+       if(irqs & (1 << DVISAMPLER1_INTERRUPT))
+               dvisampler1_isr();
 }
index 962623e16def6e8f111d9fffc4acca7b78e0c108..76fc155df3c394ab27c81c96069cb1746a3a3621 100644 (file)
 
 #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)
 {
@@ -187,7 +19,7 @@ int main(void)
        
        dvisampler0_init_video();
        fb_enable_write(1);
-       vmix();
+       while(1) dvisampler0_service();
        
        return 0;
 }