Friday, October 30, 2020

ads8661s---v1.3 working top file

 --------------------------------------------------------------------------------

--

--   FileName:         pmod_accelerometer_adxl345.vhd

--   Dependencies:     spi_master.vhd

--   Design Software:  Quartus Prime Version 17.0.0 Build 595 SJ Lite Edition

--

--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY

--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT

--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A

--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY

--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL

--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF

--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS

--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),

--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.

--

--   Version History

--   Version 1.0 09/19/2019 Scott Larson

--     Initial Public Release

--    

--------------------------------------------------------------------------------


LIBRARY ieee;

USE ieee.std_logic_1164.all;


ENTITY pmod_accelerometer_adxl345 IS

  GENERIC(

  --------------------

  

    clk_freq    : INTEGER := 100;  --system clock frequency in MHz

    spi_clk_div : INTEGER := 1; --spi_clk_div = clk_freq/100 (answer rounded up)

    --------------------added --------------------------------------------

    ----rst_pwrctl_reg 

    rst_pwrctl_reg_ms_addr  : std_logic_Vector( 7 downto 0)  :=x"05" ;

     rst_pwrctl_reg_ms_data  : std_logic_Vector( 7 downto 0)  :=x"69" ;  ---first data need to send 

    rst_pwrctl_reg_ls_addr  : std_logic_Vector( 7 downto 0)  :=x"04" ;

    rst_pwrctl_reg_ls_data  : std_logic_Vector( 7 downto 0)  :=x"00" ;  ----- enable vdd alarm , input alarm  , por reset,disable nap mode , put converter in active mode 

   ------------sdi control register 

    sdi_ctl_reg_addr : std_logic_vector ( 7 downto 0) :=x"08" ;

     sdi_mode :std_logic_vector (1 downto 0) :="00" ;     ------spi mode cpol=0 cphase=0

    

    

----- sdo-ctl-reg---=====0ch =========================

 sdo_ctl_reg_addr : std_logic_vector ( 7 downto 0) :=x"0C" ;

  ssync_clk :std_logic :='0' ;     --- 0 external clock  1- internal clock

  sdo_mode :std_logic_vector(1 downto 0) :="0X" ;      ---- follow same spi protocols that used for sdi mode  

    

      --------dataout control register ---- 11h

 dataout_ctl_reg_ms_addr : std_logic_vector( 7 downto 0) :=x"11" ;     --------------1st addr  

  device_addr_inc :std_logic :='0' ;     --- '0' do not include the register value '1' include the register value 

  vdd_active_alarm_inc :std_logic_vector (1 downto 0) :="11" ;     ---"11" include both vdd_h_flag and vdd_l_flag 

  in_active_alarm_inc :std_logic_vector (1 downto 0) :="11" ;       ---"11" include both vdd_h_flag and vdd_l_flag 

  range_inc :std_logic :='1' ;      ----- include range configuration value 


 dataout_ctl_reg_ls_addr : std_logic_vector ( 7 downto 0) :=x"10" ;     ---------second addr  ----------

  par_en :std_logic :='0' ;     --- 0 disable 1 enable

  data_val :std_logic_vector (2 downto 0) :="0XX" ;     ---------conversion data  

   

    -----------range selection register  --- 14h


 range_sel_addr : std_logic_vector ( 7 downto 0) :=x"14" ;     --------

  intref_dis:std_logic :='0' ;     --- 0 disable 1 enable

  range_sel:std_logic_vector(3 downto 0) :="0000" ;   ---------range _+ 3*vref

     

      write_MS  : std_logic_vector ( 7 downto 0) :=  "11010010" ;      ---ms of the 16 bit only written on the specified register address 

      write_LS  : std_logic_vector ( 7 downto 0) :=  "11010100";      ---ls of the 16 bit only written on the specified register address 

      write_hword : std_logic_vector ( 7 downto 0) :="11010000"  ;  ---write half word on the specified memory location 

    

    

  

  

  -----------------

--    clk_freq   : INTEGER := 50;              --system clock frequency in MHz

    data_rate  : STD_LOGIC_VECTOR := "0100"; --data rate code to configure the accelerometer

    data_range : STD_LOGIC_VECTOR := "00");  --data range code to configure the accelerometer

  PORT(

    clk            : IN      STD_LOGIC;                      --system clock

    reset_n        : IN      STD_LOGIC;                      --active low asynchronous reset

    miso           : IN      STD_LOGIC;                      --SPI bus: master in, slave out

    sclk           : BUFFER  STD_LOGIC;                      --SPI bus: serial clock

    rvs : out std_logic ; 

    adc_gpio : out std_logic ; 

    ss_n           : BUFFER  STD_LOGIC_VECTOR(0 DOWNTO 0);   --SPI bus: slave select

    mosi           : OUT     STD_LOGIC;                      --SPI bus: master out, slave in

    acceleration_x : OUT     STD_LOGIC_VECTOR(15 DOWNTO 0)  --x-axis acceleration data

--    acceleration_y : OUT     STD_LOGIC_VECTOR(15 DOWNTO 0);  --y-axis acceleration data

--    acceleration_z : OUT     STD_LOGIC_VECTOR(15 DOWNTO 0)--z-axis acceleration data

    ); 

    

END pmod_accelerometer_adxl345;


ARCHITECTURE behavior OF pmod_accelerometer_adxl345 IS

  TYPE machine IS(start, pause, configure, read_data, output_result); --needed states

  SIGNAL state              : machine := start;                       --state machine

  SIGNAL parameter          : INTEGER RANGE 0 TO 17;                   --parameter being configured

  

  

  SIGNAL acceleration_y :      STD_LOGIC_VECTOR(15 DOWNTO 0);  --y-axis acceleration data

   SIGNAL  acceleration_z :     STD_LOGIC_VECTOR(15 DOWNTO 0); --z-axis acceleration data

  

--  SIGNAL parameter_addr     : STD_LOGIC_VECTOR(5 DOWNTO 0);           --register address of configuration parameter

--  SIGNAL parameter_data     : STD_LOGIC_VECTOR(3 DOWNTO 0);           --value of configuration parameter

  

   SIGNAL parameter_addr     : STD_LOGIC_VECTOR(7 DOWNTO 0);           --register address of configuration parameter

  SIGNAL parameter_data     : STD_LOGIC_VECTOR(7 DOWNTO 0);           --value of configuration parameter

  

  SIGNAL spi_busy_prev      : STD_LOGIC;                              --previous value of the SPI component's busy signal

  SIGNAL spi_busy           : STD_LOGIC;                              --busy signal from SPI component

  SIGNAL spi_ena            : STD_LOGIC;                              --enable for SPI component

  SIGNAL spi_cont           : STD_LOGIC;                              --continuous mode signal for SPI component

  SIGNAL spi_tx_data        : STD_LOGIC_VECTOR(7 DOWNTO 0);           --transmit data for SPI component

  SIGNAL spi_rx_data        : STD_LOGIC_VECTOR(7 DOWNTO 0);           --received data from SPI component

  SIGNAL acceleration_x_int : STD_LOGIC_VECTOR(15 DOWNTO 0);          --internal x-axis acceleration data buffer

  SIGNAL acceleration_y_int : STD_LOGIC_VECTOR(15 DOWNTO 0);          --internal y-axis acceleration data buffer

  SIGNAL acceleration_z_int : STD_LOGIC_VECTOR(15 DOWNTO 0);          --internal z-axis acceleration data buffer


  --declare SPI Master component

  COMPONENT spi_master IS

     GENERIC(

        slaves  : INTEGER := 1;  --number of spi slaves

        d_width : INTEGER := 8); --data bus width

     PORT(

        clock   : IN     STD_LOGIC;                             --system clock

        reset_n : IN     STD_LOGIC;                             --asynchronous reset

        enable  : IN     STD_LOGIC;                             --initiate transaction

        cpol    : IN     STD_LOGIC;                             --spi clock polarity

        cpha    : IN     STD_LOGIC;                             --spi clock phase

        cont    : IN     STD_LOGIC;                             --continuous mode command

        clk_div : IN     INTEGER;                               --system clock cycles per 1/2 period of sclk

        addr    : IN     INTEGER;                               --address of slave

        tx_data : IN     STD_LOGIC_VECTOR(d_width-1 DOWNTO 0);  --data to transmit

        miso    : IN     STD_LOGIC;                             --master in, slave out

        sclk    : BUFFER STD_LOGIC;                             --spi clock

        ss_n    : BUFFER STD_LOGIC_VECTOR(slaves-1 DOWNTO 0);   --slave select

        mosi    : OUT    STD_LOGIC;                             --master out, slave in

        busy    : OUT    STD_LOGIC;                             --busy / data ready signal

        rx_data : OUT    STD_LOGIC_VECTOR(d_width-1 DOWNTO 0)); --data received

  END COMPONENT spi_master;


BEGIN


  --instantiate the SPI Master component

  spi_master_0:  spi_master

    GENERIC MAP(slaves => 1, d_width => 8)

    PORT MAP(clock => clk, reset_n => reset_n, enable => spi_ena, cpol => '0', cpha => '0',

          cont => spi_cont, clk_div => clk_freq/10, addr => 0, tx_data => spi_tx_data, miso => miso,

          sclk => sclk, ss_n => ss_n, mosi => mosi, busy => spi_busy, rx_data => spi_rx_data);


  PROCESS(clk ,   reset_n  )

    VARIABLE count : INTEGER := 0; --universal counter

  BEGIN

    IF(reset_n = '0') THEN              --reset activated

      spi_ena <= '0';                     --clear SPI component enable

      spi_cont <= '0';                    --clear SPI component continuous mode signal

      spi_tx_data <= (OTHERS => '0');     --clear SPI component transmit data

      acceleration_x <= (OTHERS => '0');  --clear x-axis acceleration data

      acceleration_y <= (OTHERS => '0');  --clear y-axis acceleration data

      acceleration_z <= (OTHERS => '0');  --clear z-axis acceleration data

      state <= start;                     --restart state machine

    ELSIF(clk'EVENT AND clk = '1') THEN --rising edge of system clock

      CASE state IS                       --state machine


        --entry state

        WHEN start =>

          count := 0;      --clear universal counter

          parameter <= 0;  --clear parameter indicator

          state <= pause;

          

        --pauses 200ns between SPI transactions and selects SPI transaction

        WHEN pause =>

          IF(spi_busy = '0') THEN                --SPI component not busy

            IF(count < clk_freq/5) THEN            --less than 200ns

              count := count + 1;                    --increment counter

              report "count less than 200 ns " ; 

              state <= pause;                        --remain in pause state

            ELSE                                   --200ns has elapsed

              count := 0;                            --clear counter

              CASE parameter IS                      --select SPI transaction

          

          --- nop 

                WHEN 0 =>                              --SPI transaction to set range

                  parameter <= parameter + 1;            --increment parameter for next transaction

                      parameter_addr <= x"00";            --register address with range setting

                  parameter_data <= x"00"  ;   --data to set specified range

                  state <= configure;                    --proceed to SPI transaction

                  

                WHEN 1 =>                             --SPI transaction to set data rate

                  parameter <= parameter + 1;            --increment parameter for next transaction

                  parameter_addr <= x"00";            --register address with range setting

                  parameter_data <= x"00"  ;   --data to set specified range

                  state <= configure;                    --proceed to SPI transaction

         ------------xxx--------------------------------

         

         ------rst1 

                WHEN 2 =>                             --SPI transaction to enable measuring

                  parameter <= parameter + 1;            --increment parameter for next transaction

                  parameter_addr <= write_hword ;         --register address with range setting

                  parameter_data <= rst_pwrctl_reg_ms_addr   ;  

                  state <= configure;                    --proceed to SPI transaction

                  

                 WHEN 3 =>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= rst_pwrctl_reg_ms_data; 

                  parameter_data <= x"00" ;   

                  state <= configure;                

            ---------xxxx---------------

            ---rst2

                  

                WHEN 4=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword;

                  parameter_data <=  rst_pwrctl_reg_ls_addr ;  

                  state <= configure;                

          

              

                    WHEN 5 =>                         

                  parameter <= parameter + 1;       

                  parameter_addr <=rst_pwrctl_reg_ls_data ;

                  parameter_data <=  x"00" ;    

                  state <= configure;                

       --------------xx----------------       

             

             ----sdi  

                   WHEN 6=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword ;   

                  parameter_data <=  sdi_ctl_reg_addr ; 

                  state <= configure;                 

              

                 

              

                   WHEN 7=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <=  "000000"  & sdi_mode;

                  parameter_data <= x"00" ;  

                  state <= configure;                 

              

              --------  xxx-----------------  

          

              

            ----sd0  

                   WHEN 8=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword ;   

                  parameter_data <=   sdo_ctl_reg_addr ;   

                  state <= configure;                 

              

                 

              

                   WHEN 9=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= "0"  &  ssync_clk & "0000" &  sdo_mode;

                  parameter_data <= x"00" ;  

                  state <= configure;                 

              

             ---------------xxxxxxxxxxxx---------------------------- 

             

             

             

                 ----data_out config1  

                   WHEN 10=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword ;   

                  parameter_data <=   dataout_ctl_reg_ms_addr  ; 

                  state <= configure;                 

              

                 

              

                   WHEN 11=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <=   '0'  &   device_addr_inc  &  vdd_active_alarm_inc  &  in_active_alarm_inc  &  '0'  &    range_inc;

                  parameter_data <= x"00" ;  

                  state <= configure;                 

              

             ---------------xxxxxxxxxxxx---------------------------- 

             

             

             

             

                ----data_out config2

                   WHEN 12=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword ;   

                  parameter_data <=   dataout_ctl_reg_ls_addr ; 

                  state <= configure;                 

              

                 

              

                   WHEN 13 =>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= "0000"   &     par_en   &  data_val ;

                  parameter_data <= x"00" ;  

                  state <= configure;                 

              

             ---------------xxxxxxxxxxxx----------------------------       

              

                    

                ----range 

                   WHEN 14=>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= write_hword ;   

                  parameter_data <=   range_sel_addr   ;

                  state <= configure;                 

              

                 

              

                   WHEN 15 =>                         

                  parameter <= parameter + 1;       

                  parameter_addr <= '0'   &   intref_dis   &  "00"   &   range_sel ;

                  parameter_data <= x"00" ;  

                  state <= configure;                 

              

             ---------------xxxxxxxxxxxx----------------------------     

              

              

              

              

              

              

                  

                WHEN 16 =>                             --SPI transaction to read data

                  state <= read_data;                    --proceed to SPI transaction

                WHEN OTHERS => NULL;

              END CASE;        

            END IF;

          END IF;


        --performs SPI transactions that write to configuration registers  

        WHEN configure =>

          spi_busy_prev <= spi_busy;                      --capture the value of the previous spi busy signal

          IF(spi_busy_prev = '1' AND spi_busy = '0') THEN --spi busy just went low

            count := count + 1;                             --counts times busy goes from high to low during transaction

          END IF;

          CASE count IS                                   --number of times busy has gone from high to low

            WHEN 0 =>                                       --no busy deassertions

              IF(spi_busy = '0') THEN                         --transaction not started

                spi_cont <= '1';                                --set to continuous mode

                spi_ena <= '1';                                 --enable SPI transaction

                    report "configure spi_busy  0 count 0 " ; 

                spi_tx_data <=  parameter_addr;           --first information to send

              ELSE                                            --transaction has started

                    report "configure spi_busy  1" ; 

                spi_tx_data <=  parameter_data;         --second information to send (first has been latched in)

              END IF;

            WHEN 1 =>                                       --first busy deassertion

              spi_cont <= '0';                                --clear continous mode to end transaction

              spi_ena <= '0';                                 --clear SPI transaction enable

              count := 0;                                     --clear universal counter

                  report "configure count1" ; 

              state <= pause;                                 --return to pause state

            WHEN OTHERS => NULL;

          END CASE;


        --performs SPI transactions that read acceleration data registers  

        WHEN read_data =>

          spi_busy_prev <= spi_busy;                        --capture the value of the previous spi busy signal

          IF(spi_busy_prev = '1' AND spi_busy = '0') THEN   --spi busy just went low

            count := count + 1;                               --counts the times busy goes from high to low during transaction

          END IF;          

          CASE count IS                                     --number of times busy has gone from high to low

            WHEN 0 =>                                         --no busy deassertions

              IF(spi_busy = '0') THEN                           --transaction not started

                spi_cont <= '1';                                  --set to continuous mode

                spi_ena <= '1';                                   --enable SPI transaction

--                spi_tx_data <= "11110010";                        --first information to send

                   spi_tx_data <= "11001000"; 

              ELSE                                              --transaction has started

--                spi_tx_data <= "00000000";                        --second information to send (first has been latched in)              

               spi_tx_data <=     sdo_ctl_reg_addr  ;

              END IF;

       

            WHEN 2 =>                                         --2nd busy deassertion

              acceleration_x_int(7 DOWNTO 0) <= spi_rx_data;    --latch in first received acceleration data

            WHEN 3 =>                                         --3rd busy deassertion

              acceleration_x_int(15 DOWNTO 8) <= spi_rx_data;   --latch in second received acceleration data

            WHEN 4 =>                                         --4th busy deassertion

              acceleration_y_int(7 DOWNTO 0) <= spi_rx_data;    --latch in third received acceleration data

            WHEN 5 =>                                         --5th busy deassertion

              acceleration_y_int(15 DOWNTO 8) <= spi_rx_data;   --latch in fourth received acceleration data

            WHEN 6 =>                                         --6th busy deassertion

              spi_cont <= '0';                                  --clear continuous mode to end transaction

              spi_ena <= '0';                                   --clear SPI transaction enable

              acceleration_z_int(7 DOWNTO 0) <= spi_rx_data;    --latch in fifth received acceleration data

            WHEN 7 =>                                         --7th busy deassertion

              acceleration_z_int(15 DOWNTO 8) <= spi_rx_data;   --latch in sixth received acceleration data

              count := 0;                                       --clear universal counter

              state <= output_result;                           --proceed to output result state

            WHEN OTHERS => NULL;

          END CASE;

  

        --outputs acceleration data

        WHEN output_result =>

            acceleration_x <= acceleration_x_int;  --output x-axis data

            acceleration_y <= acceleration_y_int;  --output y-axis data

            acceleration_z <= acceleration_z_int;  --output z-axis data

            state <= pause;                        --return to pause state

        

        --default to start state

        WHEN OTHERS => 

          state <= start;


      END CASE;      

    END IF;

  END PROCESS;

END behavior;


No comments:

Post a Comment

spyglass lint 1