X-Git-Url: http://git.joshuawise.com/firearm.git/blobdiff_plain/121556d62c2c40b07a709ef038fa1ce0a67127c9..8744c23dbf6a3c38649c800ae3d96e7e465e01fb:/xst/iic_init.v diff --git a/xst/iic_init.v b/xst/iic_init.v new file mode 100644 index 0000000..60fe281 --- /dev/null +++ b/xst/iic_init.v @@ -0,0 +1,219 @@ +`timescale 1 ns / 100 ps +module iic_init( Clk, //I + Reset_n, //I + Pixel_clk_greater_than_65Mhz, //I + SDA, //IO + SCL, //IO + Done //O + ); + +input Clk; +input Reset_n; +input Pixel_clk_greater_than_65Mhz; +inout SDA; +inout SCL; +output Done; + +parameter CLK_RATE_MHZ = 200, + SCK_PERIOD_US = 30, + TRANSITION_CYCLE = (CLK_RATE_MHZ * SCK_PERIOD_US) / 2, + TRANSITION_CYCLE_MSB = 11; + + +localparam IDLE = 3'd0, + INIT = 3'd1, + START = 3'd2, + CLK_FALL = 3'd3, + SETUP = 3'd4, + CLK_RISE = 3'd5, + WAIT = 3'd6, + START_BIT = 1'b1, + SLAVE_ADDR= 7'b1110110, + ACK = 1'b1, + WRITE = 1'b0, + REG_ADDR0 = 8'h49, + REG_ADDR1 = 8'h21, + REG_ADDR2 = 8'h33, + REG_ADDR3 = 8'h34, + REG_ADDR4 = 8'h36, + DATA0 = 8'hC0, + DATA1 = 8'h09, + DATA2a = 8'h06, + DATA3a = 8'h26, + DATA4a = 8'hA0, + DATA2b = 8'h08, + DATA3b = 8'h16, + DATA4b = 8'h60, + STOP_BIT=1'b0, + SDA_BUFFER_MSB=27; + +reg SDA_out; +reg SCL_out; +reg [TRANSITION_CYCLE_MSB:0] cycle_count; +reg [2:0] c_state; +reg [2:0] n_state; +reg Done; +reg [2:0] write_count; +reg [31:0] bit_count; +reg [SDA_BUFFER_MSB:0] SDA_BUFFER; +wire transition; + +always @ (posedge Clk) begin + if (~Reset_n||c_state==IDLE ) begin + SDA_out <= 1'b1; + SCL_out <=1'b1; + end + else if (c_state==INIT && transition) begin + SDA_out <=1'b0; + end + else if (c_state==SETUP) begin + SDA_out <=SDA_BUFFER[SDA_BUFFER_MSB]; + end + else if (c_state==CLK_RISE && cycle_count==TRANSITION_CYCLE/2 && bit_count==SDA_BUFFER_MSB) begin + SDA_out <= 1'b1; + end + else if (c_state==CLK_FALL) begin + SCL_out <=1'b0; + end + + else if (c_state==CLK_RISE) begin + SCL_out <=1'b1; + end +end + +//OBUFT_LVCMOS33 sda0(.O(SDA), .I(1'b0), .T(SDA_out)); +//OBUFT_LVCMOS33 scl0(.O(SCL), .I(1'b0), .T(SCL_out)); +assign SDA = SDA_out; +assign SCL = SCL_out; + +always @ (posedge Clk) begin + //reset or end condition + if(~Reset_n) begin + SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR0,ACK,DATA0,ACK,STOP_BIT}; + cycle_count<=0; + + end + //setup sda for sck rise + else if ( c_state==SETUP && cycle_count==TRANSITION_CYCLE)begin + SDA_BUFFER <= {SDA_BUFFER[SDA_BUFFER_MSB-1:0],1'b0}; + cycle_count<=0; + end + //reset count at end of state + else if ( cycle_count==TRANSITION_CYCLE) + cycle_count<=0; + //reset sda_buffer + else if (c_state==WAIT && Pixel_clk_greater_than_65Mhz )begin + case(write_count) + 0:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR1,ACK,DATA1,ACK,STOP_BIT}; + 1:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR2,ACK,DATA2a,ACK,STOP_BIT}; + 2:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR3,ACK,DATA3a,ACK,STOP_BIT}; + 3:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR4,ACK,DATA4a,ACK,STOP_BIT}; + default: SDA_BUFFER <=28'dx; + endcase + cycle_count<=cycle_count+1; + + end + else if (c_state==WAIT && ~Pixel_clk_greater_than_65Mhz )begin + case(write_count) + 0:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR1,ACK,DATA1,ACK,STOP_BIT}; + 1:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR2,ACK,DATA2b,ACK,STOP_BIT}; + 2:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR3,ACK,DATA3b,ACK,STOP_BIT}; + 3:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR4,ACK,DATA4b,ACK,STOP_BIT}; + default: SDA_BUFFER <=28'dx; + endcase + cycle_count<=cycle_count+1; + end + else + cycle_count<=cycle_count+1; +end + +always @ (posedge Clk) begin + if(~Reset_n) + write_count<=3'd0; + else if (c_state==WAIT && cycle_count==TRANSITION_CYCLE) + write_count<=write_count+1; +end + + +always @ (posedge Clk) begin + if(~Reset_n) + Done<=1'b0; + else if (c_state==IDLE) + Done<=1'b1; +end + + + + +always @ (posedge Clk) begin + if(~Reset_n||(c_state==WAIT)) + bit_count<=0; + else if ( c_state==CLK_RISE && cycle_count==TRANSITION_CYCLE) + bit_count<=bit_count+1; +end + + + +always @ (posedge Clk) begin + if(~Reset_n) + c_state<=INIT; + else + c_state<=n_state; +end + + + +assign transition = (cycle_count==TRANSITION_CYCLE); + +//Next state +always @ (*) begin + case(c_state) + IDLE: begin + if(~Reset_n) n_state = INIT; + else n_state = IDLE; + end + INIT: begin + if (transition) n_state = START; + else n_state = INIT; + end + START: begin + if(~Reset_n) n_state = INIT; + else if( transition) n_state = CLK_FALL; + else n_state = START; + end + CLK_FALL: begin + if(~Reset_n) n_state = INIT; + else if( transition) n_state = SETUP; + else n_state = CLK_FALL; + end + SETUP: begin + if(~Reset_n) n_state = INIT; + else if( transition) n_state = CLK_RISE; + else n_state = SETUP; + end + CLK_RISE: begin + if(~Reset_n) + n_state = INIT; + else if( transition && bit_count==SDA_BUFFER_MSB) + n_state = WAIT; + else if (transition ) + n_state = CLK_FALL; + else n_state = CLK_RISE; + end + WAIT: begin + if(~Reset_n|(transition && write_count!=3'd4)) + n_state = INIT; + else if (transition ) + n_state = IDLE; + else n_state = WAIT; + end + default: n_state = IDLE; + + endcase +end + + + + + +endmodule