Altera_Forum
Honored Contributor
18 years agoCyclone 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