-- **************************************************************** -- RS232 Receiver/Transmitter Package -- **************************************************************** library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; package RS232 is type SpeedROM_type is array(0 to 15) of std_logic_vector(15 downto 0); constant SpeedROM : SpeedROM_type := (x"5161", x"28B1", x"1458", x"0D90", x"0A2C", x"06C8", x"0516", x"0364", x"028B", x"01B2", x"00C8", x"0032", x"0032", x"0032", x"0032", x"0032"); -- 2400, 4800, 9600, 14440, 19200, 28800, 38400, 57600, 76800, 115200, 250000, 1000000 Baud component RS232_rx is Port (Clock : in std_logic; Rxd : in std_logic; Request : out std_logic; Grant : in std_logic; Data : out std_logic_vector(7 downto 0); Error : out std_logic; CfgSpeed : in std_logic_vector(3 downto 0); CfgParity : in std_logic; CfgParityType : in std_logic; Debug : out std_logic_vector(7 downto 0) ); end component; component RS232_tx is Port (Clock : in std_logic; Txd : out std_logic; Request : in std_logic; Grant : out std_logic; Data : in std_logic_vector(7 downto 0); CfgSpeed : in std_logic_vector(3 downto 0); CfgParity : in std_logic; CfgParityType : in std_logic ); end component; end RS232; -- **************************************************************** -- RS232 Receiver -- **************************************************************** library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.RS232.all; entity RS232_rx is Port (Clock : in std_logic; Rxd : in std_logic; Request : out std_logic := '0'; Grant : in std_logic; Data : out std_logic_vector(7 downto 0) := x"00"; Error : out std_logic; CfgSpeed : in std_logic_vector(3 downto 0); CfgParity : in std_logic; CfgParityType : in std_logic; Debug : out std_logic_vector(7 downto 0) ); end RS232_rx; architecture Behavioral of RS232_rx is signal Baud : std_logic_vector(1 downto 0) := "00"; signal RxReg : std_logic_vector(1 downto 0); signal GrantReg : std_logic_vector(1 downto 0); signal State : integer range 0 to 10 := 0; -- RS232 Receiver signal State2 : integer range 0 to 3 := 0; -- Handshake signal Din : std_logic_vector(7 downto 0); signal Din_tmp : std_logic_vector(7 downto 0); signal Handshake : std_logic := '0'; signal Cmp : std_logic_vector(15 downto 0); begin Cmp <= SpeedROM(conv_integer(CfgSpeed)); process(Clock) variable Cnt : std_logic_vector(15 downto 0):=x"0000"; variable Enabled : std_logic := '0'; begin if Clock'event and Clock='1' then -- Abtastung RxReg <= RxReg(0) & Rxd; GrantReg <= GrantReg(0) & Grant; Baud <= Baud(0) & Baud(0); -- Start-Bedingung if (RxReg = "10") and (Enabled = '0') then Enabled := '1'; Cnt := x"0000"; Baud <= "00"; State <= 0; Error <= '0'; end if; if Enabled = '1' then -- Baud-Takt erzeugen if Cnt = ('0' & Cmp(15 downto 1)) then Baud <= Baud(0) & '1'; elsif Cnt = Cmp then Baud <= Baud(0) & '0'; Cnt := x"0000"; end if; Cnt := Cnt + 1; end if; if (Enabled='1') and (Baud = "01") then -- Empfangsautomat case State is when 0 => -- Startstd_logic if Rxd = '1' then Error <= '1'; end if; when 1 to 7 => -- Datenstd_logics 1-7 Din <= Rxd & Din(7 downto 1); when 8 => -- Datenstd_logic 8 Din <= Rxd & Din(7 downto 1); when 9 => -- Parity-std_logic oder 1. Stopp-std_logic if CfgParity='1' then if (Din(0) xor Din(1) xor Din(2) xor Din(3) xor Din(4) xor Din(5) xor Din(6) xor Din(7))=CfgParityType then Error <= '0'; else Error <= '1'; end if; else Enabled := '0'; end if; when others => -- 2. Stopp-std_logic / Wartezustand Enabled := '0'; end case; if (Enabled = '0') and (Handshake = '0') then Din_tmp <= Din; Debug <= Din; Handshake <= '1'; end if; State <= State + 1; end if; -- Handshake-Automat if Handshake = '1' then case State2 is when 0 => Data <= Din_tmp; State2 <= State2 + 1; when 1 => Request <= '1'; State2 <= State2 + 1; when 2 => if GrantReg = "01" then Request <= '0'; State2 <= State2 + 1; end if; when others => if GrantReg = "10" then Handshake <= '0'; State2 <= 0; end if; end case; end if; end if; end process; end Behavioral; -- **************************************************************** -- RS232 Transmitter -- **************************************************************** library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.RS232.all; entity RS232_tx is Port (Clock : in std_logic; Txd : out std_logic := '1'; Request : in std_logic; Grant : out std_logic := '0'; Data : in std_logic_vector(7 downto 0); CfgSpeed : in std_logic_vector(3 downto 0); CfgParity : in std_logic; CfgParityType : in std_logic ); end RS232_tx; architecture Behavioral of RS232_tx is signal ReqBuf : std_logic := '0'; signal Cmp : std_logic_vector(15 downto 0); signal Baud : std_logic_vector(1 downto 0) := "00"; signal State : integer range 0 to 15 := 0; signal Byte : std_logic_vector(7 downto 0); signal TxdSig : std_logic := '1'; signal GrantSig : std_logic; begin Txd <= TxdSig; Grant <= GrantSig; Cmp <= SpeedROM(conv_integer(CfgSpeed)); process(Clock) variable Run : std_logic := '0'; variable Cnt : std_logic_vector(15 downto 0) := x"0000"; begin if Clock'event and Clock='1' then if ReqBuf='0' then GrantSig <= '0'; end if; if ReqBuf='1' and Run='0' and GrantSig='0' then Run := '1'; Byte <= Data; Cnt := x"0000"; end if; Baud <= Baud(0) & Baud(0); if Run='1' then if Cnt = ('0' & Cmp(15 downto 1)) then Baud <= Baud(0) & '1'; elsif Cnt = Cmp then Baud <= Baud(0) & '0'; Cnt := x"0000"; end if; Cnt := Cnt + 1; end if; if (Run='1') and (Baud="01") then case State is when 0 => TxdSig <= '0'; -- Startstd_logic State <= State + 1; when 1 to 8 => -- Datenstd_logics --Debug(15 downto 8) <= Byte; TxdSig <= Byte(0); Byte <= Byte(0) & Byte(7 downto 1); State <= State + 1; when others => -- Stopstd_logic TxdSig <= '1'; Run := '0'; State <= 0; GrantSig <= '1'; end case; end if; ReqBuf <= Request; end if; end process; end Behavioral;