OpenCores
URL https://opencores.org/ocsvn/neopixel_fpga/neopixel_fpga/trunk

Subversion Repositories neopixel_fpga

[/] [neopixel_fpga/] [trunk/] [rtl/] [ws2812_ctl.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 splinedriv
/*
2
 *  FpgaNeoPixel - A spi to ws2812 machine
3
 *
4
 *  Copyright (C) 2020  Hirosh Dabui <hirosh@dabui.de>
5
 *
6
 *  Permission to use, copy, modify, and/or distribute this software for any
7
 *  purpose with or without fee is hereby granted, provided that the above
8
 *  copyright notice and this permission notice appear in all copies.
9
 *
10
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 *
18
 */
19
`include "simple_spi_slave.v"
20
`include "ram_sync.v"
21
`include "ws2812_sequence.v"
22
 
23
module ws2812_ctl(clk, resetn, dout, sck,
24
                  mosi, miso, cs, ready);
25
input clk;
26
input resetn;
27
output dout;
28
 
29
input cs;
30
input sck;
31
input mosi;
32
output miso;
33
output reg ready;
34
 
35
reg [9:0] ram_addr;
36
reg [9:0] rx_word_counter;
37
reg [23:0] ram_din;
38
wire [23:0] ram_dout;
39
reg  ram_we = 0;
40
 
41
reg [23:0] din;
42
reg enable = 0;
43
wire done;
44
 
45
wire spi_done;
46
reg [23:0] spi_rx_data;
47
wire [31:0] rx_data;
48
 
49
// fifo write states
50
localparam SYSTEM_CLOCK_FREQ = 12_000_000;
51
localparam S_RESET                = 0;
52
localparam S_WAIT4_SPI_DATA       = 1;
53
localparam S_STORE_FIFO_DATA      = 2;
54
localparam S_PREPARE_FIFO         = 3;
55
 
56
// fifo read and burst states
57
localparam S_CHECK4_FIFO_DATA     = 4;
58
localparam S_GET_FIFO_DATA        = 5;
59
localparam S_BURST_WS2812_SEQ     = 6;
60
localparam S_SEQ_DONE             = 7;
61
 
62
reg [2:0] state = S_RESET;
63
 
64
spi_slave spi_slave_i(.resetn(resetn), .clk(clk), .sck(sck),
65
                      .mosi(mosi), .miso(miso), .cs(cs),
66
                      .done(spi_done), .rx_data(rx_data));
67
 
68
ram_sync #(.ADDRESS_LINES(1024), .DATA_WIDTH(24))
69
                ram_sync_i(.clk(clk), .addr(ram_addr),
70
                  .din(ram_din), .dout(ram_dout), .we(ram_we));
71
 
72
ws2812_sequence #(.SYSTEM_CLOCK_FREQ(SYSTEM_CLOCK_FREQ))
73
                ws2812_sequence_i(.clk(clk),
74
                  .din(din),
75
                  .resetn(resetn),
76
                  .enable(enable),
77
                  .dout(dout),
78
                  .done(done)
79
                );
80
 
81
always @(posedge clk)
82
  ready <= ~( &(~ram_addr) && state == S_WAIT4_SPI_DATA);
83
 
84
always @(posedge clk) begin
85
  if (~resetn) begin
86
    state <= S_RESET;
87
  end else begin
88
    case (state)
89
 
90
      S_RESET: begin
91
        enable <= 0;
92
        rx_word_counter <= 0;
93
        ram_addr <= 0;
94
        ram_we <= 0;
95
        spi_rx_data <= 0;
96
        state <= S_WAIT4_SPI_DATA;
97
      end
98
 
99
      S_WAIT4_SPI_DATA: begin
100
        if (spi_done) begin
101
          spi_rx_data <= rx_data[23:0];
102
          if (rx_data == 32'h dead_beaf) begin
103
            rx_word_counter <= ram_addr;
104
            ram_addr <= 0;
105
            state <= S_CHECK4_FIFO_DATA;
106
          end else begin
107
            state <= S_STORE_FIFO_DATA;
108
          end
109
        end else
110
          state <= S_WAIT4_SPI_DATA;
111
      end
112
 
113
      S_STORE_FIFO_DATA: begin
114
        ram_we <= 1;
115
        ram_din <= spi_rx_data;
116
        state <= S_PREPARE_FIFO;
117
      end
118
 
119
      S_PREPARE_FIFO: begin
120
        ram_we <= 0;
121
        ram_addr <= ram_addr + 1;
122
        state <= S_WAIT4_SPI_DATA;
123
      end
124
 
125
      S_CHECK4_FIFO_DATA: begin
126
        ram_we <= 0;
127
        enable <= 0;
128
        if (ram_addr == (rx_word_counter)) begin
129
          spi_rx_data <= 0;
130
          rx_word_counter <= 0;
131
          ram_addr <= 0;
132
          ram_we <= 0;
133
          state <= S_WAIT4_SPI_DATA;
134
        end else
135
          state <= S_GET_FIFO_DATA;
136
      end
137
 
138
      S_GET_FIFO_DATA: begin
139
        din <= ram_dout;
140
        state <= S_BURST_WS2812_SEQ;
141
      end
142
 
143
      S_BURST_WS2812_SEQ: begin
144
        enable <= 1;
145
        state <= S_SEQ_DONE;
146
      end
147
 
148
      S_SEQ_DONE: begin
149
          enable <= 0;
150
        if (done) begin
151
         ram_addr <= ram_addr + 1;
152
          state <= S_CHECK4_FIFO_DATA;
153
        end else
154
          state <= S_SEQ_DONE;
155
      end
156
 
157
    default: begin
158
        state <= S_RESET;
159
      end
160
    endcase
161
  end end
162
 
163
endmodule
164
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.