module Uart #( parameter DATA_LENGTH = 8 // Adjust this for the length of your data array )( output wire tx, input wire clk ); wire txBusy; wire txDone; reg [7:0] txData; reg [7:0] N_data [0:DATA_LENGTH-1]; // Array to store the data sequence reg [$clog2(DATA_LENGTH)-1:0] dataIdx = 0; // Index to track the current character being transmitted reg txStart = 1'b0; reg reset = 1'b0; reg init = 1'b1; // Initialization flag to start the first transmission wire tx_rx_Clk; reg crc_init = 1'b0; reg crc_dv = 1'b0; reg [7:0] crc_data; wire [15:0] crc_out; BaudRateGenerator2 generatorInst ( .clk(clk), .tx_rx_Clk(tx_rx_Clk) ); Uart_Transmitter txInst ( .clk(tx_rx_Clk), .start(txStart), .in(txData), .out(tx), .done(txDone), .busy(txBusy) ); // .in(fixed_data), CRC_16_CCITT_Parallel CRCInst ( .i_Clk(tx_rx_Clk), .i_Rst_n(!reset), .i_Init(crc_init), .i_DV(crc_dv), .i_Data(crc_data), .o_CRC(crc_out), .o_CRC_Reversed(), .o_CRC_Xor(), .o_CRC_Reversed_Xor() ); // Use to send binary data like 10101010 - fixed_data // always @(posedge tx_rx_Clk) begin // if (init) begin // txStart <= 1'b1; // Set txStart high for the initial transmission // init <= 1'b0; // Clear the initialization flag // end else if (txBusy & !txDone) begin // txStart <= 1'b0; // end else if (!txBusy & txDone) begin // init <= 1'b1; // end // end // Use to send request frames for Soil Sensor // State machine states localparam DATA_0 = 4'b0000, DATA_1 = 4'b0001, DATA_2 = 4'b0010, DATA_3 = 4'b0011, DATA_4 = 4'b0100, DATA_5 = 4'b0101, DATA_6 = 4'b0110, DATA_7 = 4'b0111, WAIT = 4'b1000, CRC_INIT = 4'b1001, CRC_CALC = 4'b1010, CRC_DONE = 4'b1011, DONE = 4'b1100; reg [3:0] state = CRC_INIT; // State for the state machine reg [31:0] delay_counter = 0; // Counter for delay localparam DELAY_COUNT = 20'd10000; // Adjust delay count as needed // Initialize the request frame for Nitrogen initial begin N_data[0] = 8'h01; // Address N_data[1] = 8'h03; // Function code N_data[2] = 8'h00; // Starting address high byte N_data[3] = 8'h1E; // Starting address low byte N_data[4] = 8'h00; // Quantity of registers high byte N_data[5] = 8'h01; // Quantity of registers low byte end always @(posedge tx_rx_Clk) begin if (reset) begin state <= CRC_INIT; dataIdx <= 0; txStart <= 1'b0; delay_counter <= 0; crc_init <= 1'b0; crc_dv <= 1'b0; end else begin case(state) CRC_INIT: begin // crc_init <= 1'b1; // Initialize CRC crc_dv <= 1'b0; dataIdx <= 0; state <= CRC_CALC; end CRC_CALC: begin if (dataIdx < 6) begin crc_data <= N_data[dataIdx]; crc_dv <= 1'b1; dataIdx <= dataIdx + 1; end else begin crc_dv <= 1'b0; // crc_init <= 1'b0; state <= CRC_DONE; end end CRC_DONE: begin N_data[6] <= crc_out[7:0]; // CRC low byte N_data[7] <= crc_out[15:8]; // CRC high byte dataIdx <= 0; state <= DATA_0; // Move to initial state to start transmission end DATA_0: begin // Initial state if (!txBusy && !txStart) begin txData <= N_data[dataIdx]; txStart <= 1'b1; state <= DATA_1; // Move to next state to wait for txDone end end DATA_1: begin // Wait for transmission to complete if (txDone) begin txStart <= 1'b0; state <= DATA_2; // Move to delay state delay_counter <= 0; // Initialize delay counter end end DATA_2: begin // Delay state delay_counter <= delay_counter + 1; if (delay_counter >= DELAY_COUNT) begin // Move to next data index and state dataIdx <= dataIdx + 1; if (dataIdx >= DATA_LENGTH) begin state <= DONE; // Indicate all data has been sent end else begin state <= DATA_0; // Move back to initial state to send next byte end end end DONE: begin reset = 1'b1; end endcase end end endmodule