Integrated video in. Working but cleanup-needing I2C functions.
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Tue, 29 Jun 2010 18:13:58 +0000 (20:13 +0200)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Tue, 29 Jun 2010 18:13:58 +0000 (20:13 +0200)
18 files changed:
boards/milkymist-one/rtl/setup.v
boards/milkymist-one/rtl/system.v
boards/milkymist-one/sources.mak
boards/milkymist-one/synthesis/common.ucf
boards/milkymist-one/synthesis/xst.ucf
cores/bt656cap/rtl/bt656cap.v
cores/bt656cap/rtl/bt656cap_colorspace.v
cores/bt656cap/rtl/bt656cap_ctlif.v
cores/bt656cap/rtl/bt656cap_decoder.v
cores/bt656cap/rtl/bt656cap_dma.v
cores/bt656cap/rtl/bt656cap_input.v
cores/bt656cap/test/tb_bt656cap.v
cores/fmlarb/rtl/fmlarb.v
software/demo/main.c
software/demo/shell.c
software/include/hw/bt656cap.h [new file with mode: 0644]
software/include/hw/interrupts.h
software/include/hw/ps2.h [deleted file]

index 98ea007..c647f25 100644 (file)
  * but when working on a specific part, it's very useful to be
  * able to cut down synthesis times.
  */
-`define ENABLE_AC97
-`define ENABLE_PFPU
-`define ENABLE_TMU
-`define ENABLE_ETHERNET
+//`define ENABLE_AC97
+//`define ENABLE_PFPU
+//`define ENABLE_TMU
+//`define ENABLE_ETHERNET
 `define ENABLE_FMLMETER
-//`define ENABLE_VIDEOIN
+`define ENABLE_VIDEOIN
 //`define ENABLE_MIDI
 //`define ENABLE_DMX
 //`define ENABLE_IR
index bad097f..9fa8cc4 100644 (file)
@@ -114,7 +114,7 @@ module system(
        input videoin_field,
        input videoin_llc,
        input videoin_irq_n,
-       input videoin_rst_n,
+       output videoin_rst_n,
        inout videoin_sda,
        output videoin_sdc,
 
@@ -212,6 +212,7 @@ end
 
 assign ac97_rst_n = ~sys_rst;
 assign phy_rst_n = ~sys_rst;
+assign videoin_rst_n = ~sys_rst;
 
 /*
  * We must release the Flash reset before the system reset
@@ -465,7 +466,8 @@ wire [31:0] csr_dr_uart,
                csr_dr_pfpu,
                csr_dr_tmu,
                csr_dr_ethernet,
-               csr_dr_fmlmeter;
+               csr_dr_fmlmeter,
+               csr_dr_videoin;
 
 //------------------------------------------------------------------
 // FML master wires
@@ -474,13 +476,15 @@ wire [`SDRAM_DEPTH-1:0]   fml_brg_adr,
                        fml_vga_adr,
                        fml_tmur_adr,
                        fml_tmudr_adr,
-                       fml_tmuw_adr;
+                       fml_tmuw_adr,
+                       fml_videoin_adr;
 
 wire                   fml_brg_stb,
                        fml_vga_stb,
                        fml_tmur_stb,
                        fml_tmudr_stb,
-                       fml_tmuw_stb;
+                       fml_tmuw_stb,
+                       fml_videoin_stb;
 
 wire                   fml_brg_we;
 
@@ -488,13 +492,15 @@ wire                      fml_brg_ack,
                        fml_vga_ack,
                        fml_tmur_ack,
                        fml_tmudr_ack,
-                       fml_tmuw_ack;
+                       fml_tmuw_ack,
+                       fml_videoin_ack;
 
 wire [7:0]             fml_brg_sel,
                        fml_tmuw_sel;
 
 wire [63:0]            fml_brg_dw,
-                       fml_tmuw_dw;
+                       fml_tmuw_dw,
+                       fml_videoin_dw;
 
 wire [63:0]            fml_brg_dr,
                        fml_vga_dr,
@@ -566,6 +572,15 @@ fmlarb #(
        .m4_di(64'bx),
        .m4_do(fml_tmudr_dr),
 
+       /* Video in */
+       .m5_adr(fml_videoin_adr),
+       .m5_stb(fml_videoin_stb),
+       .m5_we(1'b1),
+       .m5_ack(fml_videoin_ack),
+       .m5_sel(8'hff),
+       .m5_di(fml_videoin_dw),
+       .m5_do(),
+
        .s_adr(fml_adr),
        .s_stb(fml_stb),
        .s_we(fml_we),
@@ -604,6 +619,7 @@ csrbrg csrbrg(
                |csr_dr_tmu
                |csr_dr_ethernet
                |csr_dr_fmlmeter
+               |csr_dr_videoin
        )
 );
 
@@ -661,9 +677,11 @@ wire pfpu_irq;
 wire tmu_irq;
 wire ethernetrx_irq;
 wire ethernettx_irq;
+wire videoin_irq;
 
 wire [31:0] cpu_interrupt;
-assign cpu_interrupt = {19'd0,
+assign cpu_interrupt = {18'd0,
+       videoin_irq,
        ethernettx_irq,
        ethernetrx_irq,
        tmu_irq,
@@ -1137,6 +1155,46 @@ fmlmeter #(
 assign csr_dr_fmlmeter = 32'd0;
 `endif
 
+//---------------------------------------------------------------------------
+// Video Input
+//---------------------------------------------------------------------------
+`ifdef ENABLE_VIDEOIN
+bt656cap #(
+       .csr_addr(4'hb),
+       .fml_depth(`SDRAM_DEPTH)
+) videoin (
+       .sys_clk(sys_clk),
+       .sys_rst(sys_rst),
+
+       .csr_a(csr_a),
+       .csr_we(csr_we),
+       .csr_di(csr_dw),
+       .csr_do(csr_dr_videoin),
+
+       .irq(videoin_irq),
+
+       .fml_adr(fml_videoin_adr),
+       .fml_stb(fml_videoin_stb),
+       .fml_ack(fml_videoin_ack),
+       .fml_do(fml_videoin_dw),
+
+       .vid_clk(videoin_llc),
+       .p(videoin_p),
+       .sda(videoin_sda),
+       .sdc(videoin_sdc)
+);
+`else
+assign csr_dr_videoin = 32'd0;
+assign videoin_irq = 1'b0;
+
+assign fml_videoin_adr = {`SDRAM_DEPTH{1'bx}};
+assign fml_videoin_stb = 1'b0;
+assign fml_videoin_dw = 64'bx;
+
+assign videoin_sda = 1'bz;
+assign videoin_sdc = 1'b0;
+`endif
+
 // TODO
 assign vga_sda = 1'b0;
 assign vga_sdc = 1'b0;
@@ -1154,9 +1212,6 @@ assign usbb_oe_n = 1'b0;
 assign usbb_vp = 1'bz;
 assign usbb_vm = 1'bz;
 
-assign videoin_sda = 1'bz;
-assign videoin_sdc = 1'b0;
-
 assign midi_tx = 1'b0;
 
 assign dmxa_de = 1'b0;
index a63076e..b79c775 100644 (file)
@@ -25,42 +25,12 @@ NORFLASH_SRC=$(wildcard $(CORES_DIR)/norflash16/rtl/*.v)
 UART_SRC=$(wildcard $(CORES_DIR)/uart/rtl/*.v)
 SYSCTL_SRC=$(wildcard $(CORES_DIR)/sysctl/rtl/*.v)
 HPDMC_SRC=$(wildcard $(CORES_DIR)/hpdmc_ddr32/rtl/*.v) $(wildcard $(CORES_DIR)/hpdmc_ddr32/rtl/spartan6/*.v)
-VGAFB_SRC=                                             \
-       $(CORES_DIR)/vgafb/rtl/vgafb_pixelfeed.v        \
-       $(CORES_DIR)/vgafb/rtl/vgafb_ctlif.v            \
-       $(CORES_DIR)/vgafb/rtl/vgafb_fifo64to16.v       \
-       $(CORES_DIR)/vgafb/rtl/vgafb.v
+VGAFB_SRC=$(wildcard $(CORES_DIR)/vgafb/rtl/*.v)
 AC97_SRC=$(wildcard $(CORES_DIR)/ac97/rtl/*.v)
 PFPU_SRC=$(wildcard $(CORES_DIR)/pfpu/rtl/*.v)
-TMU_SRC=                                               \
-       $(CORES_DIR)/tmu2/rtl/tmu2_adrgen.v             \
-       $(CORES_DIR)/tmu2/rtl/tmu2_clamp.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_dpram.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_dpram_sw.v           \
-       $(CORES_DIR)/tmu2/rtl/tmu2_hdiv.v               \
-       $(CORES_DIR)/tmu2/rtl/tmu2_burst.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_pixout.v             \
-       $(CORES_DIR)/tmu2/rtl/tmu2.v                    \
-       $(CORES_DIR)/tmu2/rtl/tmu2_ctlif.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_fetchvertex.v        \
-       $(CORES_DIR)/tmu2/rtl/tmu2_hinterp.v            \
-       $(CORES_DIR)/tmu2/rtl/tmu2_qpram32.v            \
-       $(CORES_DIR)/tmu2/rtl/tmu2_vdivops.v            \
-       $(CORES_DIR)/tmu2/rtl/tmu2_decay.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_geninterp18.v        \
-       $(CORES_DIR)/tmu2/rtl/tmu2_mask.v               \
-       $(CORES_DIR)/tmu2/rtl/tmu2_qpram.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_vdiv.v               \
-       $(CORES_DIR)/tmu2/rtl/tmu2_divider17.v          \
-       $(CORES_DIR)/tmu2/rtl/tmu2_hdivops.v            \
-       $(CORES_DIR)/tmu2/rtl/tmu2_texcache.v           \
-       $(CORES_DIR)/tmu2/rtl/tmu2_vinterp.v            \
-       $(CORES_DIR)/tmu2/rtl/tmu2_blend.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_mult2.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_fdest.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_alpha.v              \
-       $(CORES_DIR)/tmu2/rtl/tmu2_buffer.v
+TMU_SRC=$(wildcard $(CORES_DIR)/tmu2/rtl/*.v)
 ETHERNET_SRC=$(wildcard $(CORES_DIR)/minimac/rtl/*.v)
 FMLMETER_SRC=$(wildcard $(CORES_DIR)/fmlmeter/rtl/*.v)
+VIDEOIN_SRC=$(wildcard $(CORES_DIR)/bt656cap/rtl/*.v)
 
-CORES_SRC=$(ASFIFO_SRC) $(CONBUS_SRC) $(LM32_SRC) $(FMLARB_SRC) $(FMLBRG_SRC) $(CSRBRG_SRC) $(NORFLASH_SRC) $(UART_SRC) $(SYSCTL_SRC) $(HPDMC_SRC) $(VGAFB_SRC) $(AC97_SRC) $(PFPU_SRC) $(TMU_SRC) $(ETHERNET_SRC) $(FMLMETER_SRC)
+CORES_SRC=$(ASFIFO_SRC) $(CONBUS_SRC) $(LM32_SRC) $(FMLARB_SRC) $(FMLBRG_SRC) $(CSRBRG_SRC) $(NORFLASH_SRC) $(UART_SRC) $(SYSCTL_SRC) $(HPDMC_SRC) $(VGAFB_SRC) $(AC97_SRC) $(PFPU_SRC) $(TMU_SRC) $(ETHERNET_SRC) $(FMLMETER_SRC) $(VIDEOIN_SRC)
index 691b049..017322a 100644 (file)
@@ -286,6 +286,9 @@ NET "videoin_rst_n" LOC = W17 | IOSTANDARD = LVCMOS33;
 NET "videoin_sda" LOC = AB17 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | PULLUP;\r
 NET "videoin_sdc" LOC = AA14 | IOSTANDARD = LVCMOS33 | SLEW = SLOW;\r
 \r
+NET "videoin_llc" TNM_NET = "GRPvideoin";\r
+TIMESPEC "TSvideoin" = PERIOD "GRPvideoin" 35 ns HIGH 50%;\r
+\r
 # ==== MIDI ====\r
 NET "midi_tx" LOC = AA21 | IOSTANDARD = LVCMOS33 | SLEW = SLOW;\r
 NET "midi_rx" LOC = AB21 | IOSTANDARD = LVCMOS33;\r
@@ -329,3 +332,6 @@ TIMESPEC "TSvga_async2" = FROM "GRPvga" TO "GRPsys" TIG;
 \r
 TIMESPEC "TSac97_async1" = FROM "GRPsys" TO "GRPac97_clk" TIG;\r
 TIMESPEC "TSac97_async2" = FROM "GRPac97_clk" TO "GRPsys" TIG;\r
+\r
+TIMESPEC "TSvideoin_async1" = FROM "GRPsys" TO "GRPvideoin" TIG;\r
+TIMESPEC "TSvideoin_async2" = FROM "GRPvideoin" TO "GRPsys" TIG;\r
index c09d1fb..786a6c8 100644 (file)
@@ -5,10 +5,10 @@ INST "ddram/clkgen_dqs" LOC = DCM_X0Y6;
 INST "ddram/b1" LOC = BUFGMUX_X2Y4;
 INST "ddram/b2" LOC = BUFGMUX_X2Y2;
 
-INST "b_phy_tx_clk0" LOC = BUFIO2_X3Y10;
-INST "b_phy_tx_clk" LOC = BUFGMUX_X3Y7;
-INST "b_phy_rx_clk0" LOC = BUFIO2_X3Y11;
-INST "b_phy_rx_clk" LOC = BUFGMUX_X3Y8;
+#INST "b_phy_tx_clk0" LOC = BUFIO2_X3Y10;
+#INST "b_phy_tx_clk" LOC = BUFGMUX_X3Y7;
+#INST "b_phy_rx_clk0" LOC = BUFIO2_X3Y11;
+#INST "b_phy_rx_clk" LOC = BUFGMUX_X3Y8;
 
 NET "ac97_clk" CLOCK_DEDICATED_ROUTE = FALSE;
 
index a485311..2aa910d 100644 (file)
@@ -46,6 +46,7 @@ wire v_field;
 wire [31:0] v_rgb565;
 bt656cap_input in(
        .sys_clk(sys_clk),
+       .sys_rst(sys_rst),
        .vid_clk(vid_clk),
 
        .p(p),
index 18d3a25..f26368a 100644 (file)
@@ -133,8 +133,11 @@ parameter S3 = 3'd2;
 parameter S4 = 3'd3;
 parameter S5 = 3'd4;
 
-always @(posedge vid_clk)
+initial state = S1;
+always @(posedge vid_clk) begin
        state <= next_state;
+       //$display("state: %d->%d (%d)", state, next_state, stb_i);
+end
 
 always @(*) begin
        mult_sela = 1'bx;
index bc36878..63c853f 100644 (file)
@@ -66,7 +66,7 @@ always @(posedge sys_clk) begin
 
                field_filter <= 2'd0;
                fml_adr_base <= {fml_depth-5{1'b0}};
-               max_bursts <= 15'd13824;
+               max_bursts <= 15'd12960;
 
                sda_oe <= 1'b0;
                sda_o <= 1'b0;
index f45ec83..8c6b50c 100644 (file)
@@ -40,6 +40,10 @@ always @(posedge vid_clk) ioreg <= p;
 
 reg [1:0] byten;
 reg [31:0] inreg;
+initial begin
+       byten <= 2'd0;
+       inreg <= 32'd0;
+end
 always @(posedge vid_clk) begin
        if(&ioreg) begin
                /* sync word */
@@ -60,6 +64,12 @@ reg in_field;
 reg in_hblank;
 reg in_vblank;
 
+initial begin
+       in_field <= 1'b0;
+       in_hblank <= 1'b0;
+       in_vblank <= 1'b0;
+       stb <= 1'b0;
+end
 always @(posedge vid_clk) begin
        stb <= 1'b0;
        if(byten == 2'd0) begin
index 1cba90e..301577e 100644 (file)
@@ -154,6 +154,7 @@ always @(*) begin
                        next_state = TRANSFER4;
                end
                TRANSFER4: begin
+                       $display("LAST BURST: %b", last_burst);
                        if(last_burst)
                                next_state = WAIT_SOF;
                        else
index 135f8fa..89bcac9 100644 (file)
@@ -17,6 +17,7 @@
 
 module bt656cap_input(
        input sys_clk,
+       input sys_rst,
        input vid_clk,
 
        input [7:0] p,
@@ -69,7 +70,7 @@ asfifo #(
        .write_en(colorspace_stb),
        .clk_write(vid_clk),
 
-       .rst(1'b0)
+       .rst(sys_rst)
 );
 assign stb = ~empty;
 
index 488be51..58a8c13 100644 (file)
@@ -51,16 +51,17 @@ initial field = 1'b0;
 initial inc = 20'd0;
 always @(posedge vid_clk) begin
        inc <= inc + 20'd1;
-       p <= inc[7:0];
-       if(inc == 20'd442368) begin
+       p <= {inc[7:1], 1'b0};
+       if(inc == 20'd414720) begin
                field <= ~field;
                p <= 8'hff;
        end
-       if(inc == 20'd442369) p <= 8'h00;
-       if(inc == 20'd442370) p <= 8'h00;
-       if(inc == 20'd442371) begin
+       if(inc == 20'd414721) p <= 8'h00;
+       if(inc == 20'd414722) p <= 8'h00;
+       if(inc == 20'd414723) begin
                p <= {1'b1, field, 6'b00_0000};
                inc <= 20'd0;
+               $display("** end of frame");
        end
 end
 
@@ -127,12 +128,13 @@ integer x;
 integer y;
 begin
        write_addr2 = write_addr[20:0]/2;
-       x = write_addr2 % 512;
-       y = write_addr2 / 512;
-       $image_set(1, x + 0, y, fml_do[63:48]);
-       $image_set(1, x + 1, y, fml_do[47:32]);
-       $image_set(1, x + 2, y, fml_do[31:16]);
-       $image_set(1, x + 3, y, fml_do[15:0]);
+       x = write_addr2 % 720;
+       y = write_addr2 / 720;
+       $display("W: %d %d", x, y);
+       $image_set(x + 0, y, fml_do[63:48]);
+       $image_set(x + 1, y, fml_do[47:32]);
+       $image_set(x + 2, y, fml_do[31:16]);
+       $image_set(x + 3, y, fml_do[15:0]);
 end
 endtask
 
@@ -183,19 +185,9 @@ always begin
        $display("Configuring DUT...");
        csrwrite(32'h04, 32'h03);
        csrread(32'h04);
+       @(posedge irq);
        csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
-       csrread(32'h04);
+       @(posedge irq);
        csrread(32'h04);
        @(posedge irq);
 
index 648abd0..3bdc314 100644 (file)
@@ -61,6 +61,14 @@ module fmlarb #(
        input [7:0] m4_sel,
        input [63:0] m4_di,
        output [63:0] m4_do,
+
+       input [fml_depth-1:0] m5_adr,
+       input m5_stb,
+       input m5_we,
+       output m5_ack,
+       input [7:0] m5_sel,
+       input [63:0] m5_di,
+       output [63:0] m5_do,
        
        output reg [fml_depth-1:0] s_adr,
        output reg s_stb,
@@ -76,6 +84,7 @@ assign m1_do = s_di;
 assign m2_do = s_di;
 assign m3_do = s_di;
 assign m4_do = s_di;
+assign m5_do = s_di;
 
 reg [2:0] master;
 reg [2:0] next_master;
@@ -98,31 +107,43 @@ always @(*) begin
                        else if(m2_stb) next_master = 3'd2;
                        else if(m3_stb) next_master = 3'd3;
                        else if(m4_stb) next_master = 3'd4;
+                       else if(m5_stb) next_master = 3'd5;
                end
                3'd1: if(~m1_stb | s_ack) begin
                        if(m0_stb) next_master = 3'd0;
                        else if(m3_stb) next_master = 3'd3;
                        else if(m4_stb) next_master = 3'd4;
+                       else if(m5_stb) next_master = 3'd5;
                        else if(m2_stb) next_master = 3'd2;
                end
                3'd2: if(~m2_stb | s_ack) begin
                        if(m0_stb) next_master = 3'd0;
                        else if(m3_stb) next_master = 3'd3;
                        else if(m4_stb) next_master = 3'd4;
+                       else if(m5_stb) next_master = 3'd5;
                        else if(m1_stb) next_master = 3'd1;
                end
                3'd3: if(~m3_stb | s_ack) begin
                        if(m0_stb) next_master = 3'd0;
                        else if(m4_stb) next_master = 3'd4;
+                       else if(m5_stb) next_master = 3'd5;
                        else if(m1_stb) next_master = 3'd1;
                        else if(m2_stb) next_master = 3'd2;
                end
-               default: if(~m4_stb | s_ack) begin // 3'd4
+               3'd4: if(~m4_stb | s_ack) begin
                        if(m0_stb) next_master = 3'd0;
+                       else if(m5_stb) next_master = 3'd5;
                        else if(m1_stb) next_master = 3'd1;
                        else if(m2_stb) next_master = 3'd2;
                        else if(m3_stb) next_master = 3'd3;
                end
+               default: if(~m5_stb | s_ack) begin // 3'd5
+                       if(m0_stb) next_master = 3'd0;
+                       else if(m1_stb) next_master = 3'd1;
+                       else if(m2_stb) next_master = 3'd2;
+                       else if(m3_stb) next_master = 3'd3;
+                       else if(m4_stb) next_master = 3'd4;
+               end
        endcase
 end
 
@@ -132,6 +153,7 @@ assign m1_ack = (master == 3'd1) & s_ack;
 assign m2_ack = (master == 3'd2) & s_ack;
 assign m3_ack = (master == 3'd3) & s_ack;
 assign m4_ack = (master == 3'd4) & s_ack;
+assign m5_ack = (master == 3'd5) & s_ack;
 
 /* Mux control signals */
 always @(*) begin
@@ -156,11 +178,16 @@ always @(*) begin
                        s_stb = m3_stb;
                        s_we = m3_we;
                end
-               default: begin // 3'd4
+               3'd4: begin
                        s_adr = m4_adr;
                        s_stb = m4_stb;
                        s_we = m4_we;
                end
+               default: begin // 3'd5
+                       s_adr = m5_adr;
+                       s_stb = m5_stb;
+                       s_we = m5_we;
+               end
        endcase
 end
 
@@ -203,10 +230,14 @@ always @(*) begin
                        s_do = m3_di;
                        s_sel = m3_sel;
                end
-               default: begin // 3'd4
+               3'd4: begin
                        s_do = m4_di;
                        s_sel = m4_sel;
                end
+               default: begin // 3'd5
+                       s_do = m5_di;
+                       s_sel = m5_sel;
+               end
        endcase
 end
 
index ee4a181..e8257c6 100644 (file)
@@ -60,13 +60,13 @@ int main()
        time_init();
        mem_init();
        vga_init();
-       snd_init();
+       //snd_init();
        pfpu_init();
        tmu_init();
        renderer_init();
        apipe_init();
        rpipe_init();
-       osd_init();
+       //osd_init();
        shell_init();
 
        while(1) {
index 83ac437..aa114a8 100644 (file)
@@ -32,6 +32,7 @@
 #include <hw/gpio.h>
 #include <hw/interrupts.h>
 #include <hw/minimac.h>
+#include <hw/bt656cap.h>
 
 #include <hal/vga.h>
 #include <hal/snd.h>
@@ -144,7 +145,7 @@ static void mw(char *addr, char *value, char *count)
                        return;
                }
        }
-       for (i=0;i<count2;i++) *addr2++ = value2;
+       for(i=0;i<count2;i++) *addr2++ = value2;
 }
 
 static int lscb(const char *filename, const char *longname, void *param)
@@ -524,6 +525,221 @@ static void echo()
        }
 }
 
+static short vbuffer[720*288] __attribute__((aligned(32)));
+
+static int i2c_init()
+{
+       unsigned timeout;
+
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDC;
+       /* Check the I2C bus is ready */
+       timeout = 1000;
+       while ((timeout > 0) && (!(CSR_BT656CAP_I2C & BT656CAP_I2C_SDAIN))) timeout--;
+
+       return timeout;
+}
+
+static void i2c_delay()
+{
+       unsigned i;
+
+       for(i=0;i<10000;i++) __asm__("nop");
+}
+
+/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
+unsigned i2c_read_bit()
+{
+       unsigned bit;
+
+       /* Let the slave drive data */
+       CSR_BT656CAP_I2C = 0;
+       i2c_delay();
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDC;
+       i2c_delay();
+       bit = CSR_BT656CAP_I2C & BT656CAP_I2C_SDAIN;
+       i2c_delay();
+       CSR_BT656CAP_I2C = 0;
+       return bit;
+}
+
+void i2c_write_bit(unsigned bit)
+{
+       if(bit) {
+               CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE|BT656CAP_I2C_SDAOUT;
+       } else {
+               CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE;
+       }
+       i2c_delay();
+       /* Clock stretching */
+       CSR_BT656CAP_I2C |= BT656CAP_I2C_SDC;
+       i2c_delay();
+       CSR_BT656CAP_I2C &= ~BT656CAP_I2C_SDC;
+}
+
+static int i2c_start;
+void i2c_start_cond(void)
+{
+       if (i2c_start) {
+               /* set SDA to 1 */
+               CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE|BT656CAP_I2C_SDAOUT;
+               i2c_delay();
+               CSR_BT656CAP_I2C |= BT656CAP_I2C_SDC;
+       }
+       /* SCL is high, set SDA from 1 to 0 */
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE|BT656CAP_I2C_SDC;
+       i2c_delay();
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE;
+       i2c_start = 1;
+}
+
+void i2c_stop_cond(void)
+{
+       /* set SDA to 0 */
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE;
+       i2c_delay();
+       /* Clock stretching */
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDAOE|BT656CAP_I2C_SDC;
+       /* SCL is high, set SDA from 0 to 1 */
+       CSR_BT656CAP_I2C = BT656CAP_I2C_SDC;
+       i2c_delay();
+       i2c_start = 0;
+}
+
+unsigned i2c_write(unsigned char byte)
+{
+       unsigned bit;
+       unsigned ack;
+
+       for(bit = 0; bit < 8; bit++) {
+               i2c_write_bit(byte & 0x80);
+               byte <<= 1;
+       }
+       ack = !i2c_read_bit();
+       return ack;
+}
+
+unsigned char i2c_read(int ack)
+{
+       unsigned char byte = 0;
+       unsigned bit;
+
+       for(bit = 0; bit < 8; bit++) {
+               byte <<= 1;
+               byte |= i2c_read_bit();
+       }
+       i2c_write_bit(!ack);
+       return byte;
+}
+
+static unsigned char vin_read_reg(unsigned char addr)
+{
+       unsigned char r;
+       
+       i2c_start_cond();
+       i2c_write(0x40);
+       i2c_write(addr);
+       i2c_start_cond();
+       i2c_write(0x41);
+       r = i2c_read(0);
+       i2c_stop_cond();
+
+       return r;
+}
+
+static void vin_write_reg(unsigned char addr, unsigned char val)
+{
+       unsigned char r;
+
+       i2c_start_cond();
+       i2c_write(0x40);
+       i2c_write(addr);
+       i2c_write(val);
+       i2c_stop_cond();
+}
+
+static void readv(char *addr)
+{
+       unsigned char a;
+       char *c;
+
+       if(*addr == 0) {
+               printf("readv <address>\n");
+               return;
+       }
+       a = strtoul(addr, &c, 0);
+       if(*c != 0) {
+               printf("incorrect address\n");
+               return;
+       }
+
+       printf("I2C init: %d\n", i2c_init());
+       i2c_delay();
+
+       printf("r: %02x\n", vin_read_reg(a));
+}
+
+static void writev(char *addr, char *value)
+{
+       unsigned char a, v;
+       char *c;
+
+       if((*addr == 0)||(*value == 0)) {
+               printf("writev <address> <value>\n");
+               return;
+       }
+       a = strtoul(addr, &c, 0);
+       if(*c != 0) {
+               printf("incorrect address\n");
+               return;
+       }
+       v = strtoul(value, &c, 0);
+       if(*c != 0) {
+               printf("incorrect value\n");
+               return;
+       }
+
+       printf("I2C init: %d\n", i2c_init());
+       i2c_delay();
+
+       vin_write_reg(a, v);
+}
+
+static const char vreg_addr[] = {
+0x15, 0x17, 0x1D, 0x0F, 0x3A, 0x3D, 0x3F, 0x50, 0xC3, 0xC4, 0x0E, 0x50, 0x52, 0x58, 0x77, 0x7C, 0x7D, 0x90, 0x91, 0x92, 0x93, 0x94, 0xCF, 0xD0, 0xD6, 0xE5, 0xD5, 0xD7, 0xE4, 0xEA, 0xE9, 0x0E
+};
+
+static const char vreg_dat[] = {
+0x00, 0x41, 0x40, 0x40, 0x16, 0xC3, 0xE4, 0x04, 0x05, 0x80, 0x80, 0x20, 0x18, 0xED, 0xC5, 0x93, 0x00, 0xC9, 0x40, 0x3C, 0xCA, 0xD5, 0x50, 0x4E, 0xDD, 0x51, 0xA0, 0xEA, 0x3E, 0x0F, 0x3E, 0x00
+};
+
+static void vtest()
+{
+       int i;
+
+       i2c_init();
+       for(i=0;i<sizeof(vreg_addr);i++)
+               vin_write_reg(vreg_addr[i], vreg_dat[i]);
+       
+       /*int x, y;
+       
+       irq_ack(IRQ_VIDEOIN);
+       CSR_BT656CAP_BASE = (unsigned int)vbuffer;
+       CSR_BT656CAP_FILTERSTATUS = BT656CAP_FILTERSTATUS_FIELD1;
+       printf("wait1\n");
+       while(!irq_pending() && IRQ_VIDEOIN);
+       irq_ack(IRQ_VIDEOIN);
+       printf("wait2\n");
+       while(!irq_pending() && IRQ_VIDEOIN);
+       irq_ack(IRQ_VIDEOIN);
+       CSR_BT656CAP_FILTERSTATUS = 0;
+       printf("wait3\n");
+       while(CSR_BT656CAP_FILTERSTATUS & BT656CAP_FILTERSTATUS_INFRAME);
+       printf("done\n");
+       for(y=0;y<288;y++)
+               for(x=0;x<720;x++)
+                       vga_frontbuffer[640*y+x] = vbuffer[720*y+x];*/
+}
+
 static char *get_token(char **str)
 {
        char *c, *d;
@@ -579,6 +795,9 @@ static void do_command(char *c)
                else if(strcmp(command, "tmutest") == 0) tmutest();
                else if(strcmp(command, "tmubench") == 0) tmubench();
                else if(strcmp(command, "echo") == 0) echo();
+               else if(strcmp(command, "vtest") == 0) vtest();
+               else if(strcmp(command, "readv") == 0) readv(param1);
+               else if(strcmp(command, "writev") == 0) writev(param1, param2);
 
                else if(strcmp(command, "") != 0) printf("Command not found: '%s'\n", command);
        }
diff --git a/software/include/hw/bt656cap.h b/software/include/hw/bt656cap.h
new file mode 100644 (file)
index 0000000..e2005c9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Milkymist VJ SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HW_BT656CAP_H
+#define __HW_BT656CAP_H
+
+#include <hw/common.h>
+
+#define CSR_BT656CAP_I2C               MMPTR(0x8000b000)
+#define CSR_BT656CAP_FILTERSTATUS      MMPTR(0x8000b004)
+#define CSR_BT656CAP_BASE              MMPTR(0x8000b008)
+#define CSR_BT656CAP_MAXBURSTS         MMPTR(0x8000b00C)
+#define CSR_BT656CAP_DONEBURSTS                MMPTR(0x8000b010)
+
+#define BT656CAP_I2C_SDAIN             (0x1)
+#define BT656CAP_I2C_SDAOUT            (0x2)
+#define BT656CAP_I2C_SDAOE             (0x4)
+#define BT656CAP_I2C_SDC               (0x8)
+
+#define BT656CAP_FILTERSTATUS_FIELD1   (0x1)
+#define BT656CAP_FILTERSTATUS_FIELD2   (0x2)
+#define BT656CAP_FILTERSTATUS_INFRAME  (0x4)
+
+#endif /* __HW_BT656CAP_H */
index de0cf3e..e75236f 100644 (file)
@@ -15,8 +15,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __INTERRUPTS_H
-#define __INTERRUPTS_H
+#ifndef __HW_INTERRUPTS_H
+#define __HW_INTERRUPTS_H
 
 #define IRQ_GPIO               (0x00000001) /* 0 */
 #define IRQ_TIMER0             (0x00000002) /* 1 */
@@ -31,5 +31,6 @@
 #define IRQ_TMU                        (0x00000400) /* 10 */
 #define IRQ_ETHRX              (0x00000800) /* 13 */
 #define IRQ_ETHTX              (0x00001000) /* 14 */
+#define IRQ_VIDEOIN            (0x00002000) /* 15 */
 
-#endif /* __INTERRUPTS_H */
+#endif /* __HW_INTERRUPTS_H */
diff --git a/software/include/hw/ps2.h b/software/include/hw/ps2.h
deleted file mode 100644 (file)
index db92c94..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Milkymist VJ SoC (Software)
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __HW_PS2_H
-#define __HW_PS2_H
-
-#include <hw/common.h>
-
-#define CSR_PS2_KEYBOARD_DATA  MMPTR(0x80007000)
-#define CSR_PS2_KEYBOARD_STATUS        MMPTR(0x80007004)
-#define CSR_PS2_MOUSE_DATA     MMPTR(0x80008000)
-#define CSR_PS2_MOUSE_STATUS   MMPTR(0x80008004)
-
-#define PS2_BUSY               (0x1)
-
-#endif /* __HW_PS2_H */