OpenCores
URL https://opencores.org/ocsvn/onewire/onewire/trunk

Subversion Repositories onewire

[/] [onewire/] [trunk/] [HDL/] [ow_temp.vhd] - Rev 2

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
--  <c>2018 william b hunter
--    This file is part of ow2rtd.
--
--    ow2rtd is free software: you can redistribute it and/or modify
--    it under the terms of the GNU Lessor General Public License as published by
--    the Free Software Foundation, either version 3 of the License, or
--    (at your option) any later version.
--
--    ow2rtd is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU Lessor General Public License
--    along with ow2rtd.  If not, see <https://www.gnu.org/licenses/>.
-----------------------------------------------------------------------------------  
--  Create Date: 5/15/2018
--  file: ow_temp.vhd
--  description: configures each ds1820 device, starts a conversion on each device, or reads the results
--    of each device. temps are set to 10 bit to shorten conversion times (and who needs 1/16 C resolution
--    when the accuracy is +-0.5C ). The temperatures are output on a bus with a strobe and a device index.
-----------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
--use work.p_ow_types.all;
 
-------------------------------------------------------------------------------------
-- Entity declaration
-------------------------------------------------------------------------------------
entity ow_temp is
  generic (
	  BITS : integer := 12;
    DEFTEMP : std_logic_vector(11 downto 0) := x"7ff";
    CRC : boolean := false
    );
  port (
    --global signals
	  clk              : in    std_logic;
    srst             : in    std_logic;
    busyin           : in    std_logic;  --busy signal from either ow_byte or ow_bit
    --signals to upper layer hierarchy
	  init             : in    std_logic; --init a device for temp reading
    conv             : in    std_logic; --send convert command to the device
    read             : in    std_logic; --read a device
    temp             : out   signed(15 downto 0);  --current device temp
    tempidx          : out   unsigned(4 downto 0); --current device index
    tempstb          : out   std_logic; --stobe indicating a temperature output
    busy             : out   std_logic;  --busy indication to higher level modules
		error            : out   std_logic;  --indicates a problem on the bus
    --signals to lower layer hierarchy (ow_bit and ow_byte)
    zzbit            : out   std_logic;  --reset strobe to ow_bit interface
    wrbit            : out   std_logic;  --write strobe to ow_bit interface
    ibit             : in    std_logic;  --the data read from the ow_bit interface
    obit             : out   std_logic;  --the data written to the ow_bit interface
	  rdbyte           : out   std_logic;  --read strobe to ow_byte interface
    wrbyte           : out   std_logic;  --write strobe to ow_byte interface
    obyte            : out   std_logic_vector(7 downto 0);  --data to write to the ow_byte
    ibyte            : in    std_logic_vector(7 downto 0);  --data read from the ow_byte
    --interface to id ram
    id_num           : out   std_logic_vector(4 downto 0); --index of the id to read or write
    id_bit           : out   std_logic_vector(5 downto 0); --index of the bit to read or write
    id_rbit          : in    std_logic  --bit value of the currently indexed bit of the current rom
  );
end ow_temp;
 
-------------------------------------------------------------------------------------
-- Architecture declaration
-------------------------------------------------------------------------------------
architecture rtl of ow_temp is
 
	type   t_state_type is (T_IDLE, T_GETTYPE, T_TXID, T_RST, T_TXTOUT, T_TXTOUT2, T_ERROR,
                          T_INIT, T_INIT1, T_INIT2, T_INIT3, T_INIT4,
                          T_CONV, T_CONV1, T_CONV2, T_CONV3, T_CONV4,
                          T_READ, T_READ1, T_READ2, T_READ3, T_READ4, T_READ5, T_READ6, T_READ7
                          );
  signal t_state : t_state_type := T_IDLE;
  signal t_next : t_state_type := T_IDLE;
 
	type slv8ary is array (integer range <>) of std_logic_vector(7 downto 0);
 
	constant ROMSTR  : integer := 1;
	constant ROMTXT : std_logic_vector( 7 downto 0) :=  x"55";
	constant ROMTXTLEN : integer := 1;
  constant INITSTR : integer := 2;
	constant INITTXT : slv8ary(1 to 4) := ( x"4e",x"7f",x"80",x"3f");
	constant INITTXTLEN : integer := INITTXT'length;
  constant CONVSTR : integer := 3;
	constant CONVTXT : std_logic_vector( 7 downto 0) := x"44";
	constant CONVTXTLEN : integer := 1;
  constant READSTR : integer := 4;
	constant READTXT : std_logic_vector( 7 downto 0) := x"be";
	constant READTXTLEN : integer := 1; --READTXT'length;
  constant LASTSTR : integer := READSTR;
 
  constant DS1822 : std_logic_vector(7 downto 0) := x"28";
 
  signal txtlen  : integer range 1 to 4;
  signal txtstr : integer range 1 to LASTSTR;
  signal txtptr : integer range 1 to 4;
  signal txbyte : std_logic_vector(7 downto 0);
 
  signal ididx    : integer range 0 to 31; --idx of the current device
	signal t_err    : std_logic := '0';
	signal irdbyte  : std_logic := '0';
	signal iwrbyte  : std_logic := '0';
	signal izzbit   : std_logic := '0';
  signal iwrbit   : std_logic := '0';
  --signal iobit    : std_logic := '0';
 
  signal readbits : integer range 1 to 10;
  signal shift    : std_logic_vector(15 downto 0);
  signal bytecnt  : integer range 0 to 9;
  signal bitcnt   : integer range 0 to 63;
  signal curid    : std_logic_vector(71 downto 0);
 
  signal stall : std_logic := '0'; -- this signal is used to stall the state machine one clock after each action
 
 
  --attribute mark_debug : string;
  --attribute mark_debug of pulse_state : signal is "true";
  --attribute mark_debug of timer : signal is "true";
 
 
begin
  ------------------------------------------------------
  --      TX MUX - mux between output commands       ---
  ------------------------------------------------------
  --select the byte to transmit from the text strings or the rom value
	txbyte <= CONVTXT when txtstr = CONVSTR  else READTXT when txtstr = READSTR
	        else ROMTXT when txtstr = ROMSTR else INITTXT(txtptr);
	txtlen <= CONVTXTLEN when txtstr = CONVSTR  else READTXTLEN when txtstr = READSTR
                  else ROMTXTLEN when txtstr = ROMSTR else INITTXTLEN;
 
  ------------------------------------------------------
  --      P_TEMP - INIT, CONV, READ temp sensors     ---
  ------------------------------------------------------
  --p_temp - sends rom match command followed by init command, convert command or 
  --         read command to the targeted temp sensor and reads data back (if a read command)
  p_temp : process (clk)
  begin
    if rising_edge(clk) then
      if srst = '1' then
        tempstb <= '0';
        t_state <= T_IDLE;
				t_err <= '0';
				izzbit <= '0';
        iwrbit <= '0';
        irdbyte <= '0';
        iwrbyte <= '0';
        ididx <= 0;
        bytecnt <= 0;
        bitcnt <= 0;
      elsif stall = '1' then
        tempstb <= '0';
        iwrbit <= '0';
        izzbit <= '0';
        iwrbyte <= '0';
        irdbyte <= '0';
        stall <= '0';
      else
          --allow 1 extra clock for ram read, temperature conversions
          --  but not when idle or we will miss the triggers
        if t_state /= T_IDLE then
          stall <= '1';
        end if;
        case t_state is
					when T_IDLE =>
            tempstb <= '0';
            obyte <= x"00";
            --shift <= x"000000000000000000";
            shift <= x"0000";
 				    izzbit <= '0';
            irdbyte <= '0';
            iwrbyte <= '0';
            izzbit <= '0';
            ididx <= 0;
            --shift <= x"00" & ids(ididx);
            --idtype <= x"00";
            bytecnt <= 0;
            bitcnt <= 0;
						if init = '1' then
              t_state <= T_GETTYPE;
              t_next <= T_INIT;
							t_err <= '0';
            elsif conv = '1' then
              t_state <= T_GETTYPE;
              t_next <= T_CONV;
              t_err <= '0'; 
            elsif read = '1' then
              t_state <= T_GETTYPE;
              t_next <= T_READ;
              t_err <= '0';
            end if;
          when T_GETTYPE =>
            --get the device type from the idrom
            shift(7 downto 0) <= id_rbit & shift(7 downto 1);
            if bitcnt = 7 then
              bitcnt <= 0;
              t_state <= t_next;
            else
              bitcnt <= bitcnt + 1;
            end if;
          when T_TXID =>
            if busyin = '0' then
              iwrbit <= '1';
              if bitcnt = 63 then
                t_state <= t_next;
                bitcnt <= 0;
              else
                bitcnt <= bitcnt + 1;
              end if;
            end if;
          when T_INIT =>
            if busyin = '0' then
              if shift(7 downto 0) = DS1822 then
                t_state <= T_RST;
                t_next <= T_INIT1;
                izzbit <= '1';
              else
                t_state <= T_INIT4;
              end if;
            end if;
          when T_INIT1 =>
            txtptr <= 1;
            txtstr <= ROMSTR;
            t_state <= T_TXTOUT;
            t_next <= T_INIT2;
          when T_INIT2 =>
            t_state <= T_TXID;
            t_next <= T_INIT3;
					when T_INIT3 =>
            txtptr <= 1;
            txtstr <= INITSTR;
            t_state <= T_TXTOUT;
            t_next <= T_INIT4;
					when T_INIT4 =>
            if ididx = 31 then
              t_state <= T_IDLE;
            else
              ididx <= ididx + 1;
              t_state <= T_GETTYPE;
              t_next <= T_INIT;
            end if;
          when T_CONV =>
            --this state cycles through all devices and initiates a conversion on all ds1822s
            if busyin = '0' then
              if shift(7 downto 0) = DS1822 then
                t_state <= T_RST;
                t_next <= T_CONV1;
                izzbit <= '1';
              else
                t_state <= T_CONV4;
              end if;
            end if;
          when T_CONV1 =>
            txtptr <= 1;
            txtstr <= ROMSTR;
            t_state <= T_TXTOUT;
            t_next <= T_CONV2;
          when T_CONV2 =>
            t_state <= T_TXID;
            t_next <= T_CONV3;
          when T_CONV3 =>
            txtptr <= 1;
            txtstr <= CONVSTR;
            t_state <= T_TXTOUT;
            t_next <= T_CONV4;
					when T_CONV4 =>
            if ididx = 31 then
              t_state <= T_IDLE;
            else
              ididx <= ididx + 1;
              t_state <= T_GETTYPE;
              t_next <= T_CONV;
            end if;
          when T_READ =>
            --this state cycles through all devices and reads all ds18B20s
            if busyin = '0' then
              if shift(7 downto 0) = DS1822 then
                t_state <= T_RST;
                t_next <= T_READ1;
                izzbit <= '1';
              else
                t_state <= T_READ7;
              end if;
            end if;
          when T_READ1 =>
            txtptr <= 1;
            txtstr <= ROMSTR;
            t_state <= T_TXTOUT;
            t_next <= T_READ2;
          when T_READ2 =>
            t_state <= T_TXID;
            t_next <= T_READ3;
          when T_READ3 =>
            txtptr <= 1;
            txtstr <= READSTR;
            t_state <= T_TXTOUT;
            t_next <= T_READ4;
            bytecnt <= 0;
          when T_READ4 =>
            if busyin = '0' then
              irdbyte <= '1';
              bytecnt <= 0;
              t_state <= T_READ5;
            end if;
          when T_READ5 =>
            --this state cycles through the 9 bytes to read
            if busyin = '0' then
              --if  CRC = true then
              --  shift <= ibyte & shift(71 downto 8);
              --else
              --  shift <= x"00000000000000" & ibyte & shift(15 downto 8);
              --end if;
              shift <= ibyte & shift(15 downto 8);
              if (bytecnt = 1 and CRC = false) or (bytecnt = 9 and CRC = true) then
                t_state <= T_READ6;
              else
                bytecnt <= bytecnt + 1;
                irdbyte <= '1';
              end if;
            end if;
					when T_READ6 =>
            tempstb <= '1';
            t_state <= T_READ7;
					when T_READ7 =>
            tempstb <= '0';
            if ididx = 31 then
              t_state <= T_IDLE;
            else
              ididx <= ididx + 1;
              t_state <= T_GETTYPE;
              t_next <= T_READ;
            end if;
          when T_RST =>
            if busyin = '0' then
              if ibit = '1' then
                t_state <= T_ERROR;
              else
                t_state <= t_next;
              end if;
            end if;
          when T_TXTOUT =>
            if busyin = '0' then
              --if txtstr = ROMSTR and txtptr > 1 then
              --  obyte <= shift(7 downto 0);
              --  shift <= shift(7 downto 0) & shift(71 downto 8);
              --else
                obyte <= txbyte;
              --end if;
              iwrbyte <= '1';
              t_state <= T_TXTOUT2;
            end if;
          when T_TXTOUT2 =>
            iwrbyte <= '0';
            if txtptr = txtlen then
              t_state <= t_next;
              txtptr <= 1;
            else
              txtptr <= txtptr + 1;
              t_state <= T_TXTOUT;
            end if;
					when T_ERROR =>
						t_err <= '1';
						t_state <= T_IDLE;
				end case;
			end if;
    end if;
  end process p_temp;
 
  ------------------------------------------------------
  --                External Signals                 ---
  ------------------------------------------------------
 
	temp <= signed(shift(15 downto 0));
	tempidx <= to_unsigned(ididx,5);
 
  busy <= '0' when t_state = T_IDLE and conv = '0' and init = '0' and read = '0' else '1';  
  wrbyte <= iwrbyte;
  rdbyte <= irdbyte;
  zzbit <= izzbit;
  wrbit <= iwrbit;
  obit <= id_rbit;
  id_num <= std_logic_vector(to_unsigned(ididx,5));
  id_bit <= std_logic_vector(to_unsigned(bitcnt,6));
 
  error <= t_err;  
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.