module ws2812_driver (
    input wire clk,             // horloge principale du FPGA
    input wire [23:0] color,    // couleur RGB (8 bits par composant)
    output reg ws2812_dout      // broche de données vers la LED
);
    reg [7:0] bit_count;        // compteur de bits pour envoyer les données
    reg [23:0] shift_reg;       // registre pour envoyer la couleur
    reg [7:0] clk_div;          // Diviseur de fréquence pour ralentir l'horloge (prescaler)
    
    // Paramètres de timing en cycles de l'horloge du FPGA
    localparam T0H = 7;  // 0.35 µs (haut) -> 7 cycles à 27 MHz
    localparam T1H = 14; // 0.7 µs (haut) -> 14 cycles à 27 MHz
    localparam T0L = 15; // 0.8 µs (bas)  -> 15 cycles à 27 MHz
    localparam T1L = 11; // 0.6 µs (bas)  -> 11 cycles à 27 MHz
    localparam RES = 150; // Temps de réinitialisation en cycles de 27 MHz (50 µs min)

    reg [15:0] timing_counter;  // Compteur pour les impulsions

    always @(posedge clk) begin
        if (timing_counter == 0) begin
            if (bit_count == 0) begin
                // Charger la couleur dans l'ordre GRB (Green, Red, Blue)
                shift_reg <= {color[7:0], color[15:8], color[23:16]}; // GRB : Green, Red, Blue
                ws2812_dout <= 1'b0;   // Commencer par envoyer un "0"
            end else begin
                // Décalage des bits pour envoyer les données
                if (shift_reg[23]) begin
                    // T1H: 0.7µs haut, 0.6µs bas (pour un bit "1")
                    ws2812_dout <= 1'b1;
                    timing_counter <= T1H;
                end else begin
                    // T0H: 0.35µs haut, 0.8µs bas (pour un bit "0")
                    ws2812_dout <= 1'b0;
                    timing_counter <= T0H;
                end
                shift_reg <= shift_reg << 1; // Décalage des bits
            end

            // Incrémentation du compteur de bits
            if (bit_count < 24)
                bit_count <= bit_count + 1;
            else
                bit_count <= 0;  // Réinitialiser pour envoyer la prochaine couleur
        end else begin
            // Maintenir l'impulsion pendant la durée déterminée
            timing_counter <= timing_counter - 1;
        end
    end
endmodule