Sfoglia il codice sorgente

usb: handle SET_CONTROL_LINE_STATE USB messages

Handle the SET_CONTROL_LINE_STATE USB messages, so that we can have an
idea if there is someone listening, or if we are just plugged into a
socket.

USB_CONFIG is true if we are plugged in to a USB host, but doesn't say
anything about someone having opened the port and receiving data.
H. Peter Anvin 3 anni fa
parent
commit
c48373f9a8

+ 3 - 3
fpga/max80.qpf

@@ -19,14 +19,14 @@
 #
 # Quartus Prime
 # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 02:33:31  January 10, 2022
+# Date created = 05:30:16  January 10, 2022
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "21.1"
-DATE = "02:33:31  January 10, 2022"
+DATE = "05:30:16  January 10, 2022"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"

BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 5 - 1
fpga/usb/usb_desc.conf

@@ -52,7 +52,11 @@ sub acm_channels($$) {
 				 byte(\$data_if)), # Which data interface
 
 			usb_desc('cs_interface.acm',
-				 byte(0x04)), # Supports SEND_BREAK
+				 # Supports SET_CONTROL_LINE_STATE and
+				 # SEND_BREAK. This also means
+				 # GET|SET_LINE_CODING has to be handled,
+				 # at least vacuously.
+				 byte(0x06)),
 
 			usb_desc('cs_interface.union',
 				 byte(\$mgmt_if),	# Controlling interface

+ 4 - 4
fpga/usb/usb_desc.v

@@ -101,7 +101,7 @@ module usb_desc_rom (
 		rom[9'h050] = 8'h04;
 		rom[9'h051] = 8'h24;
 		rom[9'h052] = 8'h02;
-		rom[9'h053] = 8'h04;
+		rom[9'h053] = 8'h06;
 		rom[9'h054] = 8'h05;
 		rom[9'h055] = 8'h24;
 		rom[9'h056] = 8'h06;
@@ -167,7 +167,7 @@ module usb_desc_rom (
 		rom[9'h092] = 8'h04;
 		rom[9'h093] = 8'h24;
 		rom[9'h094] = 8'h02;
-		rom[9'h095] = 8'h04;
+		rom[9'h095] = 8'h06;
 		rom[9'h096] = 8'h05;
 		rom[9'h097] = 8'h24;
 		rom[9'h098] = 8'h06;
@@ -233,7 +233,7 @@ module usb_desc_rom (
 		rom[9'h0d4] = 8'h04;
 		rom[9'h0d5] = 8'h24;
 		rom[9'h0d6] = 8'h02;
-		rom[9'h0d7] = 8'h04;
+		rom[9'h0d7] = 8'h06;
 		rom[9'h0d8] = 8'h05;
 		rom[9'h0d9] = 8'h24;
 		rom[9'h0da] = 8'h06;
@@ -299,7 +299,7 @@ module usb_desc_rom (
 		rom[9'h116] = 8'h04;
 		rom[9'h117] = 8'h24;
 		rom[9'h118] = 8'h02;
-		rom[9'h119] = 8'h04;
+		rom[9'h119] = 8'h06;
 		rom[9'h11a] = 8'h05;
 		rom[9'h11b] = 8'h24;
 		rom[9'h11c] = 8'h06;

+ 92 - 56
fpga/usb/usb_serial/src_v/usb_cdc_core.sv

@@ -56,6 +56,8 @@
 //           8 - receive FIFO not empty after two USB frames
 //           9 - BREAK received (sticky, W1C)
 //          10 - USB device configured
+//	    11 - DTR input active
+//          12 - RTS input active
 // 3 - RW - interrupt enable register
 //        15:0 - mask of corresponding status bits
 //       31:16 - invert polarity (0 = irq on status 1, 1 = irq on status 0)
@@ -68,26 +70,31 @@ module usb_cdc_channel
    input	 rst_n,
    input	 sys_clk,
    input	 cpu_valid,
-   input  [1:0]	 cpu_addr,
+   input [1:0]	 cpu_addr,
    output [31:0] cpu_rdata,
    input [31:0]  cpu_wdata,
-   input  [3:0]	 cpu_wstrb,
+   input [3:0]	 cpu_wstrb,
    output	 irq,
 
    // Core FIFO interface
    input	 clk_i,
    input	 rst_i,
-   usb_endpoint.dstr data_ep,
-   usb_endpoint.dstr intr_ep,
+		 usb_endpoint.dstr data_ep,
+		 usb_endpoint.dstr intr_ep,
 
    // Control signals
-   input	 recv_break_i,
-   output	 recv_break_o, // sys_clk domain, reflects the status register
+   input	 recv_break_i,	// in the USB clock domain
+   output	 recv_break_o,  // sys_clk domain, reflects the status register
 
-   // USB status
-   input	 usb_configured,
+   // Control lines (RTS, DTR) in the USB clock domain
+   input	 set_control_line,
+   input [1:0]	 control_lines,
 
-   // Top of frame strobe *in sys_clk domain*
+   // USB configuration status
+   input	 usb_configured,	// in the USB clock domain
+   input	 usb_configured_s,	// in the sys_clk domain
+
+   // Top of frame strobe *in the sys_clk domain*
    input	 start_of_frame_s
    );
 
@@ -199,7 +206,7 @@ module usb_cdc_channel
 	  had_rxdata <= 2'b00;
      end
 
-   wire [15:0] status_mask = 16'b0000_0111_1111_1111; // Implemented bit mask
+   wire [15:0] status_mask = 16'b0001_1111_1111_1111; // Implemented bit mask
    reg  [15:0] irq_mask;
    reg  [15:0] irq_pol;
    wire [ 3:0] water_mask     = 4'b1111 << (4-water_bits);
@@ -208,9 +215,6 @@ module usb_cdc_channel
 
    wire        recv_break_s;
    reg	       recv_break_q;
-
-   assign irq = irq_q;
-
    synchronizer #(.width(1)) break_synchro
      (
       .rst_n ( rst_n ),
@@ -219,6 +223,24 @@ module usb_cdc_channel
       .q     ( recv_break_s )
       );
 
+   reg [1:0]   control_lines_q;
+   wire [1:0]  control_lines_s;
+   always @(posedge rst_i or posedge clk_i)
+     if (rst_i)
+       control_lines_q <= 2'b00;
+     else if (~usb_configured)
+       control_lines_q <= 2'b00;
+     else if (set_control_line)
+       control_lines_q <= control_lines;
+
+   synchronizer #(.width(2)) ctl_synchro
+     (
+      .rst_n ( rst_n ),
+      .clk   ( sys_clk ),
+      .d     ( control_lines_q ),
+      .q     ( control_lines_s )
+      );
+
    always @(negedge rst_n or posedge sys_clk)
      if (~rst_n)
        begin
@@ -263,19 +285,20 @@ module usb_cdc_channel
    assign recv_break_o = recv_break_q; // Available to external logic
 
    tri0 [15:0] status;
-   assign status[0]    = txempty;
-   assign status[1]    = txempty | (txused_msb <= water_ctl[3:4-water_bits]);
-   assign status[2]    = txfull  | (txused_msb >= water_ctl[7:8-water_bits]);
-   assign status[3]    = txfull;
+   assign status[0]     = txempty;
+   assign status[1]     = txempty | (txused_msb <= water_ctl[3:4-water_bits]);
+   assign status[2]     = txfull  | (txused_msb >= water_ctl[7:8-water_bits]);
+   assign status[3]     = txfull;
 
-   assign status[4]    = rxempty;
-   assign status[5]    = rxempty | (rxused_msb <= water_ctl[11:12-water_bits]);
-   assign status[6]    = rxfull  | (rxused_msb >= water_ctl[15:16-water_bits]);
-   assign status[7]    = rxfull;
+   assign status[4]     = rxempty;
+   assign status[5]     = rxempty | (rxused_msb <= water_ctl[11:12-water_bits]);
+   assign status[6]     = rxfull  | (rxused_msb >= water_ctl[15:16-water_bits]);
+   assign status[7]     = rxfull;
 
-   assign status[8]    = had_rxdata[1];
-   assign status[9]    = recv_break_q;
-   assign status[10]   = usb_configured;
+   assign status[8]     = had_rxdata[1];
+   assign status[9]     = recv_break_q;
+   assign status[10]    = usb_configured_s;
+   assign status[12:11] = control_lines_s;
 
    reg	       irq_q;
    always @(negedge rst_n or posedge sys_clk)
@@ -815,7 +838,10 @@ module usb_cdc_core
    reg [15:0]  desc_base_addr_r;
    reg [15:0]  desc_len_r;
 
-   reg [7:0]   rx_break_r;
+   reg         rx_break_r;
+   reg         rx_set_control_line_r;
+   reg [1:0]   rx_control_lines_r;
+   reg [2:0]   rx_channel_r;
 
    reg	       addressed_q;
    reg	       addressed_r;
@@ -841,14 +867,17 @@ module usb_cdc_core
 
    always @ *
      begin
-	ctrl_stall_r     = 1'b0;
-	ctrl_ack_r       = 1'b0;
-	ctrl_send_data_r = 1'b0;
-	device_addr_r    = device_addr_q;
-	addressed_r      = addressed_q;
-	configured_r     = configured_q;
-	set_with_data_r  = set_with_data_q;
-	rx_break_r       = 8'b0;
+	ctrl_stall_r          = 1'b0;
+	ctrl_ack_r            = 1'b0;
+	ctrl_send_data_r      = 1'b0;
+	device_addr_r         = device_addr_q;
+	addressed_r           = addressed_q;
+	configured_r          = configured_q;
+	set_with_data_r       = set_with_data_q;
+	rx_break_r            = 1'b0;
+	rx_set_control_line_r = 1'b0;
+	rx_channel_r          = wIndex_w[3:1];
+	rx_control_lines_r    = wValue_w[1:0];
 
 	if (setup_valid_q)
 	  begin
@@ -932,7 +961,7 @@ module usb_cdc_core
 		    ctrl_ack_r      = setup_set_w && setup_no_data_w;
 		    set_with_data_r = setup_set_w && !setup_no_data_w;
 
-		    case (bRequest_w)
+		    case (bRequest_w & ~wIndex_w[0])
 		      `CDC_GET_LINE_CODING:
 			begin
 			   $display("CDC_GET_LINE_CODING");
@@ -940,10 +969,11 @@ module usb_cdc_core
 			end
 		      `CDC_SEND_BREAK:
 			begin
-			   // The break index is based on interfaces,
-			   // which is 0, 2, 4, ... for the various
-			   // channels, not endpoints.
-			   rx_break_r[wIndex_w[3:1]] = |wValue_w;
+			   rx_break_r = |wValue_w;
+			end
+		      `CDC_SET_CONTROL_LINE_STATE:
+			begin
+			   rx_set_control_line_r = 1'b1;
 			end
 		      default:
 			begin
@@ -1234,24 +1264,30 @@ module usb_cdc_core
 	   usb_cdc_channel #(.data_ep_num ( cn*2+1 ),
 			     .intr_ep_num ( cn*2+2 ))
 	   cchan (
-		 .rst_n            ( rst_n ),
-		 .sys_clk          ( sys_clk ),
-		 .cpu_valid        ( cpu_valid_cdc & cpu_addr[6:4] == cn ),
-		 .cpu_addr         ( cpu_addr[3:2] ),
-		 .cpu_rdata        ( rdata_chan[cn] ),
-		 .cpu_wdata        ( cpu_wdata ),
-		 .cpu_wstrb        ( cpu_wstrb ),
-		 .irq              ( irq[cn] ),
-
-		 .clk_i            ( clk_i ),
-		 .rst_i            ( rst_i ),
-		 .data_ep          ( usb_ep[cn*2+1].dstr ),
-		 .intr_ep          ( usb_ep[cn*2+2].dstr ),
-
-		 .usb_configured   ( configured_s ),
-
-		 .recv_break_i     ( rx_break_r[cn] ),
-		 .recv_break_o     ( recv_break_o[cn] ),
+		  .rst_n            ( rst_n ),
+		  .sys_clk          ( sys_clk ),
+		  .cpu_valid        ( cpu_valid_cdc & (cpu_addr[6:4] == cn) ),
+		  .cpu_addr         ( cpu_addr[3:2] ),
+		  .cpu_rdata        ( rdata_chan[cn] ),
+		  .cpu_wdata        ( cpu_wdata ),
+		  .cpu_wstrb        ( cpu_wstrb ),
+		  .irq              ( irq[cn] ),
+
+		  .clk_i            ( clk_i ),
+		  .rst_i            ( rst_i ),
+		  .data_ep          ( usb_ep[cn*2+1].dstr ),
+		  .intr_ep          ( usb_ep[cn*2+2].dstr ),
+
+		  .usb_configured   ( configured_q ),
+		  .usb_configured_s ( configured_s ),
+
+		  .recv_break_i     ( rx_break_r & (rx_channel_r == cn) ),
+		  .recv_break_o     ( recv_break_o[cn] ),
+
+		  .set_control_line ( rx_set_control_line_r &
+				      (rx_channel_r == cn) ),
+		  .control_lines    ( rx_control_lines_r ),
+
 		 .start_of_frame_s ( start_of_frame_s )
 		 );
 	end // block: chan

+ 2 - 2
rv32/abcpun80.c

@@ -24,7 +24,7 @@
 #define PUN_IRQ		TTY_NIRQ(PUN_TTY_CHAN)
 
 #define PUN_IRQ_MASK	(TTY_STATUS_TX_FULL|TTY_STATUS_RX_EMPTY|\
-			 TTY_STATUS_USB_CONFIG)
+			 TTY_STATUS_DTR_IN)
 
 static struct abc_dev pun80_iodev;
 
@@ -52,7 +52,7 @@ pun80_refresh_input(struct abc_dev *dev, bool advance)
     PUN_IRQPOL = status;
     pun80_status = ~15 | data_loaded;
 
-    if (status & TTY_STATUS_USB_CONFIG)
+    if (status & TTY_STATUS_DTR_IN)
 	pun80_status |= 8;
     if (!(status & TTY_STATUS_TX_FULL))
 	pun80_status |= 2;

+ 64 - 64
rv32/boot.mif

@@ -54,7 +54,7 @@ CONTENT BEGIN
 002F : 6680006F;
 0030 : 4C60006F;
 0031 : 58E0006F;
-0032 : 34C0106F;
+0032 : 34E0106F;
 0033 : 5860006F;
 0034 : 5820006F;
 0035 : 5F40006F;
@@ -196,7 +196,7 @@ CONTENT BEGIN
 00BD : 86631860;
 00BE : 70970002;
 00BF : 80E74000;
-00C0 : 547DF540;
+00C0 : 547DF580;
 00C1 : 0680008B;
 00C2 : 0810878B;
 00C3 : 18704303;
@@ -379,20 +379,20 @@ CONTENT BEGIN
 0174 : 400085B7;
 0175 : 03934401;
 0176 : 82930005;
-0177 : EF63A085;
+0177 : EF63A105;
 0178 : 76370453;
 0179 : 05134000;
-017A : 20693656;
+017A : 20693696;
 017B : 3D698522;
 017C : 28854529;
 017D : 400086B7;
 017E : 40013837;
 017F : 87934701;
-0180 : 0F93A086;
+0180 : 0F93A106;
 0181 : E0634B08;
 0182 : C71105F7;
 0183 : 400078B7;
-0184 : 37B88513;
+0184 : 37F88513;
 0185 : 04132085;
 0186 : 4E198080;
 0187 : 20236E85;
@@ -451,16 +451,16 @@ CONTENT BEGIN
 01BC : 83374000;
 01BD : 06134000;
 01BE : 03930005;
-01BF : 8633A083;
+01BF : 8633A103;
 01C0 : 458140C3;
 01C1 : 00050513;
 01C2 : 8837B761;
 01C3 : 3E374000;
 01C4 : 08934001;
-01C5 : 0E93A088;
+01C5 : 0E93A108;
 01C6 : 85B34B0E;
 01C7 : 0513411E;
-01C8 : BF49A088;
+01C8 : BF49A108;
 01C9 : CE061101;
 01CA : CC22CA26;
 01CB : C64EC84A;
@@ -712,12 +712,12 @@ CONTENT BEGIN
 02C1 : 002A6C13;
 02C2 : 018AA023;
 02C3 : 85934605;
-02C4 : 05132D1C;
+02C4 : 05132D5C;
 02C5 : 4097260D;
 02C6 : 80E74000;
-02C7 : C1054280;
+02C7 : C10542A0;
 02C8 : 400077B7;
-02C9 : 6CC78513;
+02C9 : 6D078513;
 02CA : 40001097;
 02CB : AD2080E7;
 02CC : 000AA983;
@@ -725,25 +725,25 @@ CONTENT BEGIN
 02CE : 005AA023;
 02CF : 0850BF4D;
 02D0 : 8513100C;
-02D1 : 00232D1C;
+02D1 : 00232D5C;
 02D2 : CA020201;
 02D3 : 40005097;
-02D4 : 26C080E7;
+02D4 : 26E080E7;
 02D5 : 7DB74652;
 02D6 : 100C4000;
-02D7 : 6E5D8513;
+02D7 : 6E9D8513;
 02D8 : 40001097;
 02D9 : A9A080E7;
 02DA : 082C0870;
-02DB : 2D1C8513;
+02DB : 2D5C8513;
 02DC : 5097CC02;
 02DD : 80E74000;
-02DE : 4E720DE0;
+02DE : 4E720E00;
 02DF : 7FB745E2;
 02E0 : 5E834000;
 02E1 : 2F0300AE;
 02E2 : 851301CE;
-02E3 : 9693713F;
+02E3 : 9693717F;
 02E4 : 0613009E;
 02E5 : 1097FFEF;
 02E6 : 80E74000;
@@ -772,16 +772,16 @@ CONTENT BEGIN
 02FD : 00A66733;
 02FE : 40007837;
 02FF : 00E3A023;
-0300 : 74580513;
+0300 : 74980513;
 0301 : 00497913;
 0302 : 006334B5;
 0303 : 78B71609;
 0304 : 85134000;
-0305 : 3CB96A88;
+0305 : 3CB96AC8;
 0306 : 9D634A92;
 0307 : 7A37140A;
 0308 : 05134000;
-0309 : C4B36C0A;
+0309 : C4B36C4A;
 030A : DC93009B;
 030B : 4D050024;
 030C : FA933491;
@@ -807,7 +807,7 @@ CONTENT BEGIN
 0320 : 0513000F;
 0321 : 50970504;
 0322 : 80E74000;
-0323 : 4F83C300;
+0323 : 4F83C320;
 0324 : F7932AE4;
 0325 : 0723FFEF;
 0326 : 42832AF4;
@@ -864,9 +864,9 @@ CONTENT BEGIN
 0359 : 4A014A81;
 035A : 76B7B585;
 035B : 85134000;
-035C : B5556AF6;
+035C : B5556B36;
 035D : 40007C37;
-035E : 6B5C0513;
+035E : 6B9C0513;
 035F : 95E3B56D;
 0360 : 4783F40F;
 0361 : F993000C;
@@ -889,21 +889,21 @@ CONTENT BEGIN
 0372 : 40007837;
 0373 : 0693874A;
 0374 : 45910086;
-0375 : 75480613;
+0375 : 75880613;
 0376 : 60978522;
 0377 : 80E74000;
-0378 : 87378C80;
+0378 : 87378CA0;
 0379 : 0D934000;
 037A : 0993DA84;
-037B : A68385C7;
+037B : A6838607;
 037C : 84630009;
 037D : 78B71206;
 037E : 87224000;
-037F : 75C88613;
+037F : 76088613;
 0380 : 04000593;
 0381 : 60971008;
 0382 : 80E74000;
-0383 : C68389C0;
+0383 : C68389E0;
 0384 : FE132AEC;
 0385 : 09630016;
 0386 : 4E83020E;
@@ -911,7 +911,7 @@ CONTENT BEGIN
 0388 : 1763001E;
 0389 : 856E000F;
 038A : 40005097;
-038B : A8E080E7;
+038B : A90080E7;
 038C : 2AECCF83;
 038D : FFEFF793;
 038E : 2AFC8723;
@@ -928,7 +928,7 @@ CONTENT BEGIN
 0399 : 100C460D;
 039A : C632856E;
 039B : 40004097;
-039C : 132080E7;
+039C : 134080E7;
 039D : C5834629;
 039E : 19632AEC;
 039F : 483200C5;
@@ -943,7 +943,7 @@ CONTENT BEGIN
 03A8 : 79B7080E;
 03A9 : 10104000;
 03AA : 851385A2;
-03AB : 00977619;
+03AB : 00977659;
 03AC : 80E74000;
 03AD : 0E9374C0;
 03AE : 0F130220;
@@ -952,10 +952,10 @@ CONTENT BEGIN
 03B1 : 55FD0BEC;
 03B2 : 856E567D;
 03B3 : 40005097;
-03B4 : A0C080E7;
+03B4 : A0E080E7;
 03B5 : 7DB7C911;
 03B6 : 85A24000;
-03B7 : 775D8513;
+03B7 : 779D8513;
 03B8 : 40000097;
 03B9 : 71A080E7;
 03BA : 044D2303;
@@ -1039,14 +1039,14 @@ CONTENT BEGIN
 0408 : 46010085;
 0409 : 5097854A;
 040A : 80E74000;
-040B : C5118B20;
+040B : C5118B40;
 040C : 06A340A1;
 040D : 45A1041D;
 040E : 1014BFB9;
 040F : 10000613;
 0410 : 854A85A2;
 0411 : 40004097;
-0412 : 27E080E7;
+0412 : 280080E7;
 0413 : 5782F175;
 0414 : 10000293;
 0415 : FC579EE3;
@@ -1111,7 +1111,7 @@ CONTENT BEGIN
 0450 : 00851593;
 0451 : 85664601;
 0452 : 40004097;
-0453 : 790080E7;
+0453 : 792080E7;
 0454 : 0713C901;
 0455 : 06A30200;
 0456 : 059304ED;
@@ -1123,7 +1123,7 @@ CONTENT BEGIN
 045C : 85662ABD;
 045D : 409785A2;
 045E : 80E74000;
-045F : F97133A0;
+045F : F97133C0;
 0460 : 08135402;
 0461 : 16E31000;
 0462 : BF35FD04;
@@ -1136,7 +1136,7 @@ CONTENT BEGIN
 0469 : CD890085;
 046A : 05040513;
 046B : 40004097;
-046C : 552080E7;
+046C : 554080E7;
 046D : 2AE44803;
 046E : FF787713;
 046F : 2AE40723;
@@ -1274,26 +1274,26 @@ CONTENT BEGIN
 04F3 : D713010F;
 04F4 : 1F23010F;
 04F5 : C28398E0;
-04F6 : 73130003;
-04F7 : E613400F;
-04F8 : 04630F02;
-04F9 : 66130003;
-04FA : 76930086;
-04FB : E299008F;
-04FC : 00266613;
-04FD : 16C02583;
-04FE : 00C50EA3;
-04FF : 00B51563;
-0500 : 2A234D48;
-0501 : 808288A0;
-0502 : 98B00823;
-0503 : BFA54581;
-0504 : BF954585;
-0505 : 02300793;
-0506 : 00236505;
-0507 : 458198F0;
-0508 : 52C50513;
-0509 : 0000B78D;
+04F6 : 53130003;
+04F7 : 769300BF;
+04F8 : E3930013;
+04F9 : C2990F02;
+04FA : 0083E393;
+04FB : 008F7613;
+04FC : E393E219;
+04FD : 28030023;
+04FE : 0EA316C0;
+04FF : 15630075;
+0500 : 4D480105;
+0501 : 88A02A23;
+0502 : 08238082;
+0503 : 458198B0;
+0504 : 4585BF9D;
+0505 : 0793BF8D;
+0506 : 65050230;
+0507 : 98F00023;
+0508 : 05134581;
+0509 : B78552C5;
 050A : 4F525245;
 050B : 00203A52;
 050C : 20746120;
@@ -1327,9 +1327,9 @@ CONTENT BEGIN
 0528 : 6E614A20;
 0529 : 20303120;
 052A : 32323032;
-052B : 3A303020;
-052C : 313A3435;
-052D : 00000A37;
+052B : 3A353020;
+052C : 333A3832;
+052D : 00000A30;
 052E : 00000101;
 052F : 00000000;
 0530 : 00000000;
@@ -1367,13 +1367,13 @@ CONTENT BEGIN
 0550 : 0000FFFF;
 0551 : 00000000;
 0552 : 0003F000;
-0553 : 00001408;
+0553 : 0000140A;
 0554 : 00000000;
 0555 : 00000000;
 0556 : 00000000;
 0557 : 00000000;
 0558 : 00000000;
-0559 : 00001410;
+0559 : 00001412;
 055A : 00000000;
 055B : 00000000;
 055C : 00000000;

+ 7 - 2
rv32/console.c

@@ -10,8 +10,13 @@
 
 static __always_inline void __con_putc(char c)
 {
-    /* Wait for FIFO space */
-    while (CON_FLOW_CTL && (CON_STATUS & TTY_STATUS_TX_HIGH))
+    /*
+     * Wait for FIFO space IF DTR is asserted (otherwise there might
+     * not be anyone listening...
+     */
+    while (CON_FLOW_CTL &&
+	   (CON_STATUS & (TTY_STATUS_TX_HIGH|TTY_STATUS_DTR_IN))
+	   == (TTY_STATUS_TX_HIGH|TTY_STATUS_DTR_IN))
 	pause();
 
     if (c == '\n')

+ 2 - 0
rv32/ioregs.h

@@ -97,6 +97,8 @@
 #define TTY_STATUS_RX_STALE	0x0100
 #define TTY_STATUS_RX_BREAK	0x0200
 #define TTY_STATUS_USB_CONFIG	0x0400
+#define TTY_STATUS_DTR_IN	0x0800
+#define TTY_STATUS_RTS_IN	0x1000
 #define TTY_IRQEN(n)		IODEVH0(TTY,3+((n) << 2))
 #define TTY_IRQPOL(n)		IODEVH1(TTY,3+((n) << 2))