module LEDMatrix_341450853309219412(
  input         clock,
  input         reset,
  
  output        sclk,
  output        mosi,
  output        n_cs
);

  localparam STATE_RESET_FRAME_INDEX = 1'd0,
    STATE_SEND_PIXELS = 1'd1;

  // command to reset frame index
  localparam CMD_RESET_FRAME_INDEX = 8'h26;

  localparam PIXEL_MAX = 6'h3f;

  reg [0:0] state;
  reg [1:0] state_rfi;
  reg [1:0] state_sp;

  reg [5:0] pixel_counter;

  reg [5:0] pixel_offset;

  reg tx_valid;
  reg tx_clear_cs;

  wire tx_ready;
  wire [7:0] tx_byte;

  wire [2:0] row_idx;
  wire [2:0] col_idx;
  wire [7:0] pixel;

  assign tx_byte = (state == STATE_RESET_FRAME_INDEX) ? CMD_RESET_FRAME_INDEX : pixel;

  assign row_idx = pixel_counter[5:3];
  assign col_idx = pixel_counter[2:0];

  SPIMaster_341450853309219412 spi_master_inst(
    .clock(clock),
    .reset(reset),

    .tx_ready(tx_ready),
    .tx_valid(tx_valid),
    .tx_byte(tx_byte),
    .tx_clear_cs(tx_clear_cs),

    .sclk(sclk),
    .mosi(mosi),
    .n_cs(n_cs)
  );

  LEDColor_341450853309219412 led_color_inst(
    .row_idx(row_idx),
    .col_idx(col_idx),
    .pixel_offset(pixel_offset),

    .pixel(pixel)
  );

  always @(posedge clock) begin
    if (reset) begin
      state <= STATE_RESET_FRAME_INDEX;

      pixel_counter <= 6'h0;
      pixel_offset <= 6'h0;

      tx_valid <= 1'b0;
      tx_clear_cs <= 1'b0;
    end else begin

      if (state == STATE_RESET_FRAME_INDEX) begin

        if (tx_ready == 1'b1) begin

          // send command to reset frame index

          tx_valid <= 1'b1;
          tx_clear_cs <= 1'b1;
        end else if (tx_valid == 1'b1) begin
          
          // TX accepted, transition to next state

          state <= STATE_SEND_PIXELS;
          tx_valid <= 1'b0;
        end

      end else if (state == STATE_SEND_PIXELS) begin

        if (tx_ready == 1'b1) begin

          // send pixel data

          tx_valid <= 1'b1;

          if (pixel_counter == PIXEL_MAX) begin
            // sending last pixel, so clear CS after
            tx_clear_cs <= 1'b1;
          end else begin
            tx_clear_cs <= 1'b0;
          end

        end else if (tx_valid == 1'b1) begin

          // TX accepted, transition to next state

          tx_valid <= 1'b0;

          if (pixel_counter == PIXEL_MAX) begin
            // sending last pixel
            state <= STATE_RESET_FRAME_INDEX;
            pixel_counter <= 6'h0;
            pixel_offset <= pixel_offset + 6'h1;
          end else begin
            pixel_counter <= pixel_counter + 6'h1;
          end

        end
      end
    end
  end

endmodule