zxuno-git/cores/MasterSystem/src/spi.vhd

78 lines
1.6 KiB
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity spi is
Port (
clk : in STD_LOGIC;
RD_n : in STD_LOGIC;
WR_n : in STD_LOGIC;
A : in STD_LOGIC_VECTOR (7 downto 0);
D_in : in STD_LOGIC_VECTOR (7 downto 0);
D_out : out STD_LOGIC_VECTOR (7 downto 0);
cs_n : buffer STD_LOGIC;
sclk : out STD_LOGIC;
miso : in STD_LOGIC;
mosi : out STD_LOGIC);
end spi;
architecture Behavioral of spi is
signal ready : std_logic := '1';
signal clk_div : unsigned(6 downto 0) := "0000000";
signal clk_cnt : unsigned(6 downto 0) := "0000000";
signal bit_cnt : unsigned(3 downto 0) := "0000";
signal shift : std_logic_vector(7 downto 0);
signal in_sclk : std_logic := '1';
begin
ready <= '1' when bit_cnt=0 else '0';
process (clk,A,WR_n,RD_n,D_in,miso)
begin
if rising_edge(clk) then
if ready='0' then
case clk_cnt is
when "0000000" =>
if in_sclk='1' then
mosi <= shift(7);
elsif in_sclk='0' then
shift <= shift(6 downto 0)&miso;
bit_cnt <= bit_cnt-1;
end if;
clk_cnt <= clk_div;
in_sclk <= not in_sclk;
when others =>
clk_cnt <= clk_cnt-1;
end case;
elsif WR_n='0' then
if A(0)='0' then
cs_n <= D_in(7);
clk_div <= unsigned(D_in(6 downto 0));
elsif ready='1' then
shift <= D_in;
bit_cnt <= "1000";
clk_cnt <= "0000001";
end if;
end if;
end if;
end process;
process (clk,A,WR_n,RD_n,D_in,miso)
begin
if rising_edge(clk) and RD_n='0' then
if A(0)='0' then
D_out <= ready&std_logic_vector(clk_div);
else
D_out <= shift;
end if;
end if;
end process;
sclk <= in_sclk;
end Behavioral;