I2C cleanup
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Wed, 30 Jun 2010 21:36:35 +0000 (23:36 +0200)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Wed, 30 Jun 2010 21:36:35 +0000 (23:36 +0200)
13 files changed:
boards/milkymist-one/rtl/setup.v
boards/milkymist-one/rtl/system.v
boards/milkymist-one/synthesis/common.ucf
boards/milkymist-one/synthesis/xst.ucf
cores/bt656cap/rtl/bt656cap_ctlif.v
cores/bt656cap/rtl/bt656cap_dma.v
cores/bt656cap/rtl/bt656cap_input.v
software/demo/Makefile
software/demo/main.c
software/demo/shell.c
software/include/hal/vin.h [new file with mode: 0644]
software/libhal/Makefile
software/libhal/vin.c [new file with mode: 0644]

index c647f25..98ea007 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 9fa8cc4..0a791f2 100644 (file)
@@ -398,7 +398,7 @@ conbus #(
        .m5_stb_i(ethernetrxbus_stb),
        .m5_ack_o(ethernetrxbus_ack),
        // Master 6
-       .m6_dat_i(),
+       .m6_dat_i(32'bx),
        .m6_dat_o(ethernettxbus_dat_r),
        .m6_adr_i(ethernettxbus_adr),
        .m6_cti_i(ethernettxbus_cti),
index 017322a..87b815b 100644 (file)
@@ -283,6 +283,7 @@ NET "videoin_llc" LOC = Y11 | IOSTANDARD = LVCMOS33;
 \r
 NET "videoin_irq_n" LOC = R15 | IOSTANDARD = LVCMOS33;\r
 NET "videoin_rst_n" LOC = W17 | IOSTANDARD = LVCMOS33;\r
+# IOSTANDARD = I2C does not work\r
 NET "videoin_sda" LOC = AB17 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | PULLUP;\r
 NET "videoin_sdc" LOC = AA14 | IOSTANDARD = LVCMOS33 | SLEW = SLOW;\r
 \r
index 786a6c8..c09d1fb 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 63c853f..66f4e1b 100644 (file)
@@ -51,7 +51,7 @@ always @(posedge sys_clk) begin
        sda_2 <= sda_1;
 end
 
-assign sda = sda_oe ? sda_o : 1'bz;
+assign sda = (sda_oe & ~sda_o) ? 1'b0 : 1'bz;
 
 /* CSR IF */
 
index 301577e..1cba90e 100644 (file)
@@ -154,7 +154,6 @@ always @(*) begin
                        next_state = TRANSFER4;
                end
                TRANSFER4: begin
-                       $display("LAST BURST: %b", last_burst);
                        if(last_burst)
                                next_state = WAIT_SOF;
                        else
index 89bcac9..8c37c0b 100644 (file)
@@ -58,7 +58,7 @@ bt656cap_colorspace colorspace(
 wire empty;
 asfifo #(
        .data_width(33),
-       .address_width(5)
+       .address_width(6)
 ) fifo (
        .data_out({field, rgb565}),
        .empty(empty),
index 3f82906..509e7ef 100644 (file)
@@ -83,8 +83,8 @@ main.o: ../../software/include/hal/time.h ../../software/include/hal/vga.h
 main.o: ../../software/include/hal/snd.h ../../software/include/hw/ac97.h
 main.o: ../../software/include/hw/common.h ../../software/include/hal/pfpu.h
 main.o: ../../software/include/hw/pfpu.h ../../software/include/hal/tmu.h
-main.o: ../../software/include/hw/tmu.h apipe.h rpipe.h renderer.h cpustats.h
-main.o: memstats.h osd.h shell.h
+main.o: ../../software/include/hw/tmu.h ../../software/include/hal/vin.h
+main.o: apipe.h rpipe.h renderer.h cpustats.h memstats.h osd.h shell.h
 memstats.o: ../../software/include/base/board.h
 memstats.o: ../../software/include/hal/brd.h
 memstats.o: ../../software/include/hw/fmlmeter.h
@@ -131,10 +131,12 @@ shell.o: ../../software/include/base/board.h ../../software/include/hw/pfpu.h
 shell.o: ../../software/include/hw/common.h ../../software/include/hw/tmu.h
 shell.o: ../../software/include/hw/sysctl.h ../../software/include/hw/gpio.h
 shell.o: ../../software/include/hw/interrupts.h
-shell.o: ../../software/include/hw/minimac.h ../../software/include/hal/vga.h
-shell.o: ../../software/include/hal/snd.h ../../software/include/hw/ac97.h
-shell.o: ../../software/include/hal/tmu.h ../../software/include/hal/time.h
-shell.o: ../../software/include/hal/brd.h line.h wave.h rpipe.h cpustats.h
+shell.o: ../../software/include/hw/minimac.h
+shell.o: ../../software/include/hw/bt656cap.h
+shell.o: ../../software/include/hal/vga.h ../../software/include/hal/snd.h
+shell.o: ../../software/include/hw/ac97.h ../../software/include/hal/tmu.h
+shell.o: ../../software/include/hal/time.h ../../software/include/hal/brd.h
+shell.o: ../../software/include/hal/vin.h line.h wave.h rpipe.h cpustats.h
 shell.o: memstats.h shell.h renderer.h
 tick.o: ../../software/include/hal/time.h rpipe.h
 tick.o: ../../software/include/hal/tmu.h ../../software/include/hw/tmu.h
index e8257c6..a1ce479 100644 (file)
@@ -30,6 +30,7 @@
 #include <hal/snd.h>
 #include <hal/pfpu.h>
 #include <hal/tmu.h>
+#include <hal/vin.h>
 
 #include "apipe.h"
 #include "rpipe.h"
@@ -60,13 +61,14 @@ int main()
        time_init();
        mem_init();
        vga_init();
-       //snd_init();
+       snd_init();
+       vin_init();
        pfpu_init();
        tmu_init();
        renderer_init();
        apipe_init();
        rpipe_init();
-       //osd_init();
+       osd_init();
        shell_init();
 
        while(1) {
index aa114a8..b3169cd 100644 (file)
@@ -39,6 +39,7 @@
 #include <hal/tmu.h>
 #include <hal/time.h>
 #include <hal/brd.h>
+#include <hal/vin.h>
 
 #include "line.h"
 #include "wave.h"
@@ -525,138 +526,6 @@ 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;
@@ -672,10 +541,7 @@ static void readv(char *addr)
                return;
        }
 
-       printf("I2C init: %d\n", i2c_init());
-       i2c_delay();
-
-       printf("r: %02x\n", vin_read_reg(a));
+       printf("%02x\n", vin_read_reg(a));
 }
 
 static void writev(char *addr, char *value)
@@ -698,46 +564,35 @@ static void writev(char *addr, char *value)
                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 short vbuffer[720*288] __attribute__((aligned(32)));
 
-static void vtest()
+static void testv()
 {
-       int i;
-
-       i2c_init();
-       for(i=0;i<sizeof(vreg_addr);i++)
-               vin_write_reg(vreg_addr[i], vreg_dat[i]);
        
-       /*int x, y;
+       int x, y;
        
        irq_ack(IRQ_VIDEOIN);
        CSR_BT656CAP_BASE = (unsigned int)vbuffer;
        CSR_BT656CAP_FILTERSTATUS = BT656CAP_FILTERSTATUS_FIELD1;
-       printf("wait1\n");
+       printf("wait1 %d\n", CSR_TIMER0_COUNTER);
        while(!irq_pending() && IRQ_VIDEOIN);
        irq_ack(IRQ_VIDEOIN);
-       printf("wait2\n");
+       printf("wait2 %d\n", CSR_TIMER0_COUNTER);
        while(!irq_pending() && IRQ_VIDEOIN);
        irq_ack(IRQ_VIDEOIN);
        CSR_BT656CAP_FILTERSTATUS = 0;
-       printf("wait3\n");
+       printf("wait3 %d\n", CSR_TIMER0_COUNTER);
        while(CSR_BT656CAP_FILTERSTATUS & BT656CAP_FILTERSTATUS_INFRAME);
-       printf("done\n");
+       printf("done %d\n", CSR_TIMER0_COUNTER);
+       printf("nbursts=%d/%d\n", CSR_BT656CAP_DONEBURSTS, CSR_BT656CAP_MAXBURSTS);
+       flush_bridge_cache();
        for(y=0;y<288;y++)
-               for(x=0;x<720;x++)
-                       vga_frontbuffer[640*y+x] = vbuffer[720*y+x];*/
+               for(x=0;x<640;x++)
+                       vga_frontbuffer[640*y+x] = vbuffer[720*y+x];
+       flush_bridge_cache();
 }
 
 static char *get_token(char **str)
@@ -795,7 +650,7 @@ 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, "testv") == 0) testv();
                else if(strcmp(command, "readv") == 0) readv(param1);
                else if(strcmp(command, "writev") == 0) writev(param1, param2);
 
diff --git a/software/include/hal/vin.h b/software/include/hal/vin.h
new file mode 100644 (file)
index 0000000..e1aaaf4
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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 __HAL_VIN_H
+#define __HAL_VIN_H
+
+void vin_init();
+unsigned char vin_read_reg(unsigned char addr);
+void vin_write_reg(unsigned char addr, unsigned char val);
+
+#endif /* __HAL_VIN_H */
index 8ef85ee..138caac 100644 (file)
@@ -1,7 +1,7 @@
 MMDIR=../..
 include $(MMDIR)/software/include.mak
 
-OBJECTS=brd.o mem.o pfpu.o snd.o time.o tmu.o vga.o
+OBJECTS=brd.o mem.o pfpu.o snd.o time.o tmu.o vga.o vin.o
 
 all: libhal.a
 
@@ -51,3 +51,5 @@ tmu.o: ../../software/include/hal/tmu.h
 vga.o: ../../software/include/base/stdio.h
 vga.o: ../../software/include/base/stdlib.h ../../software/include/hw/vga.h
 vga.o: ../../software/include/hw/common.h ../../software/include/hal/vga.h
+vin.o: ../../software/include/hw/bt656cap.h
+vin.o: ../../software/include/hw/common.h
diff --git a/software/libhal/vin.c b/software/libhal/vin.c
new file mode 100644 (file)
index 0000000..67e1aab
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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/>.
+ */
+
+#include <hw/bt656cap.h>
+
+static int i2c_started;
+
+static int i2c_init()
+{
+       unsigned int timeout;
+
+       i2c_started = 0;
+       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 int i;
+
+       for(i=0;i<1000;i++) __asm__("nop");
+}
+
+/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
+static unsigned int i2c_read_bit()
+{
+       unsigned int 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;
+}
+
+static void i2c_write_bit(unsigned int 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 void i2c_start_cond(void)
+{
+       if(i2c_started) {
+               /* 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_started = 1;
+}
+
+static 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_started = 0;
+}
+
+static unsigned int i2c_write(unsigned char byte)
+{
+       unsigned int bit;
+       unsigned int ack;
+
+       for(bit = 0; bit < 8; bit++) {
+               i2c_write_bit(byte & 0x80);
+               byte <<= 1;
+       }
+       ack = !i2c_read_bit();
+       return ack;
+}
+
+static unsigned char i2c_read(int ack)
+{
+       unsigned char byte = 0;
+       unsigned int bit;
+
+       for(bit = 0; bit < 8; bit++) {
+               byte <<= 1;
+               byte |= i2c_read_bit();
+       }
+       i2c_write_bit(!ack);
+       return byte;
+}
+
+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
+};
+
+void vin_init()
+{
+       int i;
+       
+       if(i2c_init())
+               printf("VIN: I2C bus initialized\n");
+       else
+               printf("VIN: I2C bus initialization problem\n");
+       for(i=0;i<sizeof(vreg_addr);i++)
+               vin_write_reg(vreg_addr[i], vreg_dat[i]);
+}
+
+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;
+}
+
+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();
+}