Infrared working
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 2 Jul 2010 16:00:56 +0000 (18:00 +0200)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 2 Jul 2010 16:00:56 +0000 (18:00 +0200)
boards/milkymist-one/rtl/setup.v
boards/milkymist-one/rtl/system.v
boards/milkymist-one/sources.mak
cores/rc5/rtl/rc5.v [new file with mode: 0644]
software/demo/shell.c
software/include/hw/capabilities.h
software/include/hw/interrupts.h

index e58568f..76ae147 100644 (file)
@@ -30,7 +30,7 @@
 //`define ENABLE_VIDEOIN
 //`define ENABLE_MIDI
 //`define ENABLE_DMX
-//`define ENABLE_IR
+`define ENABLE_IR
 //`define ENABLE_USB
 
 /*
index 6e053d3..86079ef 100644 (file)
@@ -329,7 +329,7 @@ wire                brg_ack,
 conbus #(
        .s_addr_w(3),
        .s0_addr(3'b000),       // norflash     0x00000000
-       .s1_addr(3'b001),       // free         0x20000000
+       .s1_addr(3'b001),       // USB?         0x20000000
        .s2_addr(3'b010),       // FML bridge   0x40000000
        .s3_addr(3'b100),       // CSR bridge   0x80000000
        .s4_addr(3'b101)        // free         0xa0000000
@@ -467,7 +467,8 @@ wire [31:0] csr_dr_uart,
                csr_dr_tmu,
                csr_dr_ethernet,
                csr_dr_fmlmeter,
-               csr_dr_videoin;
+               csr_dr_videoin,
+               csr_dr_ir;
 
 //------------------------------------------------------------------
 // FML master wires
@@ -620,6 +621,7 @@ csrbrg csrbrg(
                |csr_dr_ethernet
                |csr_dr_fmlmeter
                |csr_dr_videoin
+               |csr_dr_ir
        )
 );
 
@@ -678,9 +680,11 @@ wire tmu_irq;
 wire ethernetrx_irq;
 wire ethernettx_irq;
 wire videoin_irq;
+wire ir_irq;
 
 wire [31:0] cpu_interrupt;
-assign cpu_interrupt = {18'd0,
+assign cpu_interrupt = {17'd0,
+       ir_irq,
        videoin_irq,
        ethernettx_irq,
        ethernetrx_irq,
@@ -890,6 +894,17 @@ vga #(
 );
 
 //---------------------------------------------------------------------------
+// Memory card
+//---------------------------------------------------------------------------
+`ifdef ENABLE_MEMORYCARD
+// TODO
+`else
+assign mc_d[3:0] = 4'bz;
+assign mc_cmd = 1'bz;
+assign mc_clk = 1'b0;
+`endif
+
+//---------------------------------------------------------------------------
 // AC97
 //---------------------------------------------------------------------------
 `ifdef ENABLE_AC97
@@ -1198,11 +1213,58 @@ assign videoin_sda = 1'bz;
 assign videoin_sdc = 1'b0;
 `endif
 
+//---------------------------------------------------------------------------
+// MIDI
+//---------------------------------------------------------------------------
+`ifdef ENABLE_MIDI
 // TODO
-assign mc_d[3:0] = 4'bz;
-assign mc_cmd = 1'bz;
-assign mc_clk = 1'b0;
+`else
+assign midi_tx = 1'b0;
+`endif
+
+//---------------------------------------------------------------------------
+// DMX
+//---------------------------------------------------------------------------
+`ifdef ENABLE_DMX
+// TODO
+`else
+assign dmxa_de = 1'b0;
+assign dmxa_d = 1'b0;
+assign dmxb_de = 1'b0;
+assign dmxb_d = 1'b0;
+`endif
 
+//---------------------------------------------------------------------------
+// IR
+//---------------------------------------------------------------------------
+`ifdef ENABLE_IR
+rc5 #(
+       .csr_addr(4'hc),
+       .clk_freq(`CLOCK_FREQUENCY),
+) ir (
+       .sys_clk(sys_clk),
+       .sys_rst(sys_rst),
+
+       .csr_a(csr_a),
+       .csr_we(csr_we),
+       .csr_di(csr_dw),
+       .csr_do(csr_dr_ir),
+
+       .rx_irq(ir_irq),
+
+       .rx(~ir_rx)
+);
+`else
+assign csr_dr_ir = 32'd0;
+assign ir_irq = 1'b0;
+`endif
+
+//---------------------------------------------------------------------------
+// USB
+//---------------------------------------------------------------------------
+`ifdef ENABLE_USB
+// TODO
+`else
 assign usba_spd = 1'b0;
 assign usba_oe_n = 1'b0;
 assign usba_vp = 1'bz;
@@ -1211,12 +1273,6 @@ assign usbb_spd = 1'b0;
 assign usbb_oe_n = 1'b0;
 assign usbb_vp = 1'bz;
 assign usbb_vm = 1'bz;
-
-assign midi_tx = 1'b0;
-
-assign dmxa_de = 1'b0;
-assign dmxa_d = 1'b0;
-assign dmxb_de = 1'b0;
-assign dmxb_d = 1'b0;
+`endif
 
 endmodule
index b79c775..ef4fdbe 100644 (file)
@@ -32,5 +32,6 @@ 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)
+IR_SRC=$(wildcard $(CORES_DIR)/rc5/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) $(VIDEOIN_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) $(IR_SRC)
diff --git a/cores/rc5/rtl/rc5.v b/cores/rc5/rtl/rc5.v
new file mode 100644 (file)
index 0000000..6f48bae
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Milkymist VJ SoC
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ * Copyright (C) 2007 Das Labor
+ *
+ * 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/>.
+ */
+
+module rc5 #(
+       parameter csr_addr = 4'h0,
+       parameter clk_freq = 100000000
+) (
+       input sys_clk,
+       input sys_rst,
+
+       input [13:0] csr_a,
+       input csr_we,
+       input [31:0] csr_di,
+       output reg [31:0] csr_do,
+
+       output reg rx_irq,
+
+       input rx
+);
+
+//-----------------------------------------------------------------
+// enable16 generator
+//-----------------------------------------------------------------
+parameter divisor = clk_freq/570/16;
+
+reg [15:0] enable16_counter;
+
+wire enable16;
+assign enable16 = (enable16_counter == 16'd0);
+
+always @(posedge sys_clk) begin
+       if(sys_rst)
+               enable16_counter <= divisor - 1;
+       else begin
+               enable16_counter <= enable16_counter - 16'd1;
+               if(enable16)
+                       enable16_counter <= divisor - 1;
+       end
+end
+
+//-----------------------------------------------------------------
+// Synchronize rx
+//-----------------------------------------------------------------
+reg rx1;
+reg rx2;
+
+always @(posedge sys_clk) begin
+       rx1 <= rx;
+       rx2 <= rx1;
+end
+
+//-----------------------------------------------------------------
+// RX Logic
+//-----------------------------------------------------------------
+reg rx_busy;
+reg [3:0] rx_count16;
+reg [3:0] rx_bitcount;
+reg [12:0] rx_reg;
+reg [12:0] rx_data;
+
+always @(posedge sys_clk) begin
+       if(sys_rst) begin
+               rx_irq <= 1'b0;
+               rx_busy <= 1'b0;
+               rx_count16 <= 4'd0;
+               rx_bitcount <= 4'd0;
+       end else begin
+               rx_irq <= 1'b0;
+
+               if(enable16) begin
+                       if(~rx_busy) begin // look for start bit
+                               if(rx2) begin // start bit found
+                                       rx_busy <= 1'b1;
+                                       rx_count16 <= 4'd11;
+                                       rx_bitcount <= 4'd0;
+                               end
+                       end else begin
+                               rx_count16 <= rx_count16 + 4'd1;
+
+                               if(rx_count16 == 4'd0) begin // sample
+                                       rx_bitcount <= rx_bitcount + 4'd1;
+
+                                       if(rx_bitcount == 4'd0) begin // verify startbit
+                                               if(~rx2)
+                                                       rx_busy <= 1'b0;
+                                       end else if(rx_bitcount == 4'd14) begin
+                                               rx_busy <= 1'b0;
+                                               rx_data <= rx_reg;
+                                               rx_irq <= 1'b1;
+                                       end else
+                                               rx_reg <= {rx_reg[11:0], rx2};
+                               end
+                       end
+               end
+       end
+end
+
+//-----------------------------------------------------------------
+// CSR interface
+//-----------------------------------------------------------------
+
+wire csr_selected = csr_a[13:10] == csr_addr;
+
+always @(posedge sys_clk) begin
+       if(sys_rst) begin
+               csr_do <= 32'd0;
+       end else begin
+               csr_do <= 32'd0;
+               if(csr_selected)
+                       csr_do <= rx_data;
+       end
+end
+
+endmodule
index 20da1a2..baa187e 100644 (file)
@@ -33,6 +33,7 @@
 #include <hw/interrupts.h>
 #include <hw/minimac.h>
 #include <hw/bt656cap.h>
+#include <hw/rc5.h>
 
 #include <hal/vga.h>
 #include <hal/snd.h>
@@ -606,6 +607,25 @@ static void testv()
        flush_bridge_cache();
 }
 
+static void irtest()
+{
+       unsigned int r;
+       
+       irq_ack(IRQ_IR);
+       while(!readchar_nonblock()) {
+               if(irq_pending() & IRQ_IR) {
+                       r = CSR_RC5_RX;
+                       irq_ack(IRQ_IR);
+                       printf("%04x - fld:%d ctl:%d sys:%d cmd:%d\n", r,
+                              (r & 0x1000) >> 12,
+                              (r & 0x0800) >> 11,
+                              (r & 0x07c0) >> 6,
+                              r & 0x003f);
+                       
+               }
+       }
+}
+
 static char *get_token(char **str)
 {
        char *c, *d;
@@ -665,6 +685,7 @@ static void do_command(char *c)
                else if(strcmp(command, "testv") == 0) testv();
                else if(strcmp(command, "readv") == 0) readv(param1);
                else if(strcmp(command, "writev") == 0) writev(param1, param2);
+               else if(strcmp(command, "irtest") == 0) irtest();
 
                else if(strcmp(command, "") != 0) printf("Command not found: '%s'\n", command);
        }
index b2f9bce..26b1aa3 100644 (file)
@@ -28,6 +28,6 @@
 #define CAP_MIDI               (0x00000080)
 #define CAP_DMX                        (0x00000100)
 #define CAP_IR                 (0x00000200)
-#define CAP_USB                        (0x00000200)
+#define CAP_USB                        (0x00000400)
 
 #endif /* __HW_CAPABILITIES */
index e75236f..bfd6ab6 100644 (file)
@@ -32,5 +32,6 @@
 #define IRQ_ETHRX              (0x00000800) /* 13 */
 #define IRQ_ETHTX              (0x00001000) /* 14 */
 #define IRQ_VIDEOIN            (0x00002000) /* 15 */
+#define IRQ_IR                 (0x00004000) /* 16 */
 
 #endif /* __HW_INTERRUPTS_H */