// // // Design file: I2C_control.v // Daniel Ogilvie, SingMai Electronics // 23rd November 2008 // // Hardware I2C controller // module I2C_control ( input wire XTAL_27M, // 27MHz crystal clock input input wire RESETn, // Reset input input wire S625_525n, // Line standard output reg I2C_SDA, output reg I2C_SCL ); // Definitions wire I2C_clock_comp; wire I2C_clock_start; wire I2C_clock_end; reg [9:0] I2C_bitclock; wire I2C_seq_comp; reg [3:0] I2C_sequencer; wire I2C_byte_comp; wire [7:0] I2C_data; reg [7:0] I2C_byte_count; reg I2C_clock; // ******************************************************************* // Code start // Generate I2C clock from 27MHz input (50kHz) assign I2C_clock_comp = (I2C_bitclock == 10'd540); always @ (posedge XTAL_27M or negedge RESETn) begin if (!RESETn) begin I2C_bitclock <= 10'b0000000000; end else if (I2C_clock_comp) begin I2C_bitclock <= 10'b0000000000; end else begin I2C_bitclock <= (I2C_bitclock + 1); end end assign I2C_clock_start = (I2C_bitclock == 10'd135); assign I2C_clock_end = (I2C_bitclock == 10'd405); always @ (posedge XTAL_27M or negedge RESETn) begin if (!RESETn) begin I2C_clock <= 1'b0; end else if (I2C_clock_start) begin I2C_clock <= 1'b1; end else if (I2C_clock_end) begin I2C_clock <= 1'b0; end else begin I2C_clock <= I2C_clock; end end // I2C bit transfer sequencer counter assign I2C_seq_comp = (I2C_sequencer == 4'd9); always @ (posedge XTAL_27M or negedge RESETn) begin if (!RESETn) begin I2C_sequencer <= 4'b0000; end else if (I2C_seq_comp) begin I2C_sequencer <= 4'b0000; end else if (I2C_clock_comp) begin I2C_sequencer <= (I2C_sequencer + 1); end else begin I2C_sequencer <= I2C_sequencer; end end // I2C Byte transfer counter (I2C_byte_comp is end of ROM data) assign I2C_byte_comp = (I2C_byte_count == 8'd199); always @ (posedge XTAL_27M or negedge RESETn) begin if (!RESETn) begin I2C_byte_count <= 8'b00000000; end else if (I2C_byte_comp) begin I2C_byte_count <= 8'b00000000; end else if (I2C_seq_comp) begin I2C_byte_count <= (I2C_byte_count + 1); end else begin I2C_byte_count <= I2C_byte_count; end end // Address I2C data ROM I2C_ROM I2C_ROM(.Clk27(XTAL_27M), .address({S625_525n,I2C_byte_count[7:0]}), .RESETn(RESETn), .I2C_data(I2C_data[7:0])); // Send I2C values to AD9981 (AD9981 address = B"01001100" [RW=0]) always @ (*) begin case (I2C_byte_count) // I2C start condition 8'h00,8'h32,8'hb2: case (I2C_sequencer) 4'd7: begin I2C_SDA <= 1'b0; I2C_SCL <= 1'b1; end 4'd8: begin I2C_SDA <= 1'b0; I2C_SCL <= 1'b0; end default: begin I2C_SDA <= 1'b1; I2C_SCL <= 1'b1; end endcase // Send device address (RW=0) MSB first then free SDA line and send acknowledge clock. // Then repeat sequence for the remaining data registers // AD9981 8'h01,8'h02,8'h03,8'h04,8'h05,8'h06,8'h07,8'h08,8'h09,8'h0a,8'h0b,8'h0c,8'h0d,8'h0e,8'h0f,8'h10, 8'h11,8'h12,8'h13,8'h14,8'h15,8'h16,8'h17,8'h18,8'h19,8'h1a,8'h1b,8'h1c,8'h1d,8'h1e,8'h1f,8'h20, 8'h21,8'h22,8'h23,8'h24,8'h25,8'h26,8'h27,8'h28,8'h29,8'h2a,8'h2b,8'h2c,8'h2d,8'h2e,8'h2f,8'h30, // ADV7321 8'h33,8'h34,8'h35,8'h36,8'h37,8'h38,8'h39,8'h3a,8'h3b,8'h3c,8'h3d,8'h3e,8'h3f,8'h40,8'h41,8'h42, 8'h43,8'h44,8'h45,8'h46,8'h47,8'h48,8'h49,8'h4a,8'h4b,8'h4c,8'h4d,8'h4e,8'h4f,8'h50,8'h51,8'h52, 8'h53,8'h54,8'h55,8'h56,8'h57,8'h58,8'h59,8'h5a,8'h5b,8'h5c,8'h5d,8'h5e,8'h5f,8'h60,8'h61,8'h62, 8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69,8'h6a,8'h6b,8'h6c,8'h6d,8'h6e,8'h6f,8'h70,8'h71,8'h72, 8'h73,8'h74,8'h75,8'h76,8'h77,8'h78,8'h79,8'h7a,8'h7b,8'h7c,8'h7d,8'h7e,8'h7f,8'h80,8'h81,8'h82, 8'h83,8'h84,8'h85,8'h86,8'h87,8'h88,8'h89,8'h8a,8'h8b,8'h8c,8'h8d,8'h8e,8'h8f,8'h90,8'h91,8'h92, 8'h93,8'h94,8'h95,8'h96,8'h97,8'h98,8'h99,8'h9a,8'h9b,8'h9c,8'h9d,8'h9e,8'h9f,8'ha0,8'ha1,8'ha2, 8'ha3,8'ha4,8'ha5,8'ha6,8'ha7,8'ha8,8'ha9,8'haa,8'hab,8'hac,8'had,8'hae,8'haf,8'hb0, // ADAU1326 8'hb3,8'hb4,8'hb5,8'hb6,8'hb7,8'hb8,8'hb9,8'hba,8'hbb,8'hbc,8'hbd,8'hbe,8'hbf,8'hc0,8'hc1,8'hc2, 8'hc3,8'hc4,8'hc5: case (I2C_sequencer) 4'd0: begin I2C_SDA <= I2C_data[7]; I2C_SCL <= I2C_clock; end 4'd1: begin I2C_SDA <= I2C_data[6]; I2C_SCL <= I2C_clock; end 4'd2: begin I2C_SDA <= I2C_data[5]; I2C_SCL <= I2C_clock; end 4'd3: begin I2C_SDA <= I2C_data[4]; I2C_SCL <= I2C_clock; end 4'd4: begin I2C_SDA <= I2C_data[3]; I2C_SCL <= I2C_clock; end 4'd5: begin I2C_SDA <= I2C_data[2]; I2C_SCL <= I2C_clock; end 4'd6: begin I2C_SDA <= I2C_data[1]; I2C_SCL <= I2C_clock; end 4'd7: begin I2C_SDA <= I2C_data[0]; I2C_SCL <= I2C_clock; end 4'd8: begin I2C_SDA <= 1'b1; I2C_SCL <= I2C_clock; end default: begin I2C_SDA <= 1'b1; I2C_SCL <= 1'b1; end endcase // I2C stop condition 8'h31,8'hb1,8'hc6: case (I2C_sequencer) 4'd0: begin I2C_SDA <= 1'b0; I2C_SCL <= 1'b0; end 4'd1: begin I2C_SDA <= 1'b0; I2C_SCL <= 1'b1; end default: begin I2C_SDA <= 1'b1; I2C_SCL <= 1'b1; end endcase default: begin I2C_SDA <= 1'b1; I2C_SCL <= 1'b1; end endcase end endmodule