
module i2c
(
   input        CLK,

   input        START,
   input [23:0] I2C_DATA,
   output reg   END = 1,
   output reg   ACK = 0,

   //I2C bus
   output       I2C_SCL,
   inout        I2C_SDA
);

// Clock Setting
parameter CLK_Freq = 50_000_000; // 50 MHz
parameter I2C_Freq = 400_000;    // 400 kHz

reg I2C_CLOCK;
always@(negedge CLK) begin
   integer mI2C_CLK_DIV = 0;
   if(mI2C_CLK_DIV < (CLK_Freq/I2C_Freq)) begin
      mI2C_CLK_DIV <= mI2C_CLK_DIV + 1;
   end else begin
      mI2C_CLK_DIV <= 0;
      I2C_CLOCK    <= ~I2C_CLOCK;
   end
end

assign I2C_SCL = SCLK | I2C_CLOCK;
assign I2C_SDA = SDO  ? 1'bz : 1'b0;

reg SCLK = 1, SDO = 1;

always @(posedge CLK) begin
   reg old_clk;
   reg old_st;

   reg  [5:0] SD_COUNTER = 'b111111;
   reg [0:31] SD;

   old_clk <= I2C_CLOCK;
   old_st  <= START;

   if(~old_st && START) begin
      SCLK <= 1;
      SDO  <= 1;
      ACK  <= 0;
      END  <= 0;
      SD   <= {2'b10, I2C_DATA[23:16], 1'b1, I2C_DATA[15:8], 1'b1, I2C_DATA[7:0], 4'b1011};
      SD_COUNTER <= 0;
   end else begin
      if(~old_clk && I2C_CLOCK && ~&SD_COUNTER) begin
         SD_COUNTER <= SD_COUNTER + 6'd1;
         case(SD_COUNTER)
                  01: SCLK <= 0;
            10,19,28: ACK  <= ACK | I2C_SDA;
                  29: SCLK <= 1;
                  32: END  <= 1;
         endcase
      end

      if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[5]) SDO <= SD[SD_COUNTER[4:0]];
   end
end

endmodule
