diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..44a52bc --- /dev/null +++ b/Readme.md @@ -0,0 +1,51 @@ +# Updates to the PDF spec +The PDF spec does not cover the I2C target extensions in this repo. +The following sections give an overview of the changes. + +## Command register +The target extension is the TACK bit. + +| Bit | Access | Description | +|-----|--------|----------------------------------| +| [7] | W | STA - Transaction start | +| [6] | W | ST0 - Transaction stop | +| [5] | W | RD - Transaction read | +| [4] | W | WR - Transaction write | +| [3] | W | ACK - Transaction acknowledge | +| [2] | W | RSVD | +| [1] | W | TACK - Target acknowledge | +| [0] | W | IACK - Interrupt acknowledge | + +## Status register +The target extensions are the target mode, target +data available, and the target data request bits. + +| Bit | Access | Description | +|-----|--------|---------------------------| +| [7] | R | RxACK | +| [6] | R | Busy | +| [5] | R | Arbitration Lost | +| [4] | R | Target Mode | +| [3] | R | Target Data Available | +| [2] | R | Target Data Request | +| [1] | R | Transfer in Progress | +| [0] | R | Interrupt Acknowledge | + +### Target Mode +AFAICT, this is NOOP. + +### Target Data Available +Indicates that valid data was received by the target extension. + +### Target Data Request +Indicates that valid data is required by the target extension +for transmit. + +## Target operations +When Target Data Available is high, valid receive data is in the Receive +register. Acknowledge by setting the Transmit register to 0x00 and then +set TACK in the Command register to 1. + +When Target Data Request is is high, the target needs to send data. +Acknowledge by setting the Transmit register with valid data and then +set TACK in the Command register to 1. diff --git a/rtl/verilog/i2c_master_bit_ctrl.v b/rtl/verilog/i2c_master_bit_ctrl.v index a6a79c1..5fe07ef 100644 --- a/rtl/verilog/i2c_master_bit_ctrl.v +++ b/rtl/verilog/i2c_master_bit_ctrl.v @@ -587,7 +587,6 @@ module i2c_master_bit_ctrl ( assign sda_oen = master_mode ? sda_oen_master : sda_oen_slave ; assign scl_oen = master_mode ? scl_oen_master : scl_oen_slave ; reg slave_act; - reg slave_adr_received_d; //A 1 cycle pulse slave_adr_recived is generated when a slave adress is recvied after a startcommand. @@ -714,6 +713,8 @@ module i2c_master_bit_ctrl ( slave_state <= slave_wait_next_cmd_1; end end + + default:; endcase // case (slave_state) end diff --git a/rtl/verilog/i2c_master_byte_ctrl.v b/rtl/verilog/i2c_master_byte_ctrl.v index 58ca2ff..eee0f47 100644 --- a/rtl/verilog/i2c_master_byte_ctrl.v +++ b/rtl/verilog/i2c_master_byte_ctrl.v @@ -261,7 +261,7 @@ module i2c_master_byte_ctrl slave_cmd_out <= 2'b0; slave_cmd_ack <= 1'b0; end - else if (rst | i2c_al | slave_reset) + else if (rst | i2c_al) begin core_cmd <= `I2C_CMD_NOP; core_txd <= 1'b0; @@ -332,48 +332,56 @@ module i2c_master_byte_ctrl end ST_SL_RD: //If master read, slave sending data - begin - slave_cmd <= `I2C_SLAVE_CMD_NOP; - if (slave_ack) begin - if (cnt_done) begin - c_state <= ST_SL_ACK; - slave_cmd <= `I2C_SLAVE_CMD_READ; - end - else - begin - c_state <= ST_SL_RD; - slave_cmd <= `I2C_SLAVE_CMD_WRITE; - shift <= 1'b1; - end - end - end + begin + slave_cmd <= `I2C_SLAVE_CMD_NOP; + + if (slave_ack) begin + if (cnt_done) begin + c_state <= ST_SL_ACK; + slave_cmd <= `I2C_SLAVE_CMD_READ; + end + else + begin + c_state <= ST_SL_RD; + slave_cmd <= `I2C_SLAVE_CMD_WRITE; + shift <= 1'b1; + end + end + end ST_SL_WR: //If master write, slave reading data - begin - slave_cmd <= `I2C_SLAVE_CMD_NOP; - if (slave_ack) - begin - if (cnt_done) - begin - c_state <= ST_SL_ACK; - slave_cmd <= `I2C_SLAVE_CMD_WRITE; - core_txd <= 1'b0; - end - else - begin - c_state <= ST_SL_WR; - slave_cmd <= `I2C_SLAVE_CMD_READ; - end - shift <= 1'b1; - end - end + begin + slave_cmd <= `I2C_SLAVE_CMD_NOP; + + if (slave_reset) + begin + c_state <= ST_IDLE; + slave_cmd <= `I2C_SLAVE_CMD_NOP; + end + else if (slave_ack) + begin + if (cnt_done) + begin + c_state <= ST_SL_ACK; + slave_cmd <= `I2C_SLAVE_CMD_WRITE; + core_txd <= 1'b0; + end + else + begin + c_state <= ST_SL_WR; + slave_cmd <= `I2C_SLAVE_CMD_READ; + end + + shift <= 1'b1; + end + end ST_SL_WAIT: //Wait for interupt-clear and hold SCL in waitstate begin sl_wait <= 1'b1; if (sl_cont) begin sl_wait <= 1'b0; ld <= 1'b1; - slave_dat_req <= 1'b0; - slave_dat_avail <= 1'b0; + slave_dat_req <= 1'b0; + slave_dat_avail <= 1'b0; c_state <= ST_SL_PRELOAD; end end @@ -498,6 +506,7 @@ module i2c_master_byte_ctrl cmd_ack <= 1'b1; end + default:; endcase end endmodule