From f4d3b68a5c1ffd99581efa8e3378f3449a7cd20d Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Wed, 5 Oct 2022 17:43:11 +0200 Subject: [PATCH] USB unplugged cable handling --- fw/rtl/mcu/mcu_top.sv | 4 +++- fw/rtl/usb/usb_ft1248.sv | 15 ++++++++++++--- sw/controller/src/fpga.h | 2 ++ sw/controller/src/usb.c | 20 +++++++++++++++----- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/fw/rtl/mcu/mcu_top.sv b/fw/rtl/mcu/mcu_top.sv index a0dcc09..9e025df 100644 --- a/fw/rtl/mcu/mcu_top.sv +++ b/fw/rtl/mcu/mcu_top.sv @@ -387,7 +387,9 @@ module mcu_top ( REG_USB_SCR: begin reg_rdata <= { - 4'd0, + 2'd0, + usb_scb.pwrsav, + usb_scb.reset_state, usb_scb.tx_count, usb_scb.rx_count, 2'b00, diff --git a/fw/rtl/usb/usb_ft1248.sv b/fw/rtl/usb/usb_ft1248.sv index 5251c10..9b2153b 100644 --- a/fw/rtl/usb/usb_ft1248.sv +++ b/fw/rtl/usb/usb_ft1248.sv @@ -6,6 +6,8 @@ interface usb_scb (); logic write_buffer_flush; logic [10:0] rx_count; logic [10:0] tx_count; + logic pwrsav; + logic reset_state; modport controller ( output fifo_flush, @@ -13,7 +15,9 @@ interface usb_scb (); output reset_ack, output write_buffer_flush, input rx_count, - input tx_count + input tx_count, + input pwrsav, + input reset_state ); modport usb ( @@ -22,7 +26,9 @@ interface usb_scb (); input reset_ack, input write_buffer_flush, output rx_count, - output tx_count + output tx_count, + output pwrsav, + output reset_state ); endinterface @@ -144,7 +150,10 @@ module usb_ft1248 ( always_ff @(posedge clk) begin state <= next_state; cmd <= next_cmd; - + + usb_scb.pwrsav <= !ft_pwrsav; + usb_scb.reset_state <= last_reset_status; + phase <= {phase[2:0], phase[3]}; if (state == STATE_IDLE) begin phase <= 4'b0100; diff --git a/sw/controller/src/fpga.h b/sw/controller/src/fpga.h index e9082cd..a6cec0d 100644 --- a/sw/controller/src/fpga.h +++ b/sw/controller/src/fpga.h @@ -83,6 +83,8 @@ typedef enum { #define USB_SCR_RX_COUNT_MASK (0x7FF << USB_SCR_RX_COUNT_BIT) #define USB_SCR_TX_COUNT_BIT (17) #define USB_SCR_TX_COUNT_MASK (0x7FF << USB_SCR_TX_COUNT_BIT) +#define USB_SCR_RESET_STATE (1 << 28) +#define USB_SCR_PWRSAV (1 << 29) #define DMA_SCR_START (1 << 0) #define DMA_SCR_STOP (1 << 1) diff --git a/sw/controller/src/usb.c b/sw/controller/src/usb.c index e986979..ea8fa27 100644 --- a/sw/controller/src/usb.c +++ b/sw/controller/src/usb.c @@ -408,6 +408,7 @@ bool usb_prepare_read (uint32_t *args) { } void usb_get_read_info (uint32_t *args) { + uint32_t scr = fpga_reg_get(REG_USB_SCR); args[0] = 0; args[1] = 0; if (p.rx_state == RX_STATE_DATA && p.rx_cmd == 'U') { @@ -415,6 +416,8 @@ void usb_get_read_info (uint32_t *args) { args[1] = p.rx_args[1]; } args[0] |= (p.read_length > 0) ? (1 << 31) : 0; + args[0] |= (scr & USB_SCR_RESET_STATE) ? (1 << 30) : 0; + args[0] |= (scr & USB_SCR_PWRSAV) ? (1 << 29) : 0; } void usb_init (void) { @@ -438,12 +441,19 @@ void usb_init (void) { } void usb_process (void) { - if (fpga_reg_get(REG_USB_SCR) & USB_SCR_RESET_PENDING) { - if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) { - p.tx_info.done_callback(); + uint32_t scr = fpga_reg_get(REG_USB_SCR); + if (scr & (USB_SCR_PWRSAV | USB_SCR_RESET_STATE | USB_SCR_RESET_PENDING)) { + if (p.packet_pending && p.packet_info.done_callback) { + p.packet_pending = false; + p.packet_info.done_callback(); + } + if (scr & USB_SCR_RESET_PENDING) { + if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) { + p.tx_info.done_callback(); + } + usb_init(); + fpga_reg_set(REG_USB_SCR, USB_SCR_RESET_ACK); } - usb_init(); - fpga_reg_set(REG_USB_SCR, USB_SCR_RESET_ACK); } else { usb_rx_process(); usb_tx_process();