Commit 730d8ca4 authored by Andrey Filippov's avatar Andrey Filippov

started modification of the i2c sequencer to support SMIA registers (2 bytes...

started modification of the i2c sequencer to support SMIA registers (2 bytes address, >=2 bytes of data) and register read
parent 49a3f9e2
parameter FPGA_VERSION = 32'h03930039;
\ No newline at end of file
parameter FPGA_VERSION = 32'h0393003a;
\ No newline at end of file
......@@ -389,16 +389,16 @@ module sensor_i2c#(
// now creating output signals
scl_0 <= (i2c_is_start && (i2c_state[1:0]!=2'h0)) ||
(i2c_is_stop && !i2c_state[1]) ||
(i2c_is_data && (i2c_state[1] ^i2c_state[0])) ||
(i2c_is_stop && !i2c_state[1]) ||
(i2c_is_data && (i2c_state[1] ^i2c_state[0])) ||
!i2c_run;
sda_0 <= (i2c_is_start && i2c_state[1]) ||
(i2c_is_stop && (i2c_state[1:0]==2'h0)) ||
(i2c_is_data && i2c_sr[8]) ||
sda_0 <= (i2c_is_start && i2c_state[1]) ||
(i2c_is_stop && (i2c_state[1:0]==2'h0)) ||
(i2c_is_data && i2c_sr[8]) ||
!i2c_run;
sda_hard <= sda_0;
sda_hard <= sda_0;
scl_hard <= scl_0;
sda_en_hard <= i2c_run && (!sda_0 || (!i2c_is_ackn && !sda_hard));
sda_en_hard <= i2c_run && (!sda_0 || (!i2c_is_ackn && !sda_hard));
if (wen) busy_cntr <= 4'hf;
else if (|busy_cntr) busy_cntr <= busy_cntr-1;
......@@ -424,33 +424,6 @@ module sensor_i2c#(
.web(8'hff), // input[7:0]
.data_in(di_r) // input[31:0]
);
/*
RAMB16_S9_S18 i_fifo (
.DOA(i2c_data[7:0]), // Port A 8-bit Data Output
.DOPA(), // Port A 1-bit Parity Output
.ADDRA({page_r[2:0],
rpointer[5:0],
byte_number[1:0]}), // Port A 11-bit Address Input
.CLKA(mclk), // Port A Clock
.DIA(8'h0), // Port A 8-bit Data Input
.DIPA(1'b0), // Port A 1-bit parity Input
.ENA(i2c_byte_start[0]), // Port A RAM Enable Input
.SSRA(1'b0), // Port A Synchronous Set/Reset Input
.WEA(1'b0), // Port A Write Enable Input
.DOB(), // Port B 16-bit Data Output
.DOPB(), // Port B 2-bit Parity Output
.ADDRB(i2c_cmd_wa[9:0]), // Port B 10-bit Address Input
.CLKB(mclk), // Port B Clock
.DIB(di_3[15:0]), // Port B 16-bit Data Input
.DIPB(2'b0), // Port-B 2-bit parity Input
.ENB(i2c_cmd_we), // PortB RAM Enable Input
.SSRB(1'b0), // Port B Synchronous Set/Reset Input
.WEB(1'b1) // Port B Write Enable Input
);
*/
endmodule
/*******************************************************************************
* Module: sensor_i2c_prot
* Date:2015-10-05
* Author: andrey
* Description: Generate i2c R/W sequence from a 32-bit word and LUT
*
* Copyright (c) 2015 Elphel, Inc .
* sensor_i2c_prot.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sensor_i2c_prot.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module sensor_i2c_prot(
input mrst, // @ posedge mclk
input mclk, // global clock
input i2c_rst,
input i2c_start,
input [ 7:0] i2c_dly, // bit duration-1 (>=2?), 1 unit - 4 mclk periods
// setup LUT to translate address page into SA, actual address MSB and number of bytes to write (second word bypasses translation)
input tand, // table address/not data
input [19:0] td, // table address/data in
input twe, // table write enable
output reg sda,
output reg sda_en,
output reg scl,
output i2c_run,
output [ 1:0] seq_mem_ra, // number of byte to read from the sequencer memory
output [ 1:0] seq_mem_re, // [0] - re, [1] - regen to teh sequencer memory
input [ 7:0] seq_rd, // data from the sequencer memory
output [ 7:0] rdata,
output rvalid
);
reg [ 7:0] twa;
wire [31:0] tdout;
wire [ 7:0] reg_ah = tdout[7:0]; // MSB of the register address (instead of the byte 2)
wire [ 6:0] slave_a = tdout[14:8]; // 7-bit slave address (lsb == 1), used instead of the byte 3
wire [ 3:0] num_bytes_send = tdout[19:16]; // number of bytes to send (if more than 4 will skip stop and continue with next data
reg [ 3:0] bytes_left_send; // Number of bytes left in register write sequence (not counting sa?)
reg run_reg_wr; // run register write
reg run_extra_wr; // continue register write (if more than sa + 4bytes)
reg run_reg_rd;
reg i2c_done;
wire i2c_next_byte;
reg [ 2:0] mem_re;
reg [ 2:0] table_re;
wire decode_reg_rd = &seq_rd[7:5];
wire start_wr_seq = !run_extra_wr && !decode_reg_rd && read_mem_msb;
reg read_mem_msb;
assign seq_mem_re = mem_re[1:0];
always @ (posedge mclk) begin
read_mem_msb <= mem_re[1] && (seq_mem_ra == 3); // reading sequencer data MSB
mem_re <= {mem_re[1:0], i2c_start | i2c_next_byte};
table_re <= {table_re[1:0], start_wr_seq};
if (mrst || i2c_rst) run_extra_wr <= 0;
else if (i2c_start && (bytes_left_send !=0)) run_extra_wr <= 1;
else if (i2c_done) run_extra_wr <= 0;
if (mrst || i2c_rst) run_reg_wr <= 0;
else if (start_wr_seq) run_reg_wr <= 1;
else if (i2c_done) run_reg_wr <= 0;
if (mrst || i2c_rst) run_reg_rd <= 0;
else if (!run_extra_wr && decode_reg_rd && read_mem_msb) run_reg_rd <= 1;
else if (i2c_done) run_reg_rd <= 0;
// table_re[2] - valid table data (slave_a, reg_ah, reg_ah
end
// table write
always @ (posedge mclk) begin
if (mrst) twa <= 0;
else if (twe) twa <= tand ? td[7:0] : (twa + 1);
end
ram18_var_w_var_r #(
.REGISTERS (1),
.LOG2WIDTH_WR (5),
.LOG2WIDTH_RD (5),
.DUMMY (0)
) ram18_var_w_var_r_i (
.rclk (mclk), // input
.raddr ({1'b0, seq_rd}), // input[8:0]
.ren (table_re[0]), // input
.regen (table_re[1]), // input
.data_out (tdout), // output[31:0]
.wclk (mclk), // input
.waddr ({1'b0, twa}), // input[8:0]
.we (twe && !tand), // input
.web (4'hf), // input[3:0]
.data_in ({12'b0, td}) // input[31:0]
);
endmodule
This diff is collapsed.
......@@ -951,7 +951,7 @@ assign #10 gpio_pins[9] = gpio_pins[8];
1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop
2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
8'h02, //a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
TEST_TITLE = "RESEST_I2C_SEQUENCER1";
......@@ -963,7 +963,7 @@ assign #10 gpio_pins[9] = gpio_pins[8];
1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop
2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
8'h02, //a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
TEST_TITLE = "RESEST_I2C_SEQUENCER2";
......@@ -975,7 +975,7 @@ assign #10 gpio_pins[9] = gpio_pins[8];
1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop
2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
8'h02, //a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
TEST_TITLE = "RESEST_I2C_SEQUENCER3";
......@@ -987,7 +987,7 @@ assign #10 gpio_pins[9] = gpio_pins[8];
1'b1, // input set_bytes; // [11] if 1, use bytes (below), 0 - nop
2'h3, // input [SENSI2C_CMD_BYTES_PBITS -1 : 0] bytes; // [10:9] set command bytes to send after slave address (0..3)
1'b1, // input set_dly; // [8] if 1, use dly (0 - ignore)
8'h0a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
8'h02, //a, // input [SENSI2C_CMD_DLY_PBITS - 1 : 0] dly; // [7:0] - duration of quarter i2c cycle (if 0, [3:0] control SCL+SDA)
2'b0, // input [SENSI2C_CMD_SCL_WIDTH -1 : 0] scl_ctl; // [1:0] : 0: NOP, 1: 1'b0->SCL, 2: 1'b1->SCL, 3: 1'bz -> SCL
2'b0); // input [SENSI2C_CMD_SDA_WIDTH -1 : 0] sda_ctl; // [3:2] : 0: NOP, 1: 1'b0->SDA, 2: 1'b1->SDA, 3: 1'bz -> SDA
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment