mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-01-03 07:10:09 +01:00
219 lines
6.7 KiB
VHDL
219 lines
6.7 KiB
VHDL
----------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer:
|
|
--
|
|
-- Create Date: 19:51:11 05/05/2020
|
|
-- Design Name:
|
|
-- Module Name: SPICommands - Behavioral
|
|
-- Project Name:
|
|
-- Target Devices:
|
|
-- Tool versions:
|
|
-- Description:
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
----------------------------------------------------------------------------------
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
|
|
-- Uncomment the following library declaration if using
|
|
-- arithmetic functions with Signed or Unsigned values
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
-- Uncomment the following library declaration if instantiating
|
|
-- any Xilinx primitives in this code.
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity SPICommands is
|
|
Port ( CLK : in STD_LOGIC;
|
|
RESET : in STD_LOGIC;
|
|
SCLK : in STD_LOGIC;
|
|
MOSI : in STD_LOGIC;
|
|
MISO : out STD_LOGIC;
|
|
NSS : in STD_LOGIC;
|
|
SOURCE_FILTER : out STD_LOGIC_VECTOR(1 downto 0);
|
|
SOURCE_ATTENUATION : out STD_LOGIC_VECTOR(6 downto 0);
|
|
SOURCE_BANDSELECT : out STD_LOGIC; -- 0: highband, 1: lowband
|
|
SOURCE_PORTSELECT : out STD_LOGIC; -- 0: Port 1, 1: Port 2
|
|
SOURCE_UNLOCKED : in STD_LOGIC;
|
|
|
|
-- Modulation FIFO signals
|
|
MOD_FIFO_DATA : out STD_LOGIC_VECTOR (7 downto 0);
|
|
MOD_FIFO_WRITE : out STD_LOGIC;
|
|
MOD_FIFO_UNDERFLOW : in STD_LOGIC;
|
|
MOD_FIFO_OVERFLOW : in STD_LOGIC;
|
|
MOD_FIFO_THRESHOLD_CROSSED : in STD_LOGIC;
|
|
MOD_FIFO_THRESHOLD : out STD_LOGIC_VECTOR (10 downto 0);
|
|
|
|
-- Modulation lookup table
|
|
MOD_LOOKUP_INDEX : out STD_LOGIC_VECTOR (7 downto 0);
|
|
MOD_LOOKUP_DATA : out STD_LOGIC_VECTOR (143 downto 0);
|
|
MOD_LOOKUP_WRITE : out STD_LOGIC;
|
|
|
|
-- Modulation control signals
|
|
MOD_ENABLE : out STD_LOGIC;
|
|
MOD_PHASE_INC : out STD_LOGIC_VECTOR (15 downto 0);
|
|
|
|
AMP_SHDN : out STD_LOGIC;
|
|
SOURCE_RF_EN : out STD_LOGIC;
|
|
SOURCE_CE_EN : out STD_LOGIC;
|
|
PORTSWITCH_EN : out STD_LOGIC;
|
|
LEDS : out STD_LOGIC_VECTOR(2 downto 0);
|
|
INTERRUPT_ASSERTED : out STD_LOGIC);
|
|
end SPICommands;
|
|
|
|
architecture Behavioral of SPICommands is
|
|
COMPONENT spi_slave
|
|
Generic(W : integer);
|
|
PORT(
|
|
SPI_CLK : in STD_LOGIC;
|
|
MISO : out STD_LOGIC;
|
|
MOSI : in STD_LOGIC;
|
|
CS : in STD_LOGIC;
|
|
BUF_OUT : out STD_LOGIC_VECTOR (W-1 downto 0) := (others => '0');
|
|
BUF_IN : in STD_LOGIC_VECTOR (W-1 downto 0);
|
|
CLK : in STD_LOGIC;
|
|
COMPLETE : out STD_LOGIC
|
|
);
|
|
END COMPONENT;
|
|
|
|
-- SPI control signals
|
|
signal spi_buf_out : std_logic_vector(15 downto 0);
|
|
signal spi_buf_in : std_logic_vector(15 downto 0);
|
|
signal spi_complete : std_logic;
|
|
signal word_cnt : integer range 0 to 19;
|
|
type SPI_states is (FirstWord, WriteModTable, WriteModulationData, WriteRegister);
|
|
signal state : SPI_states;
|
|
signal selected_register : integer range 0 to 31;
|
|
|
|
signal last_NSS : std_logic;
|
|
|
|
signal mod_table_write : std_logic;
|
|
signal mod_first_byte : std_logic;
|
|
signal mod_second_byte : std_logic;
|
|
signal mod_data_LSB : std_logic_vector(7 downto 0);
|
|
|
|
-- Configuration registers
|
|
signal interrupt_mask : std_logic_vector(15 downto 0);
|
|
signal interrupt_status : std_logic_vector(15 downto 0);
|
|
|
|
signal mod_lookup_buffer : std_logic_vector(127 downto 0);
|
|
|
|
begin
|
|
SPI: spi_slave
|
|
GENERIC MAP(w => 16)
|
|
PORT MAP(
|
|
SPI_CLK => SCLK,
|
|
MISO => MISO,
|
|
MOSI => MOSI,
|
|
CS => NSS,
|
|
BUF_OUT => spi_buf_out,
|
|
BUF_IN => spi_buf_in,
|
|
CLK => CLK,
|
|
COMPLETE =>spi_complete
|
|
);
|
|
|
|
MOD_FIFO_WRITE <= mod_first_byte or mod_second_byte;
|
|
MOD_LOOKUP_WRITE <= mod_table_write;
|
|
|
|
process(CLK, RESET)
|
|
begin
|
|
if rising_edge(CLK) then
|
|
if RESET = '1' then
|
|
AMP_SHDN <= '1';
|
|
SOURCE_RF_EN <= '0';
|
|
SOURCE_CE_EN <= '0';
|
|
PORTSWITCH_EN <= '0';
|
|
LEDS <= (others => '1');
|
|
interrupt_status <= (others => '0');
|
|
interrupt_mask <= (others => '0');
|
|
INTERRUPT_ASSERTED <= '0';
|
|
last_NSS <= '1';
|
|
MOD_ENABLE <= '0';
|
|
mod_first_byte <= '0';
|
|
mod_second_byte <= '0';
|
|
mod_table_write <= '0';
|
|
else
|
|
interrupt_status <= "00000000000" & MOD_FIFO_THRESHOLD_CROSSED & MOD_FIFO_UNDERFLOW & MOD_FIFO_OVERFLOW & SOURCE_UNLOCKED & "0";
|
|
if (interrupt_status and interrupt_mask) = "0000000000000000" then
|
|
INTERRUPT_ASSERTED <= '0';
|
|
else
|
|
INTERRUPT_ASSERTED <= '1';
|
|
end if;
|
|
if mod_first_byte = '1' then
|
|
mod_first_byte <= '0';
|
|
mod_second_byte <= '1';
|
|
MOD_FIFO_DATA <= mod_data_LSB;
|
|
end if;
|
|
if mod_second_byte = '1' then
|
|
mod_second_byte <= '0';
|
|
end if;
|
|
if mod_table_write = '1' then
|
|
mod_table_write <= '0';
|
|
end if;
|
|
last_NSS <= NSS;
|
|
if NSS = '0' and last_NSS = '1' then
|
|
word_cnt <= 0;
|
|
spi_buf_in <= interrupt_status;
|
|
state <= FirstWord;
|
|
elsif spi_complete = '1' then
|
|
word_cnt <= word_cnt + 1;
|
|
case state is
|
|
when FirstWord =>
|
|
-- initial word determines action
|
|
case spi_buf_out(15 downto 13) is
|
|
when "000" => state <= WriteModTable;
|
|
-- also extract the index
|
|
MOD_LOOKUP_INDEX <= spi_buf_out(7 downto 0);
|
|
when "010" => state <= FirstWord;
|
|
spi_buf_in <= "1111000010100101";
|
|
when "100" => state <= WriteRegister;
|
|
selected_register <= to_integer(unsigned(spi_buf_out(4 downto 0)));
|
|
when "001" => state <= WriteModulationData;
|
|
when others => state <= FirstWord;
|
|
end case;
|
|
when WriteRegister =>
|
|
-- write received data into previously selected register
|
|
case selected_register is
|
|
when 0 => interrupt_mask <= spi_buf_out;
|
|
when 1 => SOURCE_FILTER <= spi_buf_out(15 downto 14);
|
|
MOD_ENABLE <= spi_buf_out(12);
|
|
SOURCE_ATTENUATION <= spi_buf_out(11 downto 5);
|
|
SOURCE_BANDSELECT <= spi_buf_out(4);
|
|
SOURCE_PORTSELECT <= spi_buf_out(3);
|
|
SOURCE_CE_EN <= spi_buf_out(2);
|
|
SOURCE_RF_EN <= spi_buf_out(1);
|
|
AMP_SHDN <= spi_buf_out(0);
|
|
when 2 => MOD_ENABLE <= spi_buf_out(0);
|
|
LEDS <= not spi_buf_out(15 downto 13);
|
|
when 3 => MOD_PHASE_INC <= spi_buf_out;
|
|
when 4 => MOD_FIFO_THRESHOLD <= spi_buf_out(10 downto 0);
|
|
when others =>
|
|
end case;
|
|
selected_register <= selected_register + 1;
|
|
when WriteModTable =>
|
|
if word_cnt = 9 then
|
|
MOD_LOOKUP_DATA <= mod_lookup_buffer & spi_buf_out;
|
|
mod_table_write <= '1';
|
|
else
|
|
mod_lookup_buffer <= mod_lookup_buffer(111 downto 0) & spi_buf_out;
|
|
end if;
|
|
when WriteModulationData =>
|
|
-- add two new bytes to the modulation data
|
|
MOD_FIFO_DATA <= spi_buf_out(15 downto 8);
|
|
mod_first_byte <= '1';
|
|
mod_data_LSB <= spi_buf_out(7 downto 0);
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
end Behavioral;
|
|
|