module i2c_lcd_send_byte (
    input clk, reset_p,
    input [6:0] addr,                           // Slave Address
    input [7:0] send_buffer,                    // Transmission Data Buffer
    input send, rs,                             // Send Start-bit, Register Select
    output scl, sda,                            // Serial Clock , Serial Data
    output reg busy,                            // Communication Situation
    output [15:0] led                           // for Debugging
    );

    // Change State Using Shift
    localparam I2C_IDLE                 = 6'b00_0001;   // Standby State
    localparam SEND_HIGH_NIBBLE_DISABLE = 6'b00_0010;   // High Nibble(4-bit) Transmit in Enable Clear
    localparam SEND_HIGH_NIBBLE_ENABLE  = 6'b00_0100;   // Enable Set
    localparam SEND_LOW_NIBBLE_DISABLE  = 6'b00_1000;   // Low Nibble(4-bit) Transmit in Enable Clear
    localparam SEND_LOW_NIBBLE_ENABLE   = 6'b01_0000;   // Enable Set
    localparam SEND_DISABLE             = 6'b10_0000;   // Byte(8-bit) Transmission Complete

    reg [7:0] data;                             // 4-bit Unit Transmission, D7 ~ D4, BL, E, RW, RS
    reg comm_start;                             // Communication Start-bit

    // Clock Divide 100, 10ns x 100 = 1us
    wire clk_usec_nedge, clk_usec_pedge; // Divide Clock 1us
    clock_div_100 us_clk (.clk(clk), .reset_p(reset_p),
        .nedge_div_100(clk_usec_nedge), .pedge_div_100(clk_usec_pedge));

    // Edge Detection of Send Signal
    wire send_pedge, send_nedge;
    edge_detector_pos comm_start_ed (.clk(clk), .reset_p(reset_p),
        .cp(send), .p_edge(send_pedge), .n_edge(send_nedge));

    // us Unit Count
    reg [21:0] cnt_usec;                        // us Count
    reg cnt_usec_e;                             // us Count Enable
    always @(negedge clk, posedge reset_p) begin
        if (reset_p) cnt_usec = 0;              // Count Clear
        else if (clk_usec_nedge && cnt_usec_e) begin    // Count Start when Enable & us Negative Edge
            cnt_usec = cnt_usec + 1;            // Count During Enable
        end
        else if (!cnt_usec_e) cnt_usec = 0;     // Count Clear when Disable
    end

    // Using Module, Address & Data Transmission, I2C Communication
    i2c_master master (clk, reset_p, addr, data, 1'b0, comm_start, scl, sda);

    reg [5:0] state, next_state;                // Current & Next State
    always @(negedge clk, posedge reset_p) begin
        if (reset_p) state = I2C_IDLE;          // Basic Standby
        else state = next_state;                // Change State in Negative Edge
    end

    always @(posedge clk, posedge reset_p) begin
        if (reset_p) begin
            next_state = I2C_IDLE;              // Basic Standby
            comm_start = 0;                     // Communication Disable
            cnt_usec_e = 0;                     // us Count Disable, Clear
            data = 0;                           // Transmission Data Reset
            busy = 0;                           // Communication Available
        end
        else begin
            case (state)
                I2C_IDLE                 : begin    // Standby State
                    if (send_pedge) begin       // Send Start
                        next_state = SEND_HIGH_NIBBLE_DISABLE;  // Change State SEND_HIGH_NIBBLE_DISABLE
                        busy = 1;               // Communicating
                    end
                end
                SEND_HIGH_NIBBLE_DISABLE : begin    // High Nibble(4-bit) Transmit in Enable Clear
                    if (cnt_usec < 22'd200) begin   // About 200us Required to Complete Transmission
                        data = {send_buffer[7:4], 3'b100, rs};  // High Nibble Transmission
                        comm_start = 1;         // Communication Start
                        cnt_usec_e = 1;         // us Count Enable
                    end
                    else begin
                        cnt_usec_e = 0;         // us Count Disable, Clear
                        comm_start = 0;         // Communication Start-bit Clear
                        next_state = SEND_HIGH_NIBBLE_ENABLE;   // Change State SEND_HIGH_NIBBLE_ENABLE
                    end
                end
                SEND_HIGH_NIBBLE_ENABLE  : begin    // Enable Set
                    if (cnt_usec < 22'd200) begin   // About 200us Required to Complete Transmission
                        data = {send_buffer[7:4], 3'b110, rs};  // E Pin Enable
                        comm_start = 1;         // Communication Start
                        cnt_usec_e = 1;         // us Count Enable
                    end
                    else begin
                        cnt_usec_e = 0;         // us Count Disable, Clear
                        comm_start = 0;         // Communication Start-bit Clear
                        next_state = SEND_LOW_NIBBLE_DISABLE;   // Change State SEND_LOW_NIBBLE_DISABLE
                    end
                end
                SEND_LOW_NIBBLE_DISABLE  : begin    // Low Nibble(4-bit) Transmit in Enable Clear
                    if (cnt_usec < 22'd200) begin   // About 200us Required to Complete Transmission
                        data = {send_buffer[3:0], 3'b100, rs};  // Low Nibble Transmission
                        comm_start = 1;         // Communication Start
                        cnt_usec_e = 1;         // us Count Enable
                    end
                    else begin
                        cnt_usec_e = 0;         // us Count Disable, Clear
                        comm_start = 0;         // Communication Start-bit Clear
                        next_state = SEND_LOW_NIBBLE_ENABLE;    // Change State SEND_LOW_NIBBLE_ENABLE
                    end
                end
                SEND_LOW_NIBBLE_ENABLE   : begin    // Enable Set
                    if (cnt_usec < 22'd200) begin   // About 200us Required to Complete Transmission
                        data = {send_buffer[3:0], 3'b110, rs};  // E Pin Enable
                        comm_start = 1;         // Communication Start
                        cnt_usec_e = 1;         // us Count Enable
                    end
                    else begin
                        cnt_usec_e = 0;         // us Count Disable, Clear
                        comm_start = 0;         // Communication Start-bit Clear
                        next_state = SEND_DISABLE;  // Change State SEND_DISABLE
                    end
                end
                SEND_DISABLE             : begin    // Byte(8-bit) Transmission Complete
                    if (cnt_usec < 22'd200) begin   // About 200us Required to Complete Transmission
                        data = {send_buffer[7:4], 3'b100, rs};  // E Pin Disable
                        comm_start = 1;         // Communication Start
                        cnt_usec_e = 1;         // us Count Enable
                    end
                    else begin
                        cnt_usec_e = 0;         // us Count Disable, Clear
                        comm_start = 0;         // Communication Start-bit Clear
                        next_state = I2C_IDLE;  // Change State I2C_IDLE
                        busy = 0;               // Communication Available
                    end
                end
                default                  : begin
                    cnt_usec_e = 0;             // us Count Disable, Clear
                    comm_start = 0;             // Communication Start-bit Clear
                    next_state = I2C_IDLE;      // Basic Standby
                    busy = 0;                   // Communication Available
                end
            endcase
        end
    end
endmodule