Edge sensitive sysctl irqs
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 13 Nov 2009 14:53:54 +0000 (15:53 +0100)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Fri, 13 Nov 2009 14:53:54 +0000 (15:53 +0100)
12 files changed:
boards/avnet-sp3aevl/rtl/system.v
boards/milkymist-one/rtl/system.v
boards/xilinx-ml401/synthesis/common.ucf
cores/sysctl/rtl/sysctl.v
software/demo/ui.c
software/include/hw/sysctl.h
software/libhal/pfpu.c
software/libhal/ps2.c
software/libhal/slowout.c
software/libhal/snd.c
software/libhal/time.c
software/libhal/tmu.c

index 62b6b08..a0cc01b 100644 (file)
@@ -334,7 +334,6 @@ csrbrg csrbrg(
        )
 );
 
-
 //---------------------------------------------------------------------------
 // Interrupts
 //---------------------------------------------------------------------------
@@ -344,13 +343,13 @@ wire timer1_irq;
 wire uartrx_irq;
 wire uarttx_irq;
 
-wire [31:0] cpu_interrupt_n;
-assign cpu_interrupt_n = {{27{1'b1}},
-       ~uarttx_irq,
-       ~uartrx_irq,
-       ~timer1_irq,
-       ~timer0_irq,
-       ~gpio_irq
+wire [31:0] cpu_interrupt;
+assign cpu_interrupt = {27'd0,
+       uarttx_irq,
+       uartrx_irq,
+       timer1_irq,
+       timer0_irq,
+       gpio_irq
 };
 
 //---------------------------------------------------------------------------
@@ -359,7 +358,7 @@ assign cpu_interrupt_n = {{27{1'b1}},
 lm32_top cpu(
        .clk_i(sys_clk),
        .rst_i(sys_rst),
-       .interrupt_n(cpu_interrupt_n),
+       .interrupt(cpu_interrupt),
 
        .I_ADR_O(cpuibus_adr),
        .I_DAT_I(cpuibus_dat_r),
index f59be49..6b10f8a 100644 (file)
@@ -580,19 +580,19 @@ wire ac97dmaw_irq;
 wire pfpu_irq;
 wire tmu_irq;
 
-wire [31:0] cpu_interrupt_n;
-assign cpu_interrupt_n = {{21{1'b1}},
-       ~tmu_irq,
-       ~pfpu_irq,
-       ~ac97dmaw_irq,
-       ~ac97dmar_irq,
-       ~ac97crreply_irq,
-       ~ac97crrequest_irq,
-       ~uarttx_irq,
-       ~uartrx_irq,
-       ~timer1_irq,
-       ~timer0_irq,
-       ~gpio_irq
+wire [31:0] cpu_interrupt;
+assign cpu_interrupt = {21'd0,
+       tmu_irq,
+       pfpu_irq,
+       ac97dmaw_irq,
+       ac97dmar_irq,
+       ac97crreply_irq,
+       ac97crrequest_irq,
+       uarttx_irq,
+       uartrx_irq,
+       timer1_irq,
+       timer0_irq,
+       gpio_irq
 };
 
 //---------------------------------------------------------------------------
@@ -601,7 +601,7 @@ assign cpu_interrupt_n = {{21{1'b1}},
 lm32_top cpu(
        .clk_i(sys_clk),
        .rst_i(sys_rst),
-       .interrupt_n(cpu_interrupt_n),
+       .interrupt(cpu_interrupt),
 
        .I_ADR_O(cpuibus_adr),
        .I_DAT_I(cpuibus_dat_r),
index 48cd89f..d0e04af 100644 (file)
@@ -338,6 +338,7 @@ NET "ac97_sync" LOC = D9 | IOSTANDARD = LVCMOS25;
 NET "ac97_clk" TNM_NET = "clkac97";
 TIMESPEC "TSclkac97" = PERIOD "clkac97" 80 HIGH 50%;
 
-# PS2 signals
+# ==== PS/2  ====
+# "keyboard" connector
 NET "ps2_clk1"  LOC = D2 | IOSTANDARD = LVCMOS25;
 NET "ps2_data1" LOC = G9 | IOSTANDARD = LVCMOS25;
index c7be6c8..5690287 100644 (file)
@@ -25,10 +25,10 @@ module sysctl #(
        input sys_rst,
        
        /* Interrupts */
-       output gpio_irq,
-       output timer0_irq,
-       output timer1_irq,
-   
+       output reg gpio_irq,
+       output reg timer0_irq,
+       output reg timer1_irq,
+
        /* CSR bus interface */
        input [13:0] csr_a,
        input csr_we,
@@ -55,13 +55,14 @@ end
 /* Detect level changes and generate IRQs */
 reg [ninputs-1:0] gpio_inbefore;
 always @(posedge sys_clk) gpio_inbefore <= gpio_in;
-
-reg [ninputs-1:0] gpio_irqact;
-reg [ninputs-1:0] gpio_irqen;
-
 wire [ninputs-1:0] gpio_diff = gpio_inbefore ^ gpio_in;
-
-assign gpio_irq = |(gpio_irqact & gpio_irqen);
+reg [ninputs-1:0] gpio_irqen;
+always @(posedge sys_clk) begin
+       if(sys_rst)
+               gpio_irq <= 1'b0;
+       else
+               gpio_irq <= |(gpio_diff & gpio_irqen);
+end
 
 /*
  * Dual timer
@@ -88,9 +89,11 @@ wire csr_selected = csr_a[13:10] == csr_addr;
 always @(posedge sys_clk) begin
        if(sys_rst) begin
                csr_do <= 32'd0;
+
+               timer0_irq <= 1'b0;
+               timer1_irq <= 1'b0;
        
                gpio_outputs <= {noutputs{1'b0}};
-               gpio_irqact <= {ninputs{1'b0}};
                gpio_irqen <= {ninputs{1'b0}};
                
                en0 <= 1'b0;
@@ -104,18 +107,24 @@ always @(posedge sys_clk) begin
                compare0 <= 32'hFFFFFFFF;
                compare1 <= 32'hFFFFFFFF;
        end else begin
-               /* Handle GPIO */
-               gpio_irqact <= gpio_irqact|gpio_diff;
-       
+               timer0_irq <= 1'b0;
+               timer1_irq <= 1'b0;
+
                /* Handle timer 0 */
                if( en0 & ~match0) counter0 <= counter0 + 32'd1;
-               if( en0 &  match0) trig0 <= 1'b1;
+               if( en0 &  match0) begin
+                       trig0 <= 1'b1;
+                       timer0_irq <= 1'b1;
+               end
                if( ar0 &  match0) counter0 <= 32'd1;
                if(~ar0 &  match0) en0 <= 1'b0;
 
                /* Handle timer 1 */
                if( en1 & ~match1) counter1 <= counter1 + 32'd1;
-               if( en1 &  match1) trig1 <= 1'b1;
+               if( en1 &  match1) begin
+                       trig1 <= 1'b1;
+                       timer1_irq <= 1'b1;
+               end
                if( ar1 &  match1) counter1 <= 32'd1;
                if(~ar1 &  match1) en1 <= 1'b0;
        
@@ -127,8 +136,7 @@ always @(posedge sys_clk) begin
                                        /* GPIO registers */
                                        // 0000 is GPIO IN and is read-only
                                        4'b0001: gpio_outputs <= csr_di[noutputs-1:0];
-                                       4'b0010: gpio_irqact <= (gpio_irqact|gpio_diff) & ~csr_di[ninputs-1:0];
-                                       4'b0011: gpio_irqen <= csr_di[ninputs-1:0];
+                                       4'b0010: gpio_irqen <= csr_di[ninputs-1:0];
                                        
                                        /* Timer 0 registers */
                                        4'b0100: begin
@@ -155,8 +163,7 @@ always @(posedge sys_clk) begin
                                /* GPIO registers */
                                4'b0000: csr_do <= gpio_in;
                                4'b0001: csr_do <= gpio_outputs;
-                               4'b0010: csr_do <= gpio_irqact;
-                               4'b0011: csr_do <= gpio_irqen;
+                               4'b0010: csr_do <= gpio_irqen;
                                
                                /* Timer 0 registers */
                                4'b0100: csr_do <= {en0, ar0, trig0};
index d424d36..c16b7be 100644 (file)
@@ -237,8 +237,7 @@ void ui_init()
        for(i=1;i<KEY_COUNT;i++)
                last_press[i] = last_press[0];
 
-       CSR_GPIO_CHANGES = UI_GPIO;
-       CSR_GPIO_INT |= UI_GPIO;
+       CSR_GPIO_INTEN |= UI_GPIO;
 
        mask = irq_getmask();
        mask |= IRQ_GPIO;
@@ -287,8 +286,6 @@ void ui_isr_key()
 {
        unsigned int keys;
 
-       CSR_GPIO_CHANGES = CSR_GPIO_CHANGES & UI_GPIO;
-
        keys = CSR_GPIO_IN;
 
        if(keys & GPIO_PBN)
index d9f86a0..1d03808 100644 (file)
@@ -22,8 +22,7 @@
 
 #define CSR_GPIO_IN            MMPTR(0x80001000)
 #define CSR_GPIO_OUT           MMPTR(0x80001004)
-#define CSR_GPIO_CHANGES       MMPTR(0x80001008)
-#define CSR_GPIO_INT           MMPTR(0x8000100C)
+#define CSR_GPIO_INTEN         MMPTR(0x80001008)
 
 #define CSR_TIMER0_CONTROL     MMPTR(0x80001010)
 #define CSR_TIMER0_COMPARE     MMPTR(0x80001014)
index 9c82ce5..445051f 100644 (file)
@@ -35,7 +35,9 @@ void pfpu_init()
 {
        unsigned int mask;
 
-       CSR_PFPU_CTL = 0; /* Ack any pending IRQ */
+       /* Reset PFPU */
+       CSR_PFPU_CTL = 0;
+       irq_ack(IRQ_PFPU);
 
        produce = 0;
        consume = 0;
index d0e988d..43d0500 100644 (file)
@@ -38,6 +38,8 @@ void ps2_init()
        consume = 0;
        level = 0;
 
+       irq_ack(IRQ_PS2);
+
        mask = irq_getmask();
        mask |= IRQ_PS2;
        irq_setmask(mask);
index 1f372f2..a2cd749 100644 (file)
@@ -47,7 +47,9 @@ void slowout_init()
        level = 0;
        cts = 1;
 
-       CSR_TIMER1_CONTROL = 0; /* Disable timer + ack any pending IRQ */
+       /* Reset timer */
+       CSR_TIMER1_CONTROL = 0;
+       irq_ack(IRQ_TIMER1);
 
        mask = irq_getmask();
        mask |= IRQ_TIMER1;
@@ -70,10 +72,8 @@ void slowout_isr()
        level--;
        if(level > 0)
                slowout_start(&queue[consume]);
-       else {
-               CSR_TIMER1_CONTROL = 0; /* Ack IRQ */
+       else
                cts = 1;
-       }
 }
 
 int slowout_queue(unsigned int duration, unsigned int mask)
index 4fcba56..8a31c64 100644 (file)
@@ -42,8 +42,12 @@ void snd_init()
        
        snd_cr_request = 0;
        snd_cr_reply = 0;
+
+       /* Reset AC'97 controller */
+       CSR_AC97_CRCTL = 0;
        CSR_AC97_DCTL = 0;
        CSR_AC97_UCTL = 0;
+       irq_ack(IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW);
        
        mask = irq_getmask();
        mask |= IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW;
index edc5445..7844e92 100644 (file)
@@ -35,6 +35,7 @@ void time_init()
        CSR_TIMER0_COUNTER = 0;
        CSR_TIMER0_COMPARE = brd_desc->clk_frequency;
        CSR_TIMER0_CONTROL = TIMER_AUTORESTART|TIMER_ENABLE;
+       irq_ack(IRQ_TIMER0);
 
        mask = irq_getmask();
        mask |= IRQ_TIMER0;
@@ -46,7 +47,6 @@ void time_init()
 void time_isr()
 {
        sec++;
-       CSR_TIMER0_CONTROL = TIMER_AUTORESTART|TIMER_ENABLE; /* Ack interrupt */
        time_tick();
 }
 
index da30ae7..721970f 100644 (file)
@@ -42,7 +42,8 @@ void tmu_init()
        level = 0;
        cts = 1;
 
-       CSR_TMU_CTL = 0; /* Ack any pending IRQ */
+       CSR_TMU_CTL = 0;
+       irq_ack(IRQ_TMU);
 
        mask = irq_getmask();
        mask |= IRQ_TMU;