From: Ingo Froehlich Date: Thu, 25 Jan 2018 16:48:39 +0000 (+0100) Subject: temp sensor and uid working, IF X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=1f6ca11a3a9a58d97079ad88c7fdf685e0db292a;p=padiwa.git temp sensor and uid working, IF --- diff --git a/amps2/padiwa_amps2.vhd b/amps2/padiwa_amps2.vhd index 189dd97..08ba7ec 100644 --- a/amps2/padiwa_amps2.vhd +++ b/amps2/padiwa_amps2.vhd @@ -57,7 +57,7 @@ architecture arch of padiwa_amps2 is -- signal ram_data_o: std_logic_vector(7 downto 0); -- signal ram_addr_i: std_logic_vector(3 downto 0); signal temperature_i : std_logic_vector(11 downto 0); - + signal ID_OUT : std_logic_vector(31 downto 0); signal pwm_i : std_logic_vector(32 downto 1); signal INP_i : std_logic_vector(15 downto 0); @@ -184,35 +184,10 @@ THE_PLL : entity work.pll_in133_out33_133_266 --------------------------------------------------------------------------- -- SPI Interface --------------------------------------------------------------------------- ---THE_SPI_SLAVE : entity work.spi_slave --- port map( --- CLK => clk_i, --- SPI_CLK => SPI_CLK, --- SPI_CS => SPI_CS, --- SPI_IN => SPI_IN, --- SPI_OUT => buf_SPI_OUT, --- DATA_OUT => spi_data_i, --- REG00_IN => spi_reg00_i, --- REG10_IN => spi_reg10_i, --- REG20_IN => spi_reg20_i, --- REG40_IN => spi_reg40_i, --- OPERATION_OUT => spi_operation_i, --- CHANNEL_OUT => spi_channel_i, --- WRITE_OUT => spi_write_i, --- DEBUG_OUT => spi_debug_i --- ); - ---SPI_OUT <= buf_SPI_OUT; - ---spi_reg00_i <= pwm_data_o; --- spi_reg10_i <= idram(to_integer(unsigned(spi_channel_i(2 downto 0)))); --- spi_reg40_i <= flash_busy & flash_err & "000000" & ram_data_o; ---spi_reg10_i <= (others => '0'); ---spi_reg40_i <= '0' & '0' & "000000" & ram_data_o; THE_SPI : entity work.spi_slave port map( - CLK => clk_33, + CLK => clk_i, SPI_CLK => SPI_CLK, SPI_CS => SPI_CS, SPI_IN => SPI_IN, @@ -234,7 +209,9 @@ THE_SPI : entity work.spi_slave THE_FLASH_CONTROLLER : entity generic_flash_ctrl port map( - CLK => clk_33, + + CLK_l => clk_i, + CLK_f => clk_33, RESET => '0', SPI_DATA_IN => spi_data_out, @@ -255,7 +232,6 @@ THE_FLASH_CONTROLLER : entity generic_flash_ctrl ); - --------------------------------------------------------------------------- -- Temperature and UID reader --------------------------------------------------------------------------- @@ -264,7 +240,8 @@ TEMP_SENSOR_AND_UID: entity Amps2_TempSensor_UID port map( clk => clk_i, temperature => temperature_i, - sda => I2C_SCL, + ID_OUT => ID_OUT, + sda => I2C_SDA, scl => I2C_SCL ); @@ -290,7 +267,7 @@ end generate; --------------------------------------------------------------------------- THE_IO_REG : process begin - wait until rising_edge(clk_33); + wait until rising_edge(clk_i); bus_ready <= '0'; pwm_write_i <= '0'; spi_tx_data <= x"0000"; @@ -316,6 +293,10 @@ THE_IO_REG : process begin pwm_addr_i <= spi_addr(3 downto 0); else case spi_addr is + when x"10" => spi_tx_data <= ID_OUT(7 downto 0) & "00000000" ; + when x"11" => spi_tx_data <= "00000000" & ID_OUT(31 downto 24); + when x"12" => spi_tx_data <= ID_OUT(23 downto 8); + when x"13" => spi_tx_data <= ID_OUT(7 downto 0) & "00011100"; --"0x1C"+ when x"14" => spi_tx_data <= "0000" & temperature_i; when x"20" => spi_tx_data <= input_enable; when x"21" => spi_tx_data <= inp_status; @@ -470,8 +451,12 @@ last_inp_long_reg <= inp_long_reg when rising_edge(clk_i); --------------------------------------------------------------------------- -- Test Output --------------------------------------------------------------------------- - TEST_LINE(7 downto 0) <= selected_delay; - TEST_LINE(13 downto 8) <= (others => '0'); + --TEST_LINE(7 downto 0) <= selected_delay; + TEST_LINE(13) <= SPI_CLK; + TEST_LINE(12) <= SPI_out; + TEST_LINE(11) <= SPI_in; + + TEST_LINE(10 downto 8) <= (others => '0'); end architecture; diff --git a/source/Amps2_Interface.vhd b/source/Amps2_Interface.vhd index e17c9b6..8ea5a3f 100644 --- a/source/Amps2_Interface.vhd +++ b/source/Amps2_Interface.vhd @@ -1,4 +1,3 @@ - library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -6,192 +5,191 @@ use ieee.numeric_std.all; entity Amps2_Interface is generic( clk_frequency : integer := 133_000_000; - i2c_frequency : integer := 13_300 + i2c_frequency : integer := 100_000 ); port( --System clock. - clk : in std_logic; - reset : in std_logic; - temperature: out std_logic_vector(11 downto 0); + clk : in std_logic; + reset : in std_logic :='0'; + temperature : out std_logic_vector(11 downto 0); + ID_OUT : out std_logic_vector(31 downto 0); --I2C signals. - sda : inout std_logic; - scl : inout std_logic - + sda : inout std_logic; + scl : inout std_logic ); end Amps2_Interface; architecture Behavioral of Amps2_Interface is - --The address of the TCS34725. This device has only one possible address, - --so we won't genericize it. - constant addr_temp_sensor : std_logic_vector := "1001000"; - constant addr_UID : std_logic_vector := "1010000"; +constant addr_temp_sensor : std_logic_vector := "1001000"; +constant addr_UID : std_logic_vector := "1010000"; --Signals for data exchange with the core I2C controller. - signal temp_data_LSB,temp_data_MSB,data_UID,data_to_write, last_read_data : std_logic_vector(7 downto 0); - signal reading, ena, busy : std_logic; -signal address: std_logic_vector(6 downto 0); +--I2C commands . +constant temp_register_pointer : std_logic_vector := "00000000"; +constant UID_pointer : std_logic_vector := "11111100"; + --Signals for data exchange with the core I2C controller. + signal address: std_logic_vector(6 downto 0); + signal data_to_write, last_read_data : std_logic_vector(7 downto 0); + signal reading, transaction_active, controller_in_use : std_logic; +signal temp_data_MSB: std_logic_vector(7 downto 0); +signal temp_data_LSB : std_logic_vector(7 downto 0); --Rising edge detect for the "controller in use" signal. --A rising edge of this signal indicates that the I2C controller has accepted our data. signal controller_was_in_use : std_logic; - signal controller_accepted_data : std_logic; - + signal controller_accepted_data, new_data_available : std_logic; --I2C read/write constants. constant write : std_logic := '0'; constant read : std_logic := '1'; - --I2C commands . - constant pointer_register : std_logic_vector := "00000000"; - - signal current_byte_number : integer range 2 downto 0 := 0; - - --Core state machine logic. - type state_type is (startup,read_UID, wait_for_temp_sensor, send_first_command, - wait_for_read, start_read, read_data_temp_sensor, finish_1byte_read_and_continue, - finish_read_temp_sensor); - signal state : state_type := startup; - + type state_type is (STARTUP, SEND_POWER_COMMAND, TURN_POWER_ON, + WAIT_BEFORE_READING, SEND_READ_COMMAND, START_READ, FINISH_READ_AND_CONTINUE, FINISH_READ_AND_RESTART, + UID_send_adress,UID_WAIT_BEFORE_READING,UID_START_READ,UID_FINISH_READ_AND_CONTINUE,UID_FINISH_READ_AND_RESTART,UID_FINISH + ); + signal state : state_type := STARTUP; + + type byte_buffer is array(natural range <>) of std_logic_vector(7 downto 0); + signal read_buffer : byte_buffer(1 downto 0); + + signal current_byte_number : integer range 2 downto 0 := 0; + + --Create a simple read buffer for each of the sequential bytes. + type UID_byte_buffer is array(natural range <>) of std_logic_vector(7 downto 0); + signal UID_read_buffer : byte_buffer(4 downto 0); + + signal UID_current_byte_number : integer range 4 downto 0 := 0; + begin - -- - -- Instantiate our I2C controller. - -- - I2C_CONTROLLER: - entity i2c_master + + I2C_CONTROLLER: entity i2c_master generic map( - input_clk => 133_000_000, --Our system clock speed. - bus_clk => 13_300 + input_clk => clk_frequency, + bus_clk => i2c_frequency ) port map( - clk => clk, - reset_n => not(reset), - ena => ena, - addr => address, - rw => reading, - data_wr => data_to_write, - busy => busy, - data_rd => last_read_data, - ack_error => open, - sda => sda, - scl => scl - ); - - controller_was_in_use <= busy when rising_edge(clk); - controller_accepted_data <= busy and not controller_was_in_use; - - -process(clk,reset) -begin - - -- If our reset signal is being driven, restar the FSM. - if (reset = '1') then - state <= startup ; + clk => clk, + reset_n => not reset, + ena => transaction_active, + addr => address, + rw => reading, + data_wr => data_to_write, + busy => controller_in_use, + data_rd => last_read_data, + ack_error => open, + sda => sda, + scl => scl + ); + + controller_was_in_use <= controller_in_use when rising_edge(clk); + controller_accepted_data <= controller_in_use and not controller_was_in_use; + + process(clk) + begin + if reset = '1' then + state <= state_type'left; elsif rising_edge(clk) then - - --Keep the following signals low unless asserted. data_to_write <= (others => '0'); - - case state is - - when startup => - - if busy = '0' then - state <= read_UID; - end if; - - - when read_UID => - ena <= '1'; - reading <= read; - address <= addr_UID; - - if controller_accepted_data = '1' then - state <= wait_for_temp_sensor; - end if; - - - when wait_for_temp_sensor => - ena <= '0'; - - if busy = '0' then - state <= send_first_command; - data_UID <= last_read_data; - end if; - - - - when send_first_command => - ena <= '1'; - reading <= write; - address <= addr_temp_sensor; - data_to_write <= pointer_register; - - --Wait here for the I2C controller to accept the new transmission, and become busy. - if controller_accepted_data = '1' then - state <= wait_for_read; - end if; - when wait_for_read => - - ena<='0'; - current_byte_number <=0; - if busy = '0' then - state <= start_read; - end if; - - when start_read => - ena <= '1'; - reading <= read; - - --Wait for the controller to accept the read instruction. - if controller_accepted_data = '1' then - - if current_byte_number = 2 then - state <= finish_read_temp_sensor; + case state is + + when STARTUP => + if controller_in_use = '0' then + state <= WAIT_BEFORE_READING; + end if; + + when WAIT_BEFORE_READING => + + transaction_active <= '0'; + current_byte_number <= 0; + if controller_in_use = '0' then + state <= START_READ; + end if; + + when START_READ => + transaction_active <= '1'; + reading <= read; + address <= addr_temp_sensor; + if controller_accepted_data = '1' then + if current_byte_number = read_buffer'high then + state <= FINISH_READ_AND_RESTART; else - state <= finish_1byte_read_and_continue; + state <= FINISH_READ_AND_CONTINUE; end if; - - end if; - - when finish_1byte_read_and_continue => - - --Wait for the I2C controller to finish reading... - if busy = '0' then - - --...capture the read result. - case current_byte_number is - when 0 => - temp_data_MSB<= last_read_data; - - when 1 => - temp_data_LSB<= last_read_data; - - when others => - state <= finish_read_temp_sensor; - - end case; - --... move to the next spot in the read buffer. + end if; + + when FINISH_READ_AND_CONTINUE => + if controller_in_use = '0' then + read_buffer(current_byte_number) <= last_read_data; current_byte_number <= current_byte_number + 1; - - ---... and finish reading. - state <= start_read; - - end if; - - when finish_read_temp_sensor => - - when others => - ena <= '1'; - - end case; - end if; - end process; - - -temperature(11 downto 4)<=temp_data_MSB; -temperature(3 downto 0)<=temp_data_LSB(7 downto 4); - - end Behavioral; + state <= START_READ; + end if; + + when FINISH_READ_AND_RESTART => + transaction_active <= '0'; + if controller_in_use = '0' then + read_buffer(current_byte_number) <= last_read_data; + state <= UID_send_adress; + end if; + ----------------------------------------------------------------------------------------- +----------------------------------------------------------------------------------------- + when UID_send_adress => + transaction_active <= '1'; + reading <= write; + data_to_write <= UID_pointer; + address <= addr_UID; + --UID_current_byte_number <= 0; + if controller_accepted_data = '1' then + state <= UID_START_READ; + end if; + + when UID_WAIT_BEFORE_READING => + transaction_active <= '0'; + UID_current_byte_number <= 0; + if controller_in_use = '0' then + state <= UID_START_READ; + end if; + + when UID_START_READ => + transaction_active <= '1'; + reading <= read; + if controller_accepted_data = '1' then + if UID_current_byte_number = UID_read_buffer'high then + state <= UID_FINISH_READ_AND_RESTART; + else + state <= UID_FINISH_READ_AND_CONTINUE; + end if; + end if; + + when UID_FINISH_READ_AND_CONTINUE => + + if controller_in_use = '0' then + UID_read_buffer(UID_current_byte_number) <= last_read_data; + UID_current_byte_number <= UID_current_byte_number + 1; + state <= UID_START_READ; + end if; + + when UID_FINISH_READ_AND_RESTART => + transaction_active <= '0'; + if controller_in_use = '0' then + UID_read_buffer(UID_current_byte_number) <= last_read_data; + state <= UID_FINISH; + end if; + + when UID_FINISH => + end case; + end if; + end process; +temp_data_LSB <= read_buffer(1); +temp_data_MSB <= read_buffer(0); +temperature(11 downto 4) <=temp_data_MSB; +temperature(3 downto 0) <=temp_data_LSB(7 downto 4); + +ID_OUT(31 downto 24) <=UID_read_buffer(0); +ID_OUT(23 downto 16) <=UID_read_buffer(1); +ID_OUT(15 downto 8) <=UID_read_buffer(2); +ID_OUT(7 downto 0) <=UID_read_buffer(3); + +end Behavioral; diff --git a/source/Amps2_TempSensor_UID.vhd b/source/Amps2_TempSensor_UID.vhd index 1563b8a..f6678eb 100644 --- a/source/Amps2_TempSensor_UID.vhd +++ b/source/Amps2_TempSensor_UID.vhd @@ -10,6 +10,7 @@ entity Amps2_TempSensor_UID is port( clk : in std_logic; temperature: out std_logic_vector(11 downto 0); + ID_OUT: out std_logic_vector(31 downto 0); --I2C signals. sda : inout std_logic; scl : inout std_logic @@ -17,60 +18,37 @@ entity Amps2_TempSensor_UID is end Amps2_TempSensor_UID; architecture Behavioral of Amps2_TempSensor_UID is - --signal clk : std_logic; signal reset : std_logic; - signal count : std_logic_vector (26 downto 0); + signal count : integer range 0 to 133_000_000 := 0; signal temporal: std_logic; - component OSCH - generic( - NOM_FREQ: string := "133"); - port( - STDBY : in std_logic; - OSC : out std_logic; - SEDSTDBY : out std_logic); - end component; - begin -- temperature <= "1111" & x"AB"; - - SENSOR_INTERFACE: entity Amps2_Interface generic map( clk_frequency => 133_000_000, - i2c_frequency => 13_300 + i2c_frequency => 100_000 ) port map( clk => clk, reset => reset, temperature => temperature, + ID_OUT => ID_OUT, sda => sda, scl => scl ); -------internal clock------------ ---OSCInst0: OSCH --- GENERIC MAP (NOM_FREQ => "133") --- PORT MAP (STDBY => '0', OSC => clk, SEDSTDBY => OPEN); - process begin wait until rising_edge(clk); - count <= count + 1; - if (count(26)='1') then - reset <= NOT(temporal); - count<=(others=>'0'); + if (count=133_000_000) then + temporal <= NOT(temporal); + count<=0; end if; end process; - reset <= temporal; --------timer--------- ---TIMER: entity timer --- port map( --- clk => clk, --- reset => reset --- ); + end Behavioral; diff --git a/source/i2c_master.vhd b/source/i2c_master.vhd index 6c18588..f63a6c6 100644 --- a/source/i2c_master.vhd +++ b/source/i2c_master.vhd @@ -6,7 +6,7 @@ USE ieee.std_logic_unsigned.all; ENTITY i2c_master IS GENERIC( input_clk : INTEGER := 133_000_000; --input clock speed from user logic in Hz - bus_clk : INTEGER := 13_300); --speed the i2c bus (scl) will run at in Hz + bus_clk : INTEGER := 100_000); --speed the i2c bus (scl) will run at in Hz PORT( clk : IN STD_LOGIC; --system clock reset_n : IN STD_LOGIC; --active low reset @@ -209,4 +209,4 @@ BEGIN scl <= scl_clk WHEN scl_ena = '1' ELSE 'Z'; sda <= '0' WHEN sda_ena_n = '0' ELSE 'Z'; -END logic; \ No newline at end of file +END logic;