X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=i2c.v;h=9620ba05df43f6f6749e937555e2d01c0f8e9140;hb=46a95fd39e0ef114dd837bed285f8ca6acf6bb32;hp=68156179eda6376324d90c5c941cc91e1db36dbb;hpb=ffba35f814eda0a4c47af601206cf2d3ab6eab03;p=clump.git diff --git a/i2c.v b/i2c.v index 6815617..9620ba0 100644 --- a/i2c.v +++ b/i2c.v @@ -15,12 +15,13 @@ parameter CLOCK_DIVIDE = 1; // 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; @@ -31,6 +32,7 @@ reg [3:0] tx_bits_remaining; 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}; @@ -38,37 +40,37 @@ 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 @@ -97,7 +99,8 @@ always @(posedge clk) 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 @@ -110,7 +113,12 @@ always @(posedge clk) 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]; @@ -124,8 +132,41 @@ always @(posedge clk) begin 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