USB unplugged cable handling

This commit is contained in:
Polprzewodnikowy 2022-10-05 17:43:11 +02:00
parent bce2d29cfa
commit f4d3b68a5c
4 changed files with 32 additions and 9 deletions

View File

@ -387,7 +387,9 @@ module mcu_top (
REG_USB_SCR: begin REG_USB_SCR: begin
reg_rdata <= { reg_rdata <= {
4'd0, 2'd0,
usb_scb.pwrsav,
usb_scb.reset_state,
usb_scb.tx_count, usb_scb.tx_count,
usb_scb.rx_count, usb_scb.rx_count,
2'b00, 2'b00,

View File

@ -6,6 +6,8 @@ interface usb_scb ();
logic write_buffer_flush; logic write_buffer_flush;
logic [10:0] rx_count; logic [10:0] rx_count;
logic [10:0] tx_count; logic [10:0] tx_count;
logic pwrsav;
logic reset_state;
modport controller ( modport controller (
output fifo_flush, output fifo_flush,
@ -13,7 +15,9 @@ interface usb_scb ();
output reset_ack, output reset_ack,
output write_buffer_flush, output write_buffer_flush,
input rx_count, input rx_count,
input tx_count input tx_count,
input pwrsav,
input reset_state
); );
modport usb ( modport usb (
@ -22,7 +26,9 @@ interface usb_scb ();
input reset_ack, input reset_ack,
input write_buffer_flush, input write_buffer_flush,
output rx_count, output rx_count,
output tx_count output tx_count,
output pwrsav,
output reset_state
); );
endinterface endinterface
@ -144,7 +150,10 @@ module usb_ft1248 (
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
state <= next_state; state <= next_state;
cmd <= next_cmd; cmd <= next_cmd;
usb_scb.pwrsav <= !ft_pwrsav;
usb_scb.reset_state <= last_reset_status;
phase <= {phase[2:0], phase[3]}; phase <= {phase[2:0], phase[3]};
if (state == STATE_IDLE) begin if (state == STATE_IDLE) begin
phase <= 4'b0100; phase <= 4'b0100;

View File

@ -83,6 +83,8 @@ typedef enum {
#define USB_SCR_RX_COUNT_MASK (0x7FF << USB_SCR_RX_COUNT_BIT) #define USB_SCR_RX_COUNT_MASK (0x7FF << USB_SCR_RX_COUNT_BIT)
#define USB_SCR_TX_COUNT_BIT (17) #define USB_SCR_TX_COUNT_BIT (17)
#define USB_SCR_TX_COUNT_MASK (0x7FF << USB_SCR_TX_COUNT_BIT) #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_START (1 << 0)
#define DMA_SCR_STOP (1 << 1) #define DMA_SCR_STOP (1 << 1)

View File

@ -408,6 +408,7 @@ bool usb_prepare_read (uint32_t *args) {
} }
void usb_get_read_info (uint32_t *args) { void usb_get_read_info (uint32_t *args) {
uint32_t scr = fpga_reg_get(REG_USB_SCR);
args[0] = 0; args[0] = 0;
args[1] = 0; args[1] = 0;
if (p.rx_state == RX_STATE_DATA && p.rx_cmd == 'U') { 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[1] = p.rx_args[1];
} }
args[0] |= (p.read_length > 0) ? (1 << 31) : 0; 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) { void usb_init (void) {
@ -438,12 +441,19 @@ void usb_init (void) {
} }
void usb_process (void) { void usb_process (void) {
if (fpga_reg_get(REG_USB_SCR) & USB_SCR_RESET_PENDING) { uint32_t scr = fpga_reg_get(REG_USB_SCR);
if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) { if (scr & (USB_SCR_PWRSAV | USB_SCR_RESET_STATE | USB_SCR_RESET_PENDING)) {
p.tx_info.done_callback(); 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 { } else {
usb_rx_process(); usb_rx_process();
usb_tx_process(); usb_tx_process();