// // Communication with ESP32 // // Components are: // a. serial interface // b. SPI interface (not yet implemented) // c. common open drain IRQ line // d. ESP32 EN and IO0 lines // module esp ( input rst_n, input clk, input cpu_valid, input [4:0] cpu_addr, input [3:0] cpu_wstrb, input [31:0] cpu_wdata, output reg [31:0] cpu_rdata, output reg irq, input tty_rx, output tty_tx, output esp_en, // ESP reset# inout esp_int, inout esp_io0, inout spi_clk, inout spi_miso, inout spi_mosi, inout spi_cs_esp_n, inout spi_cs_flash_n ); wire [31:0] cpu_reg = cpu_valid << cpu_addr; wire cpu_read = ~|cpu_wstrb; reg tx_break_q; wire tx_full; wire tx_empty; wire rx_full; wire rx_empty; wire rx_break; reg tx_flush; reg rx_flush; wire [7:0] tty_rdata; wire [31:0] tty_divisor; serial #( .BAUDRATE_SETTABLE ( 1'b1 ) ) esptty ( .rst_n ( rst_n ), .clk ( clk ), .tty_tx ( tty_tx ), .tty_rx ( tty_rx ), .tx_wstrb ( cpu_wstrb[0] & cpu_reg[0] ), .tx_data ( cpu_wdata[7:0] ), .tx_break ( tx_break_q ), .tx_full ( tx_full ), .tx_empty ( tx_empty ), .tx_flush ( tx_flush ), .rx_rstrb ( cpu_read & cpu_reg[0] ), .rx_data ( tty_rdata ), .rx_break ( rx_break ), .rx_full ( rx_full ), .rx_empty ( rx_empty ), .rx_flush ( rx_flush ), .divisor_wdata ( cpu_wdata ), .divisor_wstrb ( cpu_wstrb[0] & cpu_reg[1] ), .divisor ( tty_divisor ) ); // Control/clear status bits reg rx_break_q; reg esp_rst_q; reg esp_dl_q; // Force download boot reg esp_int_q; assign esp_en = esp_rst_q ? 1'b0 : 1'bz; assign esp_io0 = esp_dl_q ? 1'b0 : 1'bz; assign esp_int = esp_int_q ? 1'b0 : 1'bz; always @(negedge rst_n or posedge clk) if (~rst_n) begin rx_break_q <= 1'b0; tx_break_q <= 1'b0; esp_rst_q <= 1'b0; esp_dl_q <= 1'b0; esp_int_q <= 1'b0; end else begin rx_break_q <= rx_break | rx_break_q; if (cpu_wstrb[0] & cpu_reg[2]) begin if (cpu_wdata[2]) rx_break_q <= rx_break; tx_break_q <= cpu_wdata[6]; end if (cpu_wstrb[1] & cpu_reg[2]) esp_int_q <= cpu_wdata[8]; if (cpu_wstrb[2] & cpu_reg[2]) begin esp_rst_q <= cpu_wdata[16]; esp_dl_q <= cpu_wdata[17]; end end // else: !if(~rst_n) // Not used yet assign irq = 1'b0; // Output data MUX always @(*) case (cpu_addr) 5'd0: cpu_rdata = { 24'b0, tty_rdata }; 5'd1: cpu_rdata = tty_divisor; 5'd2: cpu_rdata = { 8'b0, 6'b0, esp_dl_q, esp_rst_q, 7'b0, ~esp_int, 1'b0, tx_break_q, tx_full, ~tx_empty, 1'b0, rx_break_q, rx_full, ~rx_empty }; default: cpu_rdata = 32'bx; endcase // case (cpu_addr) endmodule // esp