Browse Source

reset: don't reset USB of soft reset; soft reset on input BREAK

Don't reset the USB port when we do a soft system reset; this is
rather problematic when using the debug console.

Do a soft system reset when BREAK is received on the USB serial port.
H. Peter Anvin 3 years ago
parent
commit
a5abfc202c

+ 59 - 24
fpga/max80.sv

@@ -123,7 +123,9 @@ module max80 (
    // Assert internal reset for 4096 cycles after PLL lock
    parameter reset_pow2 = 12;
 
-   reg			    rst_n   = 1'b0;	// Internal reset
+   reg			    rst_n      = 1'b0;	// Internal system reset
+   reg			    hard_rst_n = 1'b0;	// Strict POR reset only
+
    tri1 [4:1]		    pll_locked;
 
    //
@@ -141,12 +143,9 @@ module max80 (
    //  sdram_clk, sys_clk    - 2:1 ratio
    //  vid_hdmiclk, vid_clk  - 5:1 ratio
    //
-   reg	    reset_cmd_q = 1'b0;
-   wire     reset_cmd;
-
    wire     master_clk;		// 336 MHz internal master clock
    pll2 pll2 (
-	      .areset ( reset_cmd_q ),
+	      .areset ( 1'b0 ),
 	      .locked ( pll_locked[2] ),
 
 	      .inclk0 ( clock_48 ),
@@ -188,22 +187,38 @@ module max80 (
    reg [23:1] sys_clk_ctr_q;
    reg [23:1] sys_clk_stb;
 
+   reg [1:0]  reset_cmd_q;
+   wire       reset_cmd;
+
    always @(negedge all_plls_locked or posedge sys_clk)
-     if (~&all_plls_locked)
+     if (~all_plls_locked)
        begin
+	  hard_rst_n    <= 1'b0;
 	  rst_n         <= 1'b0;
-	  reset_cmd_q   <= 1'b0;
+	  reset_cmd_q   <= 2'b0;
 	  sys_clk_ctr   <= 1'b0;
 	  sys_clk_ctr_q <= 1'b0;
 	  sys_clk_stb   <= 1'b0;
        end
      else
        begin
-	  sys_clk_ctr   <= sys_clk_ctr + 1'b1;
-	  sys_clk_ctr_q <= sys_clk_ctr;
-	  sys_clk_stb   <= ~sys_clk_ctr & sys_clk_ctr_q;
-	  reset_cmd_q   <= rst_n & (reset_cmd_q | reset_cmd);
-	  rst_n         <= rst_n | sys_clk_stb[reset_pow2];
+	  reset_cmd_q <= { reset_cmd_q[0], reset_cmd };
+
+	  if (reset_cmd_q == 2'b01)
+	    begin
+	       sys_clk_ctr   <= 1'b0;
+	       sys_clk_ctr_q <= 1'b0;
+	       sys_clk_stb   <= 1'b0;
+	       rst_n         <= 1'b0;
+	    end
+	  else
+	    begin
+	       sys_clk_ctr   <= sys_clk_ctr + 1'b1;
+	       sys_clk_ctr_q <= sys_clk_ctr;
+	       sys_clk_stb   <= ~sys_clk_ctr & sys_clk_ctr_q;
+	       rst_n         <= rst_n      | sys_clk_stb[reset_pow2];
+	       hard_rst_n    <= hard_rst_n | sys_clk_stb[reset_pow2];
+	    end
        end
 
    // Unused device stubs - remove when used
@@ -549,11 +564,30 @@ module max80 (
    assign sysreg_rdata[0] = SYS_MAGIC_MAX80;
    assign sysreg_rdata[1] = { max80_major, max80_minor, max80_fixes };
 
-   // Hard system reset under program control
-   assign reset_cmd =
-		     (sysreg[3] & cpu_mem_wstrb[0] & cpu_mem_wdata[0])
-		     | cpu_trap; // CPU hung
+   // System reset
+   wire        usb_rxd_break;
+   reg	       usb_rxd_break_q;
+   reg	       usb_rxd_break_rst;
 
+   always @(negedge rst_n or posedge sys_clk)
+     if (~rst_n)
+       begin
+	  usb_rxd_break_q   <= 1'b1;
+	  usb_rxd_break_rst <= 1'b0;
+       end
+     else
+       begin
+	  usb_rxd_break_q   <= usb_rxd_break;
+	  usb_rxd_break_rst <= usb_rxd_break & ~usb_rxd_break_q;
+       end
+
+   assign reset_cmd =
+		     // Explicit reset command
+		     (sysreg[3] & cpu_mem_wstrb[0] & cpu_mem_wdata[0]) |
+		     // CPU hung
+		     cpu_trap |
+		     // BREAK received on USB tty
+		     usb_rxd_break_rst;
 
   // LED indication from the CPU
    reg [2:0]   led_q;
@@ -626,7 +660,7 @@ module max80 (
 
    assign tty_cts_out  = 1'b0;	// Assert CTS#
    tty console (
-	    .rst_n ( rst_n ),
+	    .rst_n ( hard_rst_n ),
 	    .clk   ( sys_clk ),
 
 	    .valid ( iodev_valid_console ),
@@ -640,13 +674,14 @@ module max80 (
 	    );
 
    max80_usb usb (
-		  .rst_n   ( rst_n ),
-		  .clock48 ( usb_clk ),
-		  .tty_rxd ( ),
-		  .tty_txd ( tty_data_out ),
-		  .usb_dp  ( gpio[3] ),
-		  .usb_dn  ( gpio[5] ),
-		  .usb_pu  ( gpio[1] )
+		  .rst_n         ( hard_rst_n ),
+		  .clock48       ( usb_clk ),
+		  .tty_rxd       ( ),
+		  .tty_rxd_break ( usb_rxd_break ),
+		  .tty_txd       ( tty_data_out ),
+		  .usb_dp        ( gpio[3] ),
+		  .usb_dn        ( gpio[5] ),
+		  .usb_pu        ( gpio[1] )
 		  );
 
    assign tty_data_in      = tty_txd;

BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


+ 5 - 3
fpga/usb/usb.sv

@@ -10,6 +10,7 @@ module max80_usb (
 		  input  clock48,
 
 		  output tty_rxd,
+		  output tty_rxd_break,
 		  input  tty_txd,
 
 		  inout  usb_dp,
@@ -49,7 +50,7 @@ module max80_usb (
    // Reset and I/O pins
    //
    reg			 usb_rst_n;
-   always @(negedge rst_n or posedge clock48 )
+   always @(negedge rst_n or posedge clock48)
      usb_rst_n <= rst_n;	// Reset synchronized with the usb clock
 
    assign usb_dp = ( usb_rst_n & ~usb_tx_oen ) ? usb_tx_dp : 1'bz;
@@ -107,7 +108,8 @@ module max80_usb (
 	       .utmi_rxerror_i    ( utmi_rxerror ),
 	       .utmi_linestate_i  ( utmi_linestate ),
 
-	       .tx_i ( tty_txd ),
-	       .rx_o ( tty_rxd )
+	       .tx_i              ( tty_txd ),
+	       .rx_o              ( tty_rxd ),
+	       .rx_break_o        ( tty_rxd_break )
 	       );
 endmodule // max80_usb

+ 49 - 24
fpga/usb/usb_serial/src_v/usb_cdc_core.v

@@ -9,26 +9,26 @@
 //                         License: LGPL
 //-----------------------------------------------------------------
 //
-// This source file may be used and distributed without         
-// restriction provided that this copyright statement is not    
-// removed from the file and that any derivative work contains  
-// the original copyright notice and the associated disclaimer. 
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
 //
-// This source file is free software; you can redistribute it   
-// and/or modify it under the terms of the GNU Lesser General   
-// Public License as published by the Free Software Foundation; 
-// either version 2.1 of the License, or (at your option) any   
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
 // later version.
 //
-// This source 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 Lesser General Public License for more 
+// This source 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 Lesser General Public License for more
 // details.
 //
-// You should have received a copy of the GNU Lesser General    
-// Public License along with this source; if not, write to the 
-// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 // Boston, MA  02111-1307  USA
 //-----------------------------------------------------------------
 
@@ -63,6 +63,7 @@ module usb_cdc_core
     ,output          inport_accept_o
     ,output          outport_valid_o
     ,output [  7:0]  outport_data_o
+    ,output          outport_break_o
 );
 
 
@@ -273,7 +274,7 @@ wire usb_hs_w;
 //-----------------------------------------------------------------
 // Transceiver Control (high speed)
 //-----------------------------------------------------------------
-generate 
+generate
 if (USB_SPEED_HS == "True")
 begin
 
@@ -655,7 +656,7 @@ begin
         setup_frame_q   <= 1'b0;
 end
 // Detect STATUS stage (ACK for SETUP GET requests)
-// TODO: Not quite correct .... 
+// TODO: Not quite correct ....
 else if (ep0_rx_valid_w && !rx_strb_w && rx_last_w)
 begin
     setup_valid_q       <= 1'b0;
@@ -690,6 +691,9 @@ reg [15:0] ctrl_get_len_r;
 
 reg [7:0]  desc_addr_r;
 
+reg	   rx_break_q;
+reg	   rx_break_r;
+
 reg        addressed_q;
 reg        addressed_r;
 reg [6:0]  device_addr_r;
@@ -711,6 +715,7 @@ begin
     addressed_r     = addressed_q;
     configured_r    = configured_q;
     set_with_data_r = set_with_data_q;
+    rx_break_r      = 1'b0;
 
     if (setup_valid_q)
     begin
@@ -835,6 +840,9 @@ begin
         end
         `USB_CLASS_REQUEST:
         begin
+            ctrl_ack_r      = setup_set_w && setup_no_data_w;
+            set_with_data_r = setup_set_w && !setup_no_data_w;
+
             case (bRequest_w)
             `CDC_GET_LINE_CODING:
             begin
@@ -842,11 +850,14 @@ begin
                 desc_addr_r    = `ROM_CDC_LINE_CODING_ADDR;
                 ctrl_get_len_r = `ROM_CDC_LINE_CODING_SIZE;
             end
+	    `CDC_SEND_BREAK:
+	      begin
+		 rx_break_r    = (wValue_w != 16'd0);
+	      end
             default:
-            begin
-                ctrl_ack_r      = setup_set_w && setup_no_data_w;
-                set_with_data_r = setup_set_w && !setup_no_data_w;
-            end
+              begin
+		 // Do nothing
+              end
             endcase
         end
         default:
@@ -866,6 +877,7 @@ begin
     addressed_q     <= 1'b0;
     configured_q    <= 1'b0;
     set_with_data_q <= 1'b0;
+    rx_break_q      <= 1'b0;
 end
 else if (usb_reset_w)
 begin
@@ -873,6 +885,7 @@ begin
     addressed_q     <= 1'b0;
     configured_q    <= 1'b0;
     set_with_data_q <= 1'b0;
+    rx_break_q      <= 1'b0;
 end
 else
 begin
@@ -880,6 +893,7 @@ begin
     addressed_q     <= addressed_r;
     configured_q    <= configured_r;
     set_with_data_q <= set_with_data_r;
+    rx_break_q      <= rx_break_r;
 end
 
 //-----------------------------------------------------------------
@@ -1076,12 +1090,13 @@ assign ep3_rx_space_w      = 1'b0;
 reg        inport_valid_q;
 reg [7:0]  inport_data_q;
 reg [10:0] inport_cnt_q;
+reg	   outport_break_q;
 
 always @ (posedge clk_i or posedge rst_i)
 if (rst_i)
 begin
-    inport_valid_q <= 1'b0;
-    inport_data_q  <= 8'b0;
+    inport_valid_q  <= 1'b0;
+    inport_data_q   <= 8'b0;
 end
 else if (inport_accept_o)
 begin
@@ -1111,6 +1126,16 @@ assign outport_valid_o  = ep1_rx_valid_w && rx_strb_w;
 assign outport_data_o   = rx_data_w;
 assign ep1_rx_space_w   = outport_accept_i;
 
-
+always @(posedge clk_i or posedge rst_i)
+  if (rst_i)
+    outport_break_q <= 1'b0;
+  else
+    outport_break_q <= rx_break_q |
+		       (outport_break_q &
+			~setup_set_w &
+			~outport_valid_o &
+			~(inport_valid_q & ep2_tx_data_accept_w));
+
+assign outport_break_o  = outport_break_q;
 
 endmodule

+ 5 - 5
fpga/usb/usb_serial/src_v/usb_cdc_top.v

@@ -66,7 +66,8 @@ module usb_cdc_top
      input [1:0]  utmi_linestate_i,
 
      input 	  tx_i,
-     output 	  rx_o
+     output 	  rx_o,
+     output       rx_break_o
 );
 
 wire  [  7:0]  usb_rx_data_w;
@@ -76,6 +77,7 @@ wire           usb_tx_valid_w;
 wire           usb_rx_accept_w;
 wire  [  7:0]  usb_tx_data_w;
 wire           usb_rx_valid_w;
+wire           usb_rx_break_w;
 
 usb_cdc_core
 u_usb
@@ -105,6 +107,7 @@ u_usb
     ,.inport_accept_o(usb_tx_accept_w)
     ,.outport_valid_o(usb_rx_valid_w)
     ,.outport_data_o(usb_rx_data_w)
+    ,.outport_break_o(usb_rx_break_w)
 );
 
 //-----------------------------------------------------------------
@@ -445,7 +448,7 @@ else
     txd_q <= txd_r;
 
 assign rx_o = txd_q;
-
+assign rx_break_o = usb_rx_break_w;
 
 endmodule
 
@@ -529,7 +532,4 @@ assign accept_o      = (count_q != DEPTH);
 
 assign data_out_o    = ram_q[rd_ptr_q];
 
-
-
-
 endmodule

File diff suppressed because it is too large
+ 7025 - 7025
rv32/boot.mif


+ 1 - 1
rv32/io.h

@@ -38,7 +38,7 @@ static inline void __attribute__((noreturn)) reset(void)
 {
     p_maskirq(~0, 0);		/* Block all interrupts */
     for (;;)
-	asm volatile("ebreak");	/* Trigger system hang */
+	SYS_RESET = 1;
 }
 
 extern const uint32_t time_zero;

Some files were not shown because too many files changed in this diff