--===========================================================================-- -- -- S Y N T H E Z I A B L E miniUART C O R E -- -- www.OpenCores.Org - January 2000 -- This core adheres to the GNU public license -- -- Design units : miniUART core for the OCRP-1 -- -- File name : miniuart.vhd -- -- Purpose : Implements an miniUART device for reception of DMX -- signal. -- -- Library : uart_lib.vhd -- -- Dependencies : IEEE.Std_Logic_1164 -- -- Simulator : ModelSim PE/PLUS version 4.7b on a Windows95 PC --===========================================================================-- ------------------------------------------------------------------------------- -- Revision list -- Version Author Date Changes -- -- 0.1 Ovidiu Lupas 15 January 2000 New model -- 1.0 Ovidiu Lupas January 2000 Synthesis optimizations -- 2.0 Ovidiu Lupas April 2000 Bugs removed - RSBusCtrl -- the RSBusCtrl did not process all possible situations -- 2.1 Ed Feb 2007 Major rewrite for DMX reception -- -- olupas@opencores.org ------------------------------------------------------------------------------- -- Entity for DMXuart Unit - 250K baudrate -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --library work; -- use work.UART_Def.all; entity DMXuart is port ( SysClk : in Std_Logic; -- System Clock Reset : in Std_Logic; -- Reset input RxD : in Std_Logic; DataRdy : out Std_Logic; -- Externalised Drdy signal --DataOut : out Std_Logic_Vector(7 downto 0); -- BreakDetected : out Std_Logic; DMXAddr : in Unsigned(7 downto 0); Channel0 : out Std_Logic_Vector(7 downto 0); -- Channel1 : out Std_Logic_Vector(7 downto 0); -- Channel2 : out Std_Logic_Vector(7 downto 0); -- Channel3 : out Std_Logic_Vector(7 downto 0); Channel4 : out Std_Logic_Vector(7 downto 0); -- Channel5 : out Std_Logic_Vector(7 downto 0)); end entity; --================== End of entity ==============================-- ------------------------------------------------------------------------------- -- Architecture for miniUART Controller Unit ------------------------------------------------------------------------------- architecture uart of DMXuart is ----------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------- type STATE_TYPE is (WAITFORBREAK, WAITFORSTARTBYTE, WAITFORDMXADDR, WAITFORDMXADDREND); signal State : STATE_TYPE := WAITFORBREAK; signal RxData : Std_Logic_Vector(7 downto 0) := "00000000"; -- signal BREAK : Std_Logic := '0'; -- Frame error --signal BitCnt : Std_Logic_Vector(4 downto 0); signal BitStart : Std_Logic := '0'; shared variable DMXaddress : Integer range 0 to 255 :=0; shared variable ByteNumber : Integer range 0 to 255 :=0; constant CntOne : Unsigned(3 downto 0):="0001"; --signal ByteAddr : Unsigned(3 downto 0); -- samples on one bit counter ----------------------------------------------------------------------------- -- Receive Unit ----------------------------------------------------------------------------- component RxUnit is port ( Clk : in Std_Logic; -- Clock signal Reset : in Std_Logic; -- Reset input RxD : in Std_Logic; -- RS-232 data input BREAK : out Std_Logic; -- Status signal DataIn : out Std_Logic_Vector(7 downto 0); BitStart: out Std_Logic); end component; begin ----------------------------------------------------------------------------- -- Instantiation of internal components ----------------------------------------------------------------------------- RxDev : RxUnit port map (SysClk,Reset,RxD,BREAK,RxData,BitStart); ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Background processes ----------------------------------------------------------------------------- BreakDetected <= BREAK; ----------------------------------------------------------------------------- -- Combinational section ----------------------------------------------------------------------------- process(SysClk, DMXAddr, State, BitStart) begin --DMXaddress := To_Integer(DMXAddr); --if State = WAITFORDMXADDREND then DataRdy <= BitStart; --else -- DataRdy <= '0'; --end if; end process; ----------------------------------------------------------------------------- -- State machine ----------------------------------------------------------------------------- process(BREAK, BitStart,Reset, RxData) --variable ByteNumber : Integer range 0 to 512 :=0; --variable DMXaddress : Integer range 0 to 255 :=0; begin if (Reset = '0') then State <= WAITFORBREAK; elsif (BitStart'event and BitStart = '0') then DMXaddress := To_Integer(DMXAddr); case State is --======================================-- when WAITFORBREAK => -- Waiting for a new BREAK signal if BREAK = '1' then State <= WAITFORSTARTBYTE; -- Break detected, wait for 1st byte --DMXaddress := To_Integer(DMXAddr); ByteNumber := 0; end if; --======================================-- when WAITFORSTARTBYTE => -- Waiting for first byte (all zeros..) if RxData = "00000000" then State <= WAITFORDMXADDR; -- Start byte detected else State <= WAITFORBREAK; -- Go back to waiting for BREAK... end if; --======================================-- when WAITFORDMXADDR => -- Waiting for DMX address match if ByteNumber = DMXaddress then -- Are we at the start address yet? Channel0 <= RxData; ByteNumber := 0; -- reset the counter State <= WAITFORDMXADDREND; -- yes, so now wait for all channels to be received else ByteNumber := ByteNumber + 1; -- No, so increment the counter if (ByteNumber = 255) then -- Check for overrun... State <= WAITFORBREAK; -- Overflow, so go back to waiting for a BREAK signal end if; end if; if (BREAK = '1') then -- Keep a check on current conditions State <= WAITFORSTARTBYTE; -- Unexpected BREAK detected... ByteNumber := 0; -- Abandon everything! end if; --======================================-- when WAITFORDMXADDREND => ByteNumber := ByteNumber + 1; -- Increment counters if ByteNumber = 6 then -- have we received all channels? State <= WAITFORBREAK; -- yes, so go back to waiting for a BREAK signal end if; case ByteNumber is when 1 => Channel1 <= RxData; when 2 => Channel2 <= RxData; when 3 => Channel3 <= RxData; when 4 => Channel4 <= RxData; when 5 => Channel5 <= RxData; when others => null; end case; if (BREAK = '1') then -- Check for unexpected BREAK signal State <= WAITFORSTARTBYTE; -- Abandon everything! ByteNumber := 0; end if; --======================================-- end case; end if; -- if reset = '0'... end process; end uart; --===================== End of architecture =======================--