+ Post New Thread
Results 1 to 8 of 8
  1. #1
    Newbie level 3
    Points: 53, Level: 1

    Join Date
    Sep 2018
    Posts
    4
    Helped
    0 / 0
    Points
    53
    Level
    1

    Reading data from MPU6050 reads only the who am I register

    I am trying to read data from MPU 6050 to my Basys 2 board using I2c master from https://www.digikey.com/eewiki/pages...ageId=10125324

    I was able to read the who am I register successfully, But sometime I get the value zero for other register set such as accelerometer or magnetometer. Is there a specific reason for this I can share the rest of the codes if required?

    •   AltAdvertisment

        
       

  2. #2
    Advanced Member level 4
    Points: 7,695, Level: 20
    Achievements:
    7 years registered Created Blog entry
    dpaul's Avatar
    Join Date
    Jan 2008
    Location
    Germay
    Posts
    1,140
    Helped
    248 / 248
    Points
    7,695
    Level
    20
    Blog Entries
    1

    Re: Reading data from MPU6050 reads only the who am I register

    But sometime I get the value zero for other register set such as accelerometer or magnetometer.
    The default read values for each register should always be the same. If you get the same read read values every time, then it can be concluded that the I2C is working as expected.
    .....yes, I do this for fun!



    •   AltAdvertisment

        
       

  3. #3
    Newbie level 3
    Points: 53, Level: 1

    Join Date
    Sep 2018
    Posts
    4
    Helped
    0 / 0
    Points
    53
    Level
    1

    Re: Reading data from MPU6050 reads only the who am I register

    No it is always zero even if I move the sensor, but sometimes it starts reading the registers, then it contiuously read.



    •   AltAdvertisment

        
       

  4. #4
    Super Moderator
    Points: 65,789, Level: 62
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    13,383
    Helped
    3086 / 3086
    Points
    65,789
    Level
    62

    Re: Reading data from MPU6050 reads only the who am I register

    Hi,

    show your code. (especially MPU initialisation and commands)
    and a scope picture of the communication could also be helpful. (timing, voltage levels)

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  5. #5
    Newbie level 3
    Points: 53, Level: 1

    Join Date
    Sep 2018
    Posts
    4
    Helped
    0 / 0
    Points
    53
    Level
    1

    Re: Reading data from MPU6050 reads only the who am I register

    I2c controller
    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    
    ENTITY u_logic IS
    PORT(
      clk         : IN   STD_LOGIC;                     --system clock
      reset_n     : IN   STD_LOGIC;                     --active low reset
      i2c_busy    : IN   STD_LOGIC;                     --i2c busy signal (talking to i2c slave)
      i2c_data_rd : IN   STD_LOGIC_VECTOR(7 DOWNTO 0);  --data received from i2c slave
                       --i2c acknowledge error flag
      i2c_ena     : OUT  STD_LOGIC;                     --latch command into i2c master
      i2c_addr    : OUT  STD_LOGIC_VECTOR(6 DOWNTO 0);  --i2c slave address
      i2c_rw      : OUT  STD_LOGIC;                     --i2c read/write command
      i2c_data_wr : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0);
      
      data_in     : IN   STD_LOGIC_VECTOR(23 DOWNTO 0);
      data_lcd    : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0)
      ); --data to write over the i2c bus
    END u_logic;
    
    ARCHITECTURE behavior OF u_logic IS
      TYPE machine IS(ready, i2c, combine);     --state machine datatype
      SIGNAL state         : machine;                       --current state
      SIGNAL i2c_busy_prev : STD_LOGIC;                     --previous busy signal for i2c transactions
      SIGNAL spi_rx_data   : STD_LOGIC_VECTOR(24 DOWNTO 0);
    BEGIN
    
      PROCESS(clk, reset_n)
        VARIABLE i2c_busy_cnt : INTEGER := 0;  --keeps track of i2c busy signals during transaction
      BEGIN
        IF(reset_n = '0') THEN                 --reset asserted
          i2c_busy_cnt := 0; 
          i2c_ena <= '0';
          state <= ready;
        ELSIF(clk'EVENT AND clk = '1') THEN
          CASE state IS
          
            WHEN ready =>
                state <= i2c;                  
            WHEN i2c =>
              i2c_busy_prev <= i2c_busy;                      --capture the value of the previous i2c busy signal
    					 IF(i2c_busy_prev = '0' AND i2c_busy = '1') THEN --i2c busy just went high
    						i2c_busy_cnt := i2c_busy_cnt + 1;       --counts the times busy has gone from low to high during transaction
    					 END IF;
    		     CASE i2c_busy_cnt IS                           --busy_cnt keeps track of which command we are on
                 WHEN 0 =>                                    --no command latched in yet
                  i2c_ena <= '1';                             --initiate the transaction
                  i2c_addr <= data_in(23 DOWNTO 17);          --slave address is this 7 bits of message
                  i2c_rw <= '0';                              --write the name of the slave register to access
                  i2c_data_wr <= data_in(15 DOWNTO 8);        --the slave register to access is these 8 bits
                 WHEN 1 =>                                    --1st busy high: command 1 latched, okay to issue command 2
    				  i2c_ena <= '1';  
                  i2c_rw <= data_in(16);                      --command to read or right the slave register is bit 16
                  i2c_data_wr <= data_in(7 DOWNTO 0);         --data to write to register (i2c master ignores if it's a read)
                 WHEN 2 =>                                    --2nd busy high: command 2 latched, ready to stop
                  i2c_ena <= '0';                             --deassert enable to stop transaction after command 2
                  IF(i2c_busy = '0') THEN                     --indicates command 2 is finished and any data is ready
                    IF(data_in(16) = '1') THEN                --if it was a read
                      data_lcd(7 DOWNTO 0) <= i2c_data_rd;    --retrieve data from command 2 into 8 LSBs of message
                    END IF;
                    i2c_busy_cnt := 0;                        --reset busy_cnt for next transaction
                    state <= ready;                           --transaction complete, load outcome into spi slave
                  END IF;
                 WHEN OTHERS => NULL;
              END CASE;	  
            WHEN OTHERS => NULL;			 
    			 END CASE;			 
    	   END IF;
      END PROCESS;
    
    END behavior;
    Register configuration

    Code:
    library ieee ;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity mpu6050_regs is
    port (
    		clk      : IN  STD_LOGIC; 
      		reset    : IN  STD_LOGIC;
    		i2c_busy : IN  STD_LOGIC;  
      		reg_data : OUT STD_LOGIC_VECTOR(23 downto 0)
    		);
    end mpu6050_regs;
    
    architecture behv_cd of mpu6050_regs is
    
      TYPE machine IS(configs, reader);     
      SIGNAL state         : machine;                    
      SIGNAL i2c_busy_prev : STD_LOGIC; 
    begin
    
    PROCESS(clk, reset)
     VARIABLE count : INTEGER := 0; 
      BEGIN
     IF(reset        = '1') THEN        
    	 count       := 0;
    	state        <= configs;
     ELSIF rising_edge(clk) THEN
    	CASE state IS 
    		  WHEN configs =>
    					 i2c_busy_prev <= i2c_busy;                    
    				 IF(i2c_busy_prev  = '0' AND i2c_busy = '1') THEN  count := count + 1;  END IF;
    					CASE count IS                           
    								 WHEN 0 =>  reg_data  <= "1101000"&"0"&"00011001"&"00000111";--(0x19)
    								 WHEN 1 =>  reg_data  <= "1101000"&"0"&"01101011"&"00000001";--(0x6B)
    								 WHEN 2 =>  reg_data  <= "1101000"&"0"&"01101100"&"00000000";--(0x6C)
    								 WHEN 3 =>  reg_data  <= "1101000"&"0"&"00011010"&"00000000";--(0x1A)								 
    								 WHEN 4 =>  reg_data  <= "1101000"&"0"&"00011011"&"00011000";--(0x1B)                     
    								 WHEN 5 =>  reg_data  <= "1101000"&"0"&"00011100"&"00000000";--(0x1C)	
    								 WHEN 6 =>  reg_data  <= "1101000"&"0"&"00100011"&"00000000";--(0x23)
    								 WHEN 7 =>  reg_data  <= "1101000"&"0"&"00111000"&"00000001";--(0x38)
    								 WHEN 8 =>  reg_data  <= "1101000"&"0"&"01101000"&"00000000";--(0x68)
    								 WHEN 9 =>  reg_data  <= "1101000"&"0"&"01101010"&"00000000";--(0x6A)										 
    								-- WHEN 10 =>  reg_data  <= "1101000"&"1"&"01110101"&"00000000";--(0x75)	who am I
    								
    								 WHEN 10 =>  state  <= reader;  count := 0;									 
    								 WHEN OTHERS => NULL;
    					END CASE;	  				
    		  WHEN reader => 
    			i2c_busy_prev <= i2c_busy; 
    						IF(i2c_busy_prev  = '0' AND i2c_busy = '1') THEN  count := count + 1;  END IF;	
    					CASE count IS                           
    								 WHEN 0 =>  reg_data  <= "1101000"&"1"&"01110101"&"00000000";--(0x75)
    								 WHEN 1 =>  reg_data  <= "1101000"&"1"&"00111011"&"00000000";--(0x3B)
    								 WHEN 2 =>  reg_data  <= "1101000"&"1"&"00111100"&"00000000";--(0x3c)
    								 WHEN 3 =>  reg_data  <= "1101000"&"1"&"00111101"&"00000000";--(0x3d)
    								 WHEN 4 =>  reg_data  <= "1101000"&"1"&"00111110"&"00000000";--(0x3e)
    								 WHEN 5 =>  reg_data  <= "1101000"&"1"&"00111111"&"00000000";--(0x3f)
    								 WHEN 6 =>  reg_data  <= "1101000"&"1"&"01000000"&"00000000";--(0x40)
    								 WHEN 7 =>  reg_data  <= "1101000"&"1"&"01000001"&"00000000";--(0x41)
    								 WHEN 8 =>  reg_data  <= "1101000"&"1"&"01000010"&"00000000";--(0x42)
    								 WHEN 9 =>  state  <= reader;  count := 0;								 
    								 WHEN OTHERS => NULL;
    					END CASE;  
    		  WHEN OTHERS => NULL; 		  
    		 END CASE;			 
    	END IF;
     END PROCESS;
    end behv_cd;
    I2C master

    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.std_logic_unsigned.all;
    
    ENTITY i2c_master IS
      GENERIC(
        input_clk : INTEGER := 50_000_000; --input clock speed from user logic in Hz
        bus_clk   : INTEGER := 400_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
        ena       : IN     STD_LOGIC;                    --latch in command
        addr      : IN     STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
        rw        : IN     STD_LOGIC;                    --'0' is write, '1' is read
        data_wr   : IN     STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
        busy      : OUT    STD_LOGIC;                    --indicates transaction in progress
        data_rd   : OUT    STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
        ack_error : BUFFER STD_LOGIC;                    --flag if improper acknowledge from slave
        sda       : INOUT  STD_LOGIC;                    --serial data output of i2c bus
        scl       : INOUT  STD_LOGIC);                   --serial clock output of i2c bus
    END i2c_master;
    
    ARCHITECTURE logic OF i2c_master IS
      CONSTANT divider  :  INTEGER := (input_clk/bus_clk)/4; --number of clocks in 1/4 cycle of scl
      TYPE machine IS(ready, start, command, slv_ack1, wr, rd, slv_ack2, mstr_ack, stop); --needed states
      SIGNAL state         : machine;                        --state machine
      SIGNAL data_clk      : STD_LOGIC;                      --data clock for sda
      SIGNAL data_clk_prev : STD_LOGIC;                      --data clock during previous system clock
      SIGNAL scl_clk       : STD_LOGIC;                      --constantly running internal scl
      SIGNAL scl_ena       : STD_LOGIC := '0';               --enables internal scl to output
      SIGNAL sda_int       : STD_LOGIC := '1';               --internal sda
      SIGNAL sda_ena_n     : STD_LOGIC;                      --enables internal sda to output
      SIGNAL addr_rw       : STD_LOGIC_VECTOR(7 DOWNTO 0);   --latched in address and read/write
      SIGNAL data_tx       : STD_LOGIC_VECTOR(7 DOWNTO 0);   --latched in data to write to slave
      SIGNAL data_rx       : STD_LOGIC_VECTOR(7 DOWNTO 0);   --data received from slave
      SIGNAL bit_cnt       : INTEGER RANGE 0 TO 7 := 7;      --tracks bit number in transaction
      SIGNAL stretch       : STD_LOGIC := '0';               --identifies if slave is stretching scl
    BEGIN
    
      --generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
      PROCESS(clk, reset_n)
        VARIABLE count  :  INTEGER RANGE 0 TO divider*4;  --timing for clock generation
      BEGIN
        IF(reset_n = '0') THEN                --reset asserted
          stretch <= '0';
          count := 0;
        ELSIF(clk'EVENT AND clk = '1') THEN
          data_clk_prev <= data_clk;          --store previous value of data clock
          IF(count = divider*4-1) THEN        --end of timing cycle
            count := 0;                       --reset timer
          ELSIF(stretch = '0') THEN           --clock stretching from slave not detected
            count := count + 1;               --continue clock generation timing
          END IF;
          CASE count IS
            WHEN 0 TO divider-1 =>            --first 1/4 cycle of clocking
              scl_clk <= '0';
              data_clk <= '0';
            WHEN divider TO divider*2-1 =>    --second 1/4 cycle of clocking
              scl_clk <= '0';
              data_clk <= '1';
            WHEN divider*2 TO divider*3-1 =>  --third 1/4 cycle of clocking
              scl_clk <= '1';                 --release scl
              IF(scl = '0') THEN              --detect if slave is stretching clock
                stretch <= '1';
              ELSE
                stretch <= '0';
              END IF;
              data_clk <= '1';
            WHEN OTHERS =>                    --last 1/4 cycle of clocking
              scl_clk <= '1';
              data_clk <= '0';
          END CASE;
        END IF;
      END PROCESS;
    
      --state machine and writing to sda during scl low (data_clk rising edge)
      PROCESS(clk, reset_n)
      BEGIN
        IF(reset_n = '0') THEN                 --reset asserted
          state <= ready;                      --return to initial state
          busy <= '1';                         --indicate not available
          scl_ena <= '0';                      --sets scl high impedance
          sda_int <= '1';                      --sets sda high impedance
          ack_error <= '0';                    --clear acknowledge error flag
          bit_cnt <= 7;                        --restarts data bit counter
          data_rd <= "00000000";               --clear data read port
        ELSIF(clk'EVENT AND clk = '1') THEN
          IF(data_clk = '1' AND data_clk_prev = '0') THEN  --data clock rising edge
            CASE state IS
              WHEN ready =>                      --idle state
                IF(ena = '1') THEN               --transaction requested
                  busy <= '1';                   --flag busy
                  addr_rw <= addr & rw;          --collect requested slave address and command
                  data_tx <= data_wr;            --collect requested data to write
                  state <= start;                --go to start bit
                ELSE                             --remain idle
                  busy <= '0';                   --unflag busy
                  state <= ready;                --remain idle
                END IF;
              WHEN start =>                      --start bit of transaction
                busy <= '1';                     --resume busy if continuous mode
                sda_int <= addr_rw(bit_cnt);     --set first address bit to bus
                state <= command;                --go to command
              WHEN command =>                    --address and command byte of transaction
                IF(bit_cnt = 0) THEN             --command transmit finished
                  sda_int <= '1';                --release sda for slave acknowledge
                  bit_cnt <= 7;                  --reset bit counter for "byte" states
                  state <= slv_ack1;             --go to slave acknowledge (command)
                ELSE                             --next clock cycle of command state
                  bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
                  sda_int <= addr_rw(bit_cnt-1); --write address/command bit to bus
                  state <= command;              --continue with command
                END IF;
              WHEN slv_ack1 =>                   --slave acknowledge bit (command)
                IF(addr_rw(0) = '0') THEN        --write command
                  sda_int <= data_tx(bit_cnt);   --write first bit of data
                  state <= wr;                   --go to write byte
                ELSE                             --read command
                  sda_int <= '1';                --release sda from incoming data
                  state <= rd;                   --go to read byte
                END IF;
              WHEN wr =>                         --write byte of transaction
                busy <= '1';                     --resume busy if continuous mode
                IF(bit_cnt = 0) THEN             --write byte transmit finished
                  sda_int <= '1';                --release sda for slave acknowledge
                  bit_cnt <= 7;                  --reset bit counter for "byte" states
                  state <= slv_ack2;             --go to slave acknowledge (write)
                ELSE                             --next clock cycle of write state
                  bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
                  sda_int <= data_tx(bit_cnt-1); --write next bit to bus
                  state <= wr;                   --continue writing
                END IF;
              WHEN rd =>                         --read byte of transaction
                busy <= '1';                     --resume busy if continuous mode
                IF(bit_cnt = 0) THEN             --read byte receive finished
                  IF(ena = '1' AND addr_rw = addr & rw) THEN  --continuing with another read at same address
                    sda_int <= '0';              --acknowledge the byte has been received
                  ELSE                           --stopping or continuing with a write
                    sda_int <= '1';              --send a no-acknowledge (before stop or repeated start)
                  END IF;
    --				  
    --				  if(enable = '1') then
    				  -----------
                  bit_cnt <= 7;                  --reset bit counter for "byte" states
                  data_rd <= data_rx;            --output received data
                  state <= mstr_ack;             --go to master acknowledge
    				  ----------------
    --				  else
    --				  data_rd <= "00000000";
    --				  end if;
    				  
    				  
                ELSE                             --next clock cycle of read state
    				
                  bit_cnt <= bit_cnt - 1;        --keep track of transaction bits
                  state <= rd;                   --continue reading
                END IF;
              WHEN slv_ack2 =>                   --slave acknowledge bit (write)
                IF(ena = '1') THEN               --continue transaction
                  busy <= '0';                   --continue is accepted
                  addr_rw <= addr & rw;          --collect requested slave address and command
                  data_tx <= data_wr;            --collect requested data to write
                  IF(addr_rw = addr & rw) THEN   --continue transaction with another write
                    sda_int <= data_wr(bit_cnt); --write first bit of data
                    state <= wr;                 --go to write byte
                  ELSE                           --continue transaction with a read or new slave
                    state <= start;              --go to repeated start
                  END IF;
                ELSE                             --complete transaction
                  state <= stop;                 --go to stop bit
                END IF;
              WHEN mstr_ack =>                   --master acknowledge bit after a read
                IF(ena = '1') THEN               --continue transaction
                  busy <= '0';                   --continue is accepted and data received is available on bus
                  addr_rw <= addr & rw;          --collect requested slave address and command
                  data_tx <= data_wr;            --collect requested data to write
                  IF(addr_rw = addr & rw) THEN   --continue transaction with another read
                    sda_int <= '1';              --release sda from incoming data
                    state <= rd;                 --go to read byte
                  ELSE                           --continue transaction with a write or new slave
                    state <= start;              --repeated start
                  END IF;    
                ELSE                             --complete transaction
                  state <= stop;                 --go to stop bit
                END IF;
              WHEN stop =>                       --stop bit of transaction
                busy <= '0';                     --unflag busy
                state <= ready;                  --go to idle state
            END CASE;    
          ELSIF(data_clk = '0' AND data_clk_prev = '1') THEN  --data clock falling edge
            CASE state IS
              WHEN start =>                  
                IF(scl_ena = '0') THEN                  --starting new transaction
                  scl_ena <= '1';                       --enable scl output
                  ack_error <= '0';                     --reset acknowledge error output
                END IF;
              WHEN slv_ack1 =>                          --receiving slave acknowledge (command)
                IF(sda /= '0' OR ack_error = '1') THEN  --no-acknowledge or previous no-acknowledge
                  ack_error <= '1';                     --set error output if no-acknowledge
                END IF;
              WHEN rd =>                                --receiving slave data
                data_rx(bit_cnt) <= sda;                --receive current slave data bit
              WHEN slv_ack2 =>                          --receiving slave acknowledge (write)
                IF(sda /= '0' OR ack_error = '1') THEN  --no-acknowledge or previous no-acknowledge
                  ack_error <= '1';                     --set error output if no-acknowledge
                END IF;
              WHEN stop =>
                scl_ena <= '0';                         --disable scl
              WHEN OTHERS =>
                NULL;
            END CASE;
          END IF;
        END IF;
      END PROCESS;  
    
      --set sda output
      WITH state SELECT
        sda_ena_n <= data_clk_prev WHEN start,     --generate start condition
                     NOT data_clk_prev WHEN stop,  --generate stop condition
                     sda_int WHEN OTHERS;          --set to internal sda signal    
          
      --set scl and sda outputs
      scl <= '0' WHEN (scl_ena = '1' AND scl_clk = '0') ELSE 'Z';
      sda <= '0' WHEN sda_ena_n = '0' ELSE 'Z';
      
    END logic;
    Top module

    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    Library UNISIM;
    use UNISIM.vcomponents.all;
    
    ENTITY I2C_top IS
    GENERIC(
      sys_clk_frq : INTEGER   := 50_000_000; --system clock speed in Hz
      i2c_scl_frq : INTEGER   := 400_000    --speed the i2c bus (scl) will run at in Hz
      );       --spi clock phase mode
       PORT(   
            clk100      : IN    STD_LOGIC;  --system clock
    		  reset       : IN    STD_LOGIC;  --active low reset
    		  scl         : INOUT STD_LOGIC;  --i2c serial clock
    		  sda         : INOUT STD_LOGIC;
    		  i2c_ack_err : OUT   STD_LOGIC;
    		  led         : OUT   STD_LOGIC;		  
    		 data_lcd    : out  STD_LOGIC_VECTOR(7 DOWNTO 0)
    		  --node_scl : inout std_logic; --set pullups for these in ucf
    		--	node_sda : inout std_logic--set pullups for these in ucf
    		  
    		  ); --i2c serial data
    END I2C_top;
    
    ARCHITECTURE logic OF I2C_top IS
    ---components starts from here
    --I2C slave component
    --component I2C_slave is
    --  generic (
    --    SLAVE_ADDR          : std_logic_vector(6 downto 0)   := "0000011"); -- I added := "0000000" to get it to compile
    --  port (
    --    scl                 : inout std_logic;
    --    sda                 : inout std_logic;
    --    clk                 : in    std_logic;
    --    rst                 : in    std_logic;
    --    -- User interface
    --    read_req            : out   std_logic;
    --    data_to_master      : in    std_logic_vector(7 downto 0);
    --    data_valid          : out   std_logic;
    --    data_from_master    : out   std_logic_vector(7 downto 0));
    --end component;
    
    component mpu6050_regs is
    port (
    		clk      : IN  STD_LOGIC; 
      		reset    : IN  STD_LOGIC;
    		i2c_busy : IN  STD_LOGIC;  
      		reg_data : OUT STD_LOGIC_VECTOR(23 downto 0)
    		);
    end component;
    
    component i2c_master IS
      GENERIC(
        input_clk : INTEGER := 50_000_000; --input clock speed from user logic in Hz
        bus_clk   : INTEGER := 400_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
        ena       : IN     STD_LOGIC;                    --latch in command
        addr      : IN     STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
        rw        : IN     STD_LOGIC;                    --'0' is write, '1' is read
        data_wr   : IN     STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
        busy      : OUT    STD_LOGIC;                    --indicates transaction in progress
        data_rd   : OUT    STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
        ack_error : BUFFER STD_LOGIC;                    --flag if improper acknowledge from slave
        sda       : INOUT  STD_LOGIC;                    --serial data output of i2c bus
        scl       : INOUT  STD_LOGIC);                   --serial clock output of i2c bus
    END component;
    
    component u_logic IS
    PORT(
      clk         : IN   STD_LOGIC;                     --system clock
      reset_n     : IN   STD_LOGIC;                     --active low reset
      i2c_busy    : IN   STD_LOGIC;                     --i2c busy signal (talking to i2c slave)
      i2c_data_rd : IN   STD_LOGIC_VECTOR(7 DOWNTO 0);  --data received from i2c slave
                       --i2c acknowledge error flag
      i2c_ena     : OUT  STD_LOGIC;                     --latch command into i2c master
      i2c_addr    : OUT  STD_LOGIC_VECTOR(6 DOWNTO 0);  --i2c slave address
      i2c_rw      : OUT  STD_LOGIC;                     --i2c read/write command
      i2c_data_wr : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0);
      
      data_in     : IN   STD_LOGIC_VECTOR(23 DOWNTO 0);
      data_lcd    : OUT  STD_LOGIC_VECTOR(7 DOWNTO 0)
      ); --data to write over the i2c bus
    END component;
    
    
      CONSTANT spi_d_width : INTEGER := 25;  --spi data width in bits
      SIGNAL   i2c_ena     : STD_LOGIC;
      SIGNAL   i2c_addr    : STD_LOGIC_VECTOR(6 DOWNTO 0);
      SIGNAL   i2c_rw      : STD_LOGIC;
      SIGNAL   i2c_data_wr : STD_LOGIC_VECTOR(7 DOWNTO 0);
      SIGNAL   i2c_data_rd : STD_LOGIC_VECTOR(7 DOWNTO 0);
      SIGNAL   i2c_busy    : STD_LOGIC;
      SIGNAL   clock       : STD_LOGIC;
      SIGNAL   reset_n     : STD_LOGIC;
      SIGNAL   reg_data    : STD_LOGIC_VECTOR(23 DOWNTO 0);
      
    	signal read_req         : std_logic                      := '0';
    	signal data_to_master   : std_logic_vector (7 downto 0)  := "01010101";
    	signal data_valid       : std_logic                      := '0';
    	signal data_from_master : std_logic_vector (7 downto 0)  := (others => '0');
    	signal data_reg: std_logic_vector (7 downto 0);
    	signal ackerr: std_logic;
      
    BEGIN
    reset_n <= not reset;
    led     <= i2c_busy;
    i2c_ack_err <= ackerr;
    --	 --- I2C slave
    --	 i2cSlave: I2C_slave generic map (
    --									SLAVE_ADDR => "0000011")
    --								port map(
    --									scl               => node_scl,
    --									sda               => node_sda,
    --									clk               => clk100,
    --									rst               => reset,
    --									-- User interface
    --									read_req          => read_req,
    --									data_to_master    => data_to_master,
    --									data_valid        => data_valid,
    --									data_from_master  => data_from_master);
    
      
      logic:  u_logic PORT MAP(
    					 clk         => clk100, 
    					 reset_n     => reset_n, 
    					 i2c_busy    => i2c_busy,
    					 i2c_data_rd => i2c_data_rd, 
    					
    					 i2c_ena     => i2c_ena, 
    					 i2c_addr    => i2c_addr, 
    					 i2c_rw      => i2c_rw,
    					 i2c_data_wr => i2c_data_wr,
    					 data_in     => reg_data,
    					 data_lcd    => open
    				 );  
    				 
      --instantiate registers for MPU6050
      regs:  mpu6050_regs PORT MAP(
    					 clk         => clk100, 
    					 reset       => reset, 
    					 i2c_busy    => i2c_busy,
    					 reg_data    => reg_data
    				 );  
      
      --instantiate the i2c master
      i_master: i2c_master
        GENERIC MAP(	input_clk => sys_clk_frq, 
    						bus_clk => i2c_scl_frq	)
        PORT MAP(
    						 clk       => clk100, 
    						 reset_n   => reset_n, 
    						 ena       => i2c_ena,					 
    						 addr      => i2c_addr,
    						 rw        => i2c_rw, 
    						 data_wr   => i2c_data_wr, 
    						 busy      => i2c_busy,
    						 data_rd   => data_lcd, 
    					--	 data_rd   => data_to_master, 
    					--	 ack_error => i2c_ack_err, 
    						 ack_error => ackerr, 
    						 sda       => sda,
    						 scl       => scl
    				 );  
    
    END logic;



    •   AltAdvertisment

        
       

  6. #6
    Full Member level 4
    Points: 1,953, Level: 10

    Join Date
    May 2014
    Posts
    235
    Helped
    22 / 22
    Points
    1,953
    Level
    10

    Re: Reading data from MPU6050 reads only the who am I register

    With regards to your addressing.

    Why do you only list the middle section?

    WHEN 0 => reg_data <= "1101000"&"1"&"01110101"&"00000000";--(0x75)

    24x"D1_75_00"

    I would recommend chip scoping (integrated logic analyser) the signals of interest.
    You're getting back data, Is the address what you expect it to be?

    but sometimes it starts reading the registers, then it contiuously read.
    Looking at state machine you never leave reader state! Unless reset.



  7. #7
    Newbie level 3
    Points: 53, Level: 1

    Join Date
    Sep 2018
    Posts
    4
    Helped
    0 / 0
    Points
    53
    Level
    1

    Re: Reading data from MPU6050 reads only the who am I register

    Quote Originally Posted by wesleytaylor View Post
    With regards to your addressing.

    Why do you only list the middle section?

    WHEN 0 => reg_data <= "1101000"&"1"&"01110101"&"00000000";--(0x75)

    24x"D1_75_00"

    I would recommend chip scoping (integrated logic analyser) the signals of interest.
    You're getting back data, Is the address what you expect it to be?


    Looking at state machine you never leave reader state! Unless reset.
    I have commented the register that I am reading or writing to. So it goes as Device address & read/write & register address & data

    I want to stay in the reader state as I am reading data continuously after the configuration.



  8. #8
    Super Moderator
    Points: 247,995, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,137
    Helped
    13124 / 13124
    Points
    247,995
    Level
    100

    Re: Reading data from MPU6050 reads only the who am I register

    I want to stay in the reader state as I am reading data continuously after the configuration.
    Review the burst read transaction description. You'll write a start register address, then read a number of consecutive registers while the address is auto-incremented. Stop the burst read transaction and repeat.



--[[ ]]--