1 | library IEEE;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.std_logic_arith.all;
|
4 |
|
5 | entity spi is
|
6 | port ( spi_Tx : out std_logic; -- SPI-lines
|
7 | spi_clk : out std_logic;
|
8 | spi_cs : out std_logic;
|
9 | spi_Rx : in std_logic;
|
10 |
|
11 | new_data : in std_logic; -- sign
|
12 |
|
13 | TxData : in std_logic_vector(7 downto 0);
|
14 | RxData : out std_logic_vector(7 downto 0);
|
15 |
|
16 | reset : in std_logic;
|
17 | clk : in std_logic);
|
18 | end spi;
|
19 |
|
20 | -------------------------------------------------------------------------------
|
21 | -- ARCHITECTURE
|
22 | -------------------------------------------------------------------------------
|
23 | architecture rtl of spi is
|
24 |
|
25 | signal s_TxBuf : std_logic_vector(7 downto 0);
|
26 | signal s_RxBuf : std_logic_vector(7 downto 0);
|
27 | signal s_cnt : std_logic_vector(4 downto 0);
|
28 | signal s_busy : std_logic;
|
29 |
|
30 | begin
|
31 |
|
32 | p_spi_master : process(clk,reset)
|
33 | begin
|
34 | if(reset = '1')then
|
35 | s_TxBuf <= (others => '0');
|
36 | s_RxBuf <= (others => '0');
|
37 | s_cnt <= (others => '0');
|
38 | s_busy <= '0';
|
39 | spi_cs <= '1';
|
40 | spi_clk <= '1';
|
41 | spi_Tx <= '1';
|
42 | elsif(clk = '1' and clk'event) then
|
43 | if(new_data = '1' and s_busy = '0')then
|
44 | s_TxBuf <= TxData;
|
45 | s_busy <= '1';
|
46 | s_cnt <= (others => '0');
|
47 | spi_cs <= '0';
|
48 | end if;
|
49 |
|
50 | if(s_busy = '1')then -- shifting is enabled
|
51 | s_cnt <= unsigned(s_cnt) + conv_unsigned(1,1);
|
52 | if(s_cnt(4) /= '1')then -- are 16 ticks over?
|
53 | if(s_cnt(0) = '0')then -- shift out data on every "even" LSB
|
54 | s_TxBuf <= s_TxBuf(6 downto 0) & '0'; -- shift operation
|
55 | spi_Tx <= s_TxBuf(7); -- data out
|
56 | spi_clk <= '0'; -- toggle sclk
|
57 | else -- s_cnt is "odd": rising sclk
|
58 | s_RxBuf <= s_RxBuf(6 downto 0) & spi_Rx; -- read RxLine
|
59 | spi_clk <= '1';
|
60 | end if;
|
61 | else -- 16th tick is reached
|
62 | -- bring module in 'idle'-state
|
63 | s_busy <= '0';
|
64 | spi_cs <= '1';
|
65 | spi_Tx <= '1';
|
66 | spi_clk <= '1';
|
67 | RxData <= s_RxBuf;
|
68 | s_TxBuf <= (others => '0');
|
69 | s_RxBuf <= (others => '0');
|
70 | s_cnt <= (others => '0');
|
71 | end if;
|
72 | end if;
|
73 | end if;
|
74 | end process p_spi_master;
|
75 | end rtl;
|