Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
18 years ago

Cyclone II is not working correct???

Hello,

I have written a small process, which should read a dmx-signal (seriell signal with special timings).

THe whole thing is working realy good, but sometimes it makes things, which i haven`t programmed.

The dmx-reader is a state machine and sometimes, one state changes into another, which i haven`t writen (states which are never assigned occurs or the state change is not correct).

This is the source code for the state machine (it runs at 10MHz).

process (pwm_clock)
variable divider : integer := 0;
variable state : bit_vector (3 downto 0) :="0000";
variable dmx_data : std_logic_vector (0 to 7) :="00000000";
variable dmx_bit_value : integer := 0;
variable dmx_bit_count : integer := 0;
variable dmx_data_count : integer range 0 to 255 := 0;
variable dmx_data_position : integer range 0 to 511 := 0;
begin
if (rising_edge(pwm_clock)) then
	divider := divider +1;
	if(divider > 1) then
	divider := 0;
	-- different states
	case state is
	-- waiting for startbit
	when "0000" => 
		case check(dmx_in) is	
		when  '0' =>
			dmx_bit_value := dmx_bit_value +1;
		when '1'=>	
			if(dmx_bit_value > 430) then
				state := "0001";
			elsif(dmx_bit_value > 200) and (dmx_data = "00000000") then
				state := "0001";				
			end if;
			dmx_bit_value := 0;
			dmx_data_position := 0; 
		when others => null;
		end case;
	-- waiting for Mark after Break 
	when "0001" =>
		case check(dmx_in) is
		when '1'  => 
			dmx_data_count := dmx_data_count +1;
		when '0' =>
			if(dmx_data_count > 38) then
				state := "0010";
				dmx_data_count := 0;
			else
				dmx_data_count := 0;
			end if;
		when others => null;
		end case;
	-- waiting for Start Byte and startbit
	when "0010" =>
		case check(dmx_in) is
		when '0' => 
			dmx_data_count := dmx_data_count +1;
		when '1'=>
			if(dmx_data_count > 178) then
				state := "0011";
				dmx_data_count := 0;
			else
				state := "0000";
				dmx_data_count := 0;
			end if;
		when others => null;
		end case;
	-- waiting for 2 stopbits
	when "0011" =>
		case check(dmx_in) is
		when '1'=> 
			dmx_data_count := dmx_data_count +1;
		when '0'=>
			if(dmx_data_count > 38) then
				state := "0100";
				dmx_data_count := 0;
			else
				state := "0000";
				dmx_data_count := 0;
			end if;
		when others => 
				state := "0000";
				dmx_data_count := 0;
		end case;
	--receive startbit, after the startbit, you have to wait for 2 clocks, to sync back to the signal
	when "0100" =>
		dmx_data_count := dmx_data_count +1;
		if(dmx_data_count > 17) then
			if(dmx_bit_value > 13)then		
				state := "0101";
			else
				state:="0000";
			end if;
			dmx_data_count := 0;
			dmx_bit_value := 0;
		end if;
		case check(dmx_in) is	
		when '0' => 
			dmx_bit_value := dmx_bit_value +1;
		when others => 
			null;
		end case;		
-- Wait 2 clock (to avoid the signal flanks)
	when "0101" =>	
		dmx_data_count := dmx_data_count +1;
		if(dmx_data_count > 1) then 
			state :="0110";
			dmx_data_count := 0;
			dmx_bit_value := 0;
			dmx_bit_count :=0;
		end if;		
-- Receive the data_bytes
	when "0110" =>	
		-- Receive for 19 Clocks and check the signal
		case check(dmx_in) is
		when '1'=> 
			dmx_bit_value := dmx_bit_value +1;
		when others => null;	
		end case;
		dmx_data_count := dmx_data_count +1;	
		if(dmx_data_count > 17) then
		-- if more then 14 received bits are '1' then the transmitted bit is 1
			if(dmx_bit_value > 13) then
				dmx_data(7-dmx_bit_count) := '1';
			else				
				dmx_data(7-dmx_bit_count) := '0';
			end if;
			dmx_data_count := 0;
			dmx_bit_count := dmx_bit_count +1;
			state :="0111";	
		end if;	
--	wait for 2 Clocks (to avoid the signal flanks)
		when "0111" =>
		dmx_data_count := dmx_data_count +1;	
		if(dmx_data_count > 1) then 
			state :="0110";
			dmx_data_count := 0;
			dmx_bit_value := 0;	
			-- check if 8 bits are received
			if(dmx_bit_count > 7) then
				dmx_bit_count := 0;		
				dmx_data_count := 0;
				state:="1000";
			end if;
		end if;		
-- wait for the 2 Stopbits and check, if the signal is correct, or if it is a new start signal
		when "1000" =>		
		case check(dmx_in) is
		when '1' => 
			dmx_bit_value := dmx_bit_value +1;
		when others => null;	
		end case;
		dmx_data_count := dmx_data_count +1;
		
		if(dmx_data_count > 38) then	
		
			if(dmx_bit_value > 30) then
				dmx_pwm_integer_value(dmx_data_position) := conv_integer(dmx_data);
				--leds <= dmx_data;
				dmx_data_position := dmx_data_position +1;
				dmx_bit_value := 0;
				state :="1001";				
			else
				state :="0000";	
			end if;
			dmx_data_count := 0;
			
		end if;	
-- wait for the next startbit
		when "1001" => 	
			if(check(dmx_in) = '0') then						
				state := "0100";
			end if;
		when others =>state:="0000";
		end case;
	
	end if;
end if;
end process;

Examples of wrong state changes:

Here the State machine changes from 1001b to 1010b which is not declared (it should change to 0100b.

http://ej-lighting.at/stp1.jpg

A change from 1001b to 1011b which is never declared!!

http://ej-lighting.at/stp2.jpg

At the moment I have no Idea what could be wrong in this implementation.

Thanks

Thomas Brunner

11 Replies