⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.txt

📁 I2C core code in Hardware descrption language so as enable a cpld/fpga to be programmed for specific
💻 TXT
📖 第 1 页 / 共 2 页
字号:
              stm_mstr <= mstr_rd_wait_half;  
            end if;
          --------------------
          when mstr_rd_wait_half =>
            i_scl_mstr <= '1';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_rd_wait_half;
            else                           
              i_scl_cntr <= 0;
              i_mstr_rd_data <= i_mstr_rd_data( 6 downto 0 ) & sda;
              stm_mstr <= mstr_rd_read;               
            end if;  
          --------------------- 
          when mstr_rd_read =>
            i_scl_mstr <= '1';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_rd_read;
            else                           
              i_scl_cntr <= 0;               
              if ( i_bit_cntr_mstr > 0 ) then
                i_bit_cntr_mstr <= i_bit_cntr_mstr - 1;
                i_scl_mstr <= '0';              
                stm_mstr <= mstr_rd_wait_low;  
              else
                i_mstr_ad <= ( others => '0' );  
                mstr_dout <= i_mstr_rd_data;               
                stm_mstr <= mstr_rd_wait_ack;
              end if;
            end if;      
          ---------------------
          --#######################
          --### SEND ACKNOWELEDGE #
          --#######################
          when mstr_rd_wait_ack =>
            i_scl_mstr <= '0';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_rd_wait_ack;
            else                           
              i_scl_cntr <= 0;
              i_sda_mstr <= not send_ack;
              stm_mstr <= mstr_rd_get_ack;
            end if;
          ----------------------              
          when mstr_rd_get_ack =>
            i_scl_mstr <= '0';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_rd_get_ack;
            else
              i_scl_cntr <= 0;
              --i_ack_mstr <= sda;
              stm_mstr <= mstr_rd_wait_last_half;
            end if;
          ----------------------
          when mstr_rd_wait_last_half =>
            i_scl_mstr <= '1';
            if ( i_scl_cntr < FULL_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_rd_wait_last_half;
            else              
              i_scl_cntr <= 0;
              stm_mstr <= mstr_active;
            end if;
          ---------------------- 
          --######################
          --######## STOP ########
          --######################                                        
          when mstr_stop =>
            i_scl_mstr <= '1';
            i_sda_mstr <= '0';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_stop;
            else
              i_scl_cntr <= 0;
              i_sda_mstr <= '1';
              stm_mstr <= mstr_gap;
            end if;                                                  
          ---------------------  
          when mstr_gap =>
            if ( i_scl_cntr < GAP_WIDTH ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_gap;
            else
              i_scl_cntr <= 0;
              stm_mstr <= mstr_idle;
            end if;
          --#####################
          --###### RESTART ######        
          --#####################
          when mstr_restart =>
            i_scl_mstr <= '1';
            i_sda_mstr <= '0';
            if ( i_scl_cntr < HALF_BIT ) then
              i_scl_cntr <= i_scl_cntr + 1;
              stm_mstr <= mstr_restart;
            else
              i_scl_cntr <= 0;
              i_sda_mstr <= '1';
              stm_mstr <= mstr_start_cnt;
            end if;                                                  
          when others => stm_mstr <= mstr_idle;
          end case;
        end if;
      end if;
    end process i2c_master; 
 --##############################################    
 --##############################################
 --##############################################
 --##############################################
 --##############################################
 --##############################################     
     slv_dout <= i_slv_dout;
     i2c_slave:
     process( sys_clk , sys_rst )
       begin
         if ( sys_rst = '1' ) then
           stm_slv <= slv_idle;
           slv_busy <= '0';
           i_slv_bit_cnt <= 0;
           i_slv_addr <= ( others => '0' );
           i_sda_slv <= 'Z';
           i_slv_reg_addr <= ( others => '0' );
           i_slv_data <= ( others => '0' );
           slv_read <= '0';
           slv_write <= '0';
           i_slv_dout <=  ( others => '0' );
         elsif rising_edge( sys_clk ) then
           case stm_slv is
           ----------------------
           when slv_idle =>
             slv_busy <= '0';
             i_sda_slv <= 'Z';
             i_slv_bit_cnt <= 0;
             if ( i_mstr_slv = '0' ) and ( i_slv_strt_bit = '1' ) then
               stm_slv <= slv_get_addr;
               slv_busy <= '1';
             else
               stm_slv <= slv_idle;
             end if;
           ----------------------
           when slv_get_addr =>
             i_sda_slv <= 'Z';
             if ( i_slv_stop_bit = '0' ) then
               if ( i_slv_scl_rise = '1' ) then
                 if ( i_slv_bit_cnt < 8 ) then               
                   i_slv_addr <= i_slv_addr( 6 downto 0 ) & sda;
                   i_slv_bit_cnt <= i_slv_bit_cnt + 1;  
                   stm_slv <= slv_get_addr;
                 elsif( i_slv_bit_cnt = 8 ) then
                   i_slv_addr <= i_slv_addr( 6 downto 0 ) & sda;
                   i_slv_bit_cnt <= 0; 
                   stm_slv <= slv_send_addr_ack;                 
                 end if;
               elsif ( i_slv_scl_fall = '1' ) and ( i_slv_bit_cnt = 8 ) then
                 stm_slv <= slv_send_addr_ack;
                 i_slv_bit_cnt <= 0;               
               else
                 stm_slv <= slv_get_addr;
               end if;
             else
               stm_slv <= slv_idle;
             end if;
           -----------------------      
           when slv_send_addr_ack =>
             if ( i_slv_addr( 7 downto 1 ) = SLAVE_ADDR ) then  
               if ( i_slv_scl_rise = '1' ) then
                 i_sda_slv <= '0';
                 stm_slv <= slv_wait_ack;
               end if;
             else
               stm_slv <= slv_idle;
             end if;        
           -----------------------     
           when slv_wait_ack =>
             if ( i_slv_scl_fall = '1' ) then
               if ( reg_exist = '1' ) then
                 stm_slv <= slv_read_reg_addr;
               elsif ( i_slv_addr( 0 ) = '0' ) then
                 stm_slv <= slv_write_data;
                 slv_read <= '1';
               elsif ( i_slv_addr( 0 ) = '1' ) then
                 stm_slv <= slv_read_reg_addr;                 
               end if;
             else
               stm_slv <= slv_wait_ack;
             end if;
           -----------------------             
           when slv_rd_wr =>  
             i_sda_slv <= 'Z';
             i_slv_data <= slv_din; 
             i_slv_dout <= i_slv_reg_addr;                                                                  
             if ( i_slv_addr( 0 ) = '1' ) then
               slv_write <= '1';                       
               stm_slv <= slv_read_data;
             else
               stm_slv <= slv_write_data;                              
               slv_read <= '1';
             end if;             
           -----------------------
           when slv_read_reg_addr =>  
             slv_write <= '0';   
             i_sda_slv <= 'Z';
             if ( i_slv_stop_bit = '0' ) then
               if ( i_slv_scl_rise = '1' ) then
                 if ( i_slv_bit_cnt < 7 ) then               
                   i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
                   i_slv_bit_cnt <= i_slv_bit_cnt + 1; 
                   stm_slv <= slv_read_reg_addr;  
                 elsif ( i_slv_bit_cnt = 7 ) then
                   i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;                                                    
                   i_slv_bit_cnt <= 0;
                   stm_slv <= slv_send_data_ack;
                 end if;       
               else
                 stm_slv <= slv_read_reg_addr;
               end if;
             else
               stm_slv <= slv_idle;
             end if;
           -----------------------  
           when slv_send_data_ack =>  
             if ( i_slv_scl_rise = '1' ) then
               i_sda_slv <= '0';
               stm_slv <= slv_wait_data_ack;
             end if;                  
           -----------------------
           when slv_wait_data_ack =>
             if ( i_slv_scl_fall = '1' ) then
               stm_slv <= slv_rd_wr;
             else
               stm_slv <= slv_wait_data_ack;
             end if;  
           -----------------------  
           when slv_write_data =>
             slv_read <= '0';
             if ( i_slv_stop_bit = '0' ) then
               i_sda_slv <= i_slv_data( 7 );               
               if ( i_slv_scl_fall = '1' ) then
                 if ( i_slv_bit_cnt < 7 ) then
                  -- i_sda_slv <= i_slv_data( 7 );
                   i_slv_data <= i_slv_data( 6 downto 0 ) & '0';
                   i_slv_bit_cnt <= i_slv_bit_cnt + 1;
                   stm_slv <= slv_write_data;
                 elsif ( i_slv_bit_cnt = 7 ) then
                   i_sda_slv <= i_slv_data( 7 );
                   i_slv_bit_cnt <= 0;
                   stm_slv <= slv_get_wait_data_ack;
                 end if;
               end if;
             else
               stm_slv <= slv_idle;
             end if;
           ----------------------- 
           when slv_get_wait_data_ack =>
             i_sda_slv <= 'Z';
             if ( i_slv_scl_rise = '1' ) then
               stm_slv <= slv_get_data_ack;
             else
               stm_slv <= slv_get_wait_data_ack;
             end if;
           -----------------------
           when slv_get_data_ack =>
             i_sda_slv <= 'Z';
             if ( i_slv_scl_fall = '1' ) then
               if ( sda = '0' ) and ( i_slv_sda_fall = '0' ) then
                 stm_slv <= slv_rd_wr;
               else
                 stm_slv <= slv_idle;
               end if;
             else
               stm_slv <= slv_get_data_ack;
             end if;
           ------------------------  
           when slv_read_data =>
             slv_write <= '0';
             if ( i_slv_stop_bit = '1' ) then
               stm_slv <= slv_idle;
             else
               if ( i_slv_scl_rise = '1' ) then
                 if ( i_slv_bit_cnt < 7 ) then               
                   i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
                   i_slv_bit_cnt <= i_slv_bit_cnt + 1; 
                   stm_slv <= slv_read_data;  
                 elsif ( i_slv_bit_cnt = 7 ) then
                   i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;                                                    
                   i_slv_bit_cnt <= 0;
                   stm_slv <= slv_send_data_ack;
                 end if;       
               else
                 stm_slv <= slv_read_data;
               end if;             
             end if;
           -------------------------  
           when others => stm_slv <= slv_idle;
           end case;  
         end if;
       end process i2c_slave;
END ARCHITECTURE arc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -