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

Subversion Repositories spi_master_lightweight

[/] [spi_master_lightweight/] [trunk/] [rtl/] [lw_spi_master.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 bbinb
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_UNSIGNED.ALL;
4
 
5
entity lw_spi_master is
6
generic (
7
        c_clkfreq                       : integer := 50_000_000;
8
        c_sclkfreq                      : integer := 5_000_000;
9
        c_cpol                          : std_logic := '0';
10
        c_cpha                          : std_logic := '0'
11
);
12
Port (
13
        clk_i                   : in  STD_LOGIC;
14
        en_i                    : in  STD_LOGIC;
15
        mosi_data_i     : in  STD_LOGIC_VECTOR (7 downto 0);
16
        miso_data_o     : out STD_LOGIC_VECTOR (7 downto 0);
17
        data_ready_o    : out STD_LOGIC;
18
        cs_o                    : out STD_LOGIC;
19
        sclk_o                  : out STD_LOGIC;
20
        mosi_o                  : out STD_LOGIC;
21
        miso_i                  : in  STD_LOGIC
22
);
23
end lw_spi_master;
24
 
25
architecture Behavioral of lw_spi_master is
26
 
27
signal write_reg        : std_logic_vector (7 downto 0)  := (others => '0');
28
signal read_reg         : std_logic_vector (7 downto 0)  := (others => '0');
29
 
30
signal sclk_en          : std_logic := '0';
31
signal sclk                     : std_logic := '0';
32
signal sclk_prev        : std_logic := '0';
33
signal sclk_rise        : std_logic := '0';
34
signal sclk_fall        : std_logic := '0';
35
 
36
signal pol_phase        : std_logic_vector (1 downto 0) := (others => '0');
37
signal mosi_en          : std_logic := '0';
38
signal miso_en          : std_logic := '0';
39
 
40
constant c_edgecntrlimdiv2      : integer := c_clkfreq/(c_sclkfreq*2);
41
signal edgecntr                 : integer range 0 to c_edgecntrlimdiv2 := 0;
42
 
43
signal cntr     : integer range 0 to 15 := 0;
44
 
45
type states is (S_IDLE, S_TRANSFER);
46
signal state : states := S_IDLE;
47
 
48
--------------------------------------------------------------------------------
49
--------------------------------------------------------------------------------
50
--------------------------------------------------------------------------------
51
begin
52
 
53
pol_phase <= c_cpol & c_cpha;
54
 
55
P_SAMPLE_EN : process (pol_phase, sclk_fall, sclk_rise) begin
56
 
57
        case pol_phase is
58
 
59
                when "00" =>
60
 
61
                        mosi_en <= sclk_fall;
62
                        miso_en <= sclk_rise;
63
 
64
                when "01" =>
65
 
66
                        mosi_en <= sclk_rise;
67
                        miso_en <= sclk_fall;
68
 
69
                when "10" =>
70
 
71
                        mosi_en <= sclk_rise;
72
                        miso_en <= sclk_fall;
73
 
74
                when "11" =>
75
 
76
                        mosi_en <= sclk_fall;
77
                        miso_en <= sclk_rise;
78
 
79
                when others =>
80
 
81
        end case;
82
 
83
end process;
84
 
85
P_RISEFALL_DETECT : process (sclk, sclk_prev) begin
86
 
87
        if (sclk = '1' and sclk_prev = '0') then
88
                sclk_rise <= '1';
89
        else
90
                sclk_rise <= '0';
91
        end if;
92
 
93
        if (sclk = '0' and sclk_prev = '1') then
94
                sclk_fall <= '1';
95
        else
96
                sclk_fall <= '0';
97
        end if;
98
 
99
end process;
100
 
101
 
102
P_MAIN : process (clk_i) begin
103
if (rising_edge(clk_i)) then
104
 
105
        sclk_prev       <= sclk;
106
 
107
        case state is
108
 
109
                when S_IDLE =>
110
 
111
                        cs_o                    <= '1';
112
                        mosi_o                  <= '0';
113
                        data_ready_o    <= '0';
114
                        sclk_en                 <= '0';
115
                        cntr                    <= 0;
116
 
117
                        if (c_cpol = '0') then
118
                                sclk_o  <= '0';
119
                        else
120
                                sclk_o  <= '1';
121
                        end if;
122
 
123
                        if (en_i = '1') then
124
                                state           <= S_TRANSFER;
125
                                sclk_en         <= '1';
126
                                write_reg       <= mosi_data_i;
127
                                mosi_o          <= mosi_data_i(7);
128
                                read_reg        <= x"00";
129
                        end if;
130
 
131
                when S_TRANSFER =>
132
 
133
                        cs_o    <= '0';
134
                        mosi_o  <= write_reg(7);
135
 
136
 
137
                        if (c_cpha = '1') then
138
 
139
                                if (cntr = 0) then
140
                                        sclk_o  <= sclk;
141
                                        if (miso_en = '1') then
142
                                                read_reg(0)                              <= miso_i;
143
                                                read_reg(7 downto 1)    <= read_reg(6 downto 0);
144
                                                cntr                                    <= cntr + 1;
145
                                        end if;
146
                                elsif (cntr = 8) then
147
                                        data_ready_o    <= '1';
148
                                        miso_data_o             <= read_reg;
149
                                        if (mosi_en = '1') then
150
                                                data_ready_o    <= '0';
151
                                                if (en_i = '1') then
152
                                                        write_reg       <= mosi_data_i;
153
                                                        mosi_o          <= mosi_data_i(7);
154
                                                        sclk_o          <= sclk;
155
                                                        cntr            <= 0;
156
                                                else
157
                                                        state   <= S_IDLE;
158
                                                        cs_o    <= '1';
159
                                                end if;
160
                                        end if;
161
                                elsif (cntr = 9) then
162
                                        if (miso_en = '1') then
163
                                                state   <= S_IDLE;
164
                                                cs_o    <= '1';
165
                                        end if;
166
                                else
167
                                        sclk_o  <= sclk;
168
                                        if (miso_en = '1') then
169
                                                read_reg(0)                              <= miso_i;
170
                                                read_reg(7 downto 1)    <= read_reg(6 downto 0);
171
                                                cntr                                    <= cntr + 1;
172
                                        end if;
173
                                        if (mosi_en = '1') then
174
                                                mosi_o  <= write_reg(7);
175
                                                write_reg(7 downto 1)   <= write_reg(6 downto 0);
176
                                        end if;
177
                                end if;
178
 
179
                        else    -- c_cpha = '0'
180
 
181
                                if (cntr = 0) then
182
                                        sclk_o  <= sclk;
183
                                        if (miso_en = '1') then
184
                                                read_reg(0)                              <= miso_i;
185
                                                read_reg(7 downto 1)    <= read_reg(6 downto 0);
186
                                                cntr                                    <= cntr + 1;
187
                                        end if;
188
                                elsif (cntr = 8) then
189
 
190
                                        data_ready_o    <= '1';
191
                                        miso_data_o             <= read_reg;
192
                                        sclk_o                  <= sclk;
193
                                        if (mosi_en = '1') then
194
                                                data_ready_o    <= '0';
195
                                                if (en_i = '1') then
196
                                                        write_reg       <= mosi_data_i;
197
                                                        mosi_o          <= mosi_data_i(7);
198
                                                        cntr            <= 0;
199
                                                else
200
                                                        cntr    <= cntr + 1;
201
                                                end if;
202
                                                if (miso_en = '1') then
203
                                                        state   <= S_IDLE;
204
                                                        cs_o    <= '1';
205
                                                end if;
206
                                        end if;
207
                                elsif (cntr = 9) then
208
                                        if (miso_en = '1') then
209
                                                state   <= S_IDLE;
210
                                                cs_o    <= '1';
211
                                        end if;
212
                                else
213
                                        sclk_o  <= sclk;
214
                                        if (miso_en = '1') then
215
                                                read_reg(0)                              <= miso_i;
216
                                                read_reg(7 downto 1)    <= read_reg(6 downto 0);
217
                                                cntr                                    <= cntr + 1;
218
                                        end if;
219
                                        if (mosi_en = '1') then
220
                                                write_reg(7 downto 1)   <= write_reg(6 downto 0);
221
                                        end if;
222
                                end if;
223
 
224
                        end if;
225
 
226
        end case;
227
 
228
end if;
229
end process;
230
 
231
P_SCLK_GEN : process (clk_i) begin
232
if (rising_edge(clk_i)) then
233
 
234
        if (sclk_en = '1') then
235
                if edgecntr = c_edgecntrlimdiv2-1 then
236
                        sclk            <= not sclk;
237
                        edgecntr        <= 0;
238
                else
239
                        edgecntr        <= edgecntr + 1;
240
                end if;
241
        else
242
                edgecntr        <= 0;
243
                if (c_cpol = '0') then
244
                        sclk    <= '0';
245
                else
246
                        sclk    <= '1';
247
                end if;
248
        end if;
249
 
250
end if;
251
end process;
252
 
253
end Behavioral;

powered by: WebSVN 2.1.0

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