// We transmit a START, then the address (constant 0xE1), then
// [tx_byte], then [more_bytes] bytes from [mb_in]
parameter TX_IDLE = 0;
-parameter TX_ADDRESS = 1;
-parameter TX_FIRST_BYTE = 2;
-parameter TX_MORE_BYTES = 3;
-parameter TX_STOP = 4;
+parameter TX_START = 1;
+parameter TX_ADDRESS = 2;
+parameter TX_FIRST_BYTE = 3;
+parameter TX_MORE_BYTES = 4;
+parameter TX_STOP = 5;
-reg [10:0] tx_clk_divider = CLOCK_DIVIDE;
+reg [30:0] tx_clk_divider = CLOCK_DIVIDE;
reg data_out = 1'b1;
reg clk_out = 1'b1;
reg [7:0] tx_data;
reg [3:0] step = 0;
+reg [5:0] more_bytes_idx = 0;
wire [7:0] address = {7'h70, 1'b0}; // address 0x70, write
wire [15:0] address_data = {address, tx_data};
assign sda = data_out;
assign scl = clk_out;
assign is_transmitting = tx_state != TX_IDLE;
+assign mb_addr = more_bytes_idx;
always @(posedge clk) begin
- // The clk_divider counter counts down from
- // the CLOCK_DIVIDE constant. Whenever it
- // reaches 0, 1/16 of the bit period has elapsed.
- // Countdown timers for the receiving and transmitting
- // state machines are decremented.
- tx_clk_divider = tx_clk_divider - 1;
- if (!tx_clk_divider) begin
- tx_clk_divider = CLOCK_DIVIDE;
- tx_countdown = tx_countdown - 1;
- end
-
- // Transmit state machine
- case (tx_state)
+ if(tx_clk_divider) begin
+ tx_clk_divider <= tx_clk_divider - 1;
+ end else begin
+ tx_clk_divider <= CLOCK_DIVIDE - 1;
+ end
+
+ case (tx_state)
TX_IDLE: begin
if (transmit) begin
- // If the transmit flag is raised in the idle
- // state, save tx_byte for transmission
tx_data = tx_byte;
- // Send the initial, low pulse of 1 bit period
- // to signal the start, followed by the data
- data_out = 0;
- tx_state = TX_ADDRESS;
tx_bits_remaining = 8;
step = 0;
+ tx_state = TX_START;
+ tx_clk_divider <= CLOCK_DIVIDE - 1;
end
end // case: TX_IDLE
+ TX_START: begin
+ if(tx_clk_divider) begin end
+ else begin
+ data_out = 0;
+ tx_state = TX_ADDRESS;
+ end
+ end
+
TX_ADDRESS: begin
- if(step == 0) begin
+ if(tx_clk_divider) begin end
+ else if(step == 0) begin
clk_out <= 0;
step <= 1;
end else if (tx_bits_remaining == 0) begin
end // case: TX_ADDRESS
TX_FIRST_BYTE: begin
- if(step == 0) begin
+ if(tx_clk_divider) begin end
+ else if(step == 0) begin
clk_out <= 0;
step <= 1;
end else if (tx_bits_remaining == 0) begin
end else begin
step <= 0;
- tx_state <= TX_STOP;
+ if(more_bytes)
+ tx_state <= TX_MORE_BYTES;
+ else
+ tx_state <= TX_STOP;
+ tx_bits_remaining <= 8;
+ more_bytes_idx <= 0;
end
end else if(step == 1) begin
data_out <= tx_data[tx_bits_remaining - 1];
end
end // case: TX_FIRST_BYTE
+ TX_MORE_BYTES: begin
+ if(tx_clk_divider) begin end
+ else if(step == 0) begin
+ clk_out <= 0;
+ step <= 1;
+ end else if (tx_bits_remaining == 0) begin
+ if(step == 1) begin
+ data_out <= 0; // really should be z, not 0
+ step <= 2;
+ end else if(step == 2)begin
+ clk_out <= 1;
+ step <= 3;
+ end else begin
+ step <= 0;
+ tx_bits_remaining <= 8;
+
+ if(more_bytes_idx == more_bytes)
+ tx_state <= TX_STOP;
+ more_bytes_idx <= more_bytes_idx + 1;
+ end
+ end else if(step == 1) begin
+ data_out <= mb_in[tx_bits_remaining - 1];
+ step <= 2;
+ end else if(step == 2) begin
+ clk_out <= 1;
+ step <= 3;
+ end else begin // step == 3
+ tx_bits_remaining = tx_bits_remaining - 1;
+ step <= 0;
+ end
+ end // case: TX_MORE_BYTES
+
TX_STOP: begin
- if(step == 0) begin
+ if(tx_clk_divider) begin end
+ else if(step == 0) begin
clk_out <= 0;
step <= 1;
end else if(step == 1) begin