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_rdata <= {
4'd0,
2'd0,
usb_scb.pwrsav,
usb_scb.reset_state,
usb_scb.tx_count,
usb_scb.rx_count,
2'b00,

View File

@ -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
@ -145,6 +151,9 @@ module usb_ft1248 (
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;

View File

@ -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)

View File

@ -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();