Part Number:PCA9548A
I am experiencing an issue while configuring the IIC with AXI-IIC. After I set the RESET pin high, only one 9-bit piece of information is transmitted on the SCL and SDA lines. The last bit of this transmission is a NACK signal. Despite multiple attempts, I am unable to successfully configure the IIC.
Here are the codes and cores I've used:
-- Title: IIC Controller for KC705 clock setup -- Project: cpri_v6_1 ----------------------------------------------------------------------- -- File: iic_controller.vhd -- Author: Xilinx ----------------------------------------------------------------------- -- Description: --This module generates IIC commands to set up the Si570 and Si5326 --Clock generation on the KC705 board to provide CPRI GT reference --clock -- ----------------------------------------------------------------------- -- (c) Copyright 2004 - 2012 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. ----------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity iic_controller is port (reset: in std_logic;clk100 : in std_logic;-- 100 MHz system clockiic_sda : inout std_logic;iic_scl : inout std_logic;done: out std_logic); end iic_controller; architecture rtl of iic_controller is-- AXI IIC controller component (from EDK)component axi_iic_controlport (S_AXI_ACLK: in std_logic;S_AXI_ARESETN : in std_logic;IIC2INTC_Irpt : out std_logic;S_AXI_AWADDR : in std_logic_vector(31 downto 0);S_AXI_AWVALID : in std_logic;S_AXI_AWREADY : out std_logic;S_AXI_WDATA: in std_logic_vector(31 downto 0);S_AXI_WSTRB: in std_logic_vector(3 downto 0);S_AXI_WVALID : in std_logic;S_AXI_WREADY : out std_logic;S_AXI_BRESP: out std_logic_vector(1 downto 0);S_AXI_BVALID : out std_logic;S_AXI_BREADY : in std_logic;S_AXI_ARADDR : in std_logic_vector(31 downto 0);S_AXI_ARVALID : in std_logic;S_AXI_ARREADY : out std_logic;S_AXI_RDATA: out std_logic_vector(31 downto 0);S_AXI_RRESP: out std_logic_vector(1 downto 0);S_AXI_RVALID : out std_logic;S_AXI_RREADY : in std_logic;tx_fifo_empty : out std_logic;bus_busy: out std_logic;Sda_I: in std_logic;Sda_O: out std_logic;Sda_T: out std_logic;Scl_I: in std_logic;Scl_O: out std_logic;Scl_T: out std_logic;Gpo: out std_logic_vector(0 downto 0));end component;--------------------------------------------------------------------------------- Command look up table format----------------------------------------------------------------------------------- The total number of IIC commands is indicated in the first entry.-- Each subsequent entry indicates the AXI IIC core target address and target data.---- Refer to AXI IIC core DS756 for addresses and tx_fifo format.---- for example,-- - entry 1 writes 0x0001 to address 0x100-- - entry 2 writes 0x01e8 to address 0x108---- AXI IIC controller registers :-- x0100 - Control Register-- x0108 - Tx FIFObit 8 = Start, Bit 9 = Stop, 7:0 = Datasignal cmd_rom : t_cmd_rom := (0 => X"0000_0039", -- Total IIC commands in table--1 => X"0100_0001", -- enable AXI IIC core------------------------------------------------- PCA9548 IIC switchAddr = 74-----------------------------------------------2 => X"0108_01e8", -- addr = 74 (shifted up 1 bit - bit 0 = rw)3 => X"0108_0281", -- channel 7 enabled (Si5324/Si5326)-- channel 0 enabled (Si570)------------------------------------------------- Si5326 Jitter AttenuatorAddr = 68-----------------------------------------------4 => X"0108_01d0", -- Register 05 => X"0108_0000", -- setup Si5326 for6 => X"0108_0254", -- free run mode-- Set N1_HS output divider7 => X"0108_01d0",8 => X"0108_0019", -- Register 259 => X"0108_0280", -- N1_HS = 8 (0b101)-- Transceiver is clocked from CLKOUT1 from Si5324/5326.-- Set the CLKOUT1 divider here.10 => X"0108_01d0",11 => X"0108_001f", -- Register 3112 => X"0108_0200", -- NC1_LS[19:16] = 4 (0x00)13 => X"0108_01d0",14 => X"0108_0020", -- Register 3215 => X"0108_0200", -- NC1_LS[15:8] = 4 (0x00)16 => X"0108_01d0",17 => X"0108_0021", -- Register 3318 => X"0108_0203", -- NC1_LS[7:0] = 4 (0x03)-- Set the PLL divider to 8 * 31219 => X"0108_01d0",20 => X"0108_0028", -- Register 4021 => X"0108_0280", -- N2_HS = 8, N2_LS[19:16] = 336 (0x00)22 => X"0108_01d0",23 => X"0108_0029", -- Register 4124 => X"0108_0201", -- N2_LS[15:8] = 336 (0x51)25 => X"0108_01d0",26 => X"0108_002A", -- Register 4227 => X"0108_024F", -- N2_LS[7:0] = 336 (0x4F)-- The recovered clock from the FPGA to the CLKIN1 input of the Si5324/5326-- is set at 30.72MHz. Divide this by 1301 to get the correct input-- to the PLL.28 => X"0108_01d0",29 => X"0108_002B", -- Register 4330 => X"0108_0200", -- N31[18:16] = 84 (0x00)31 => X"0108_01d0",32 => X"0108_002C", -- Register 4433 => X"0108_0200", -- N31[15:8] = 84 (0x05)34 => X"0108_01d0",35 => X"0108_002D", -- Register 4536 => X"0108_0253", -- N31[7:0] = 84 (0x14)-- The free running oscillator runs at 114.285MHz. Divide this by-- 4840 to get the correct input to the PLL37 => X"0108_01d0",38 => X"0108_002E", -- Register 4639 => X"0108_0200", -- N32[18:16] = 60 (0x00)40 => X"0108_01d0",41 => X"0108_002F", -- Register 4742 => X"0108_0200", -- N32[18:16] = 60 (0x12)43 => X"0108_01d0",44 => X"0108_0030", -- Register 4845 => X"0108_023B", -- N32[7:0] = 60 (0xE7)-- Set the auto-select mode to "Automatic Revertive" and-- program LOCK settings46 => X"0108_01d0",47 => X"0108_0004", -- Register 448 => X"0108_0292", -- AUTOSEL_REG[1:0] = 0b1049 => X"0108_01d0",50 => X"0108_0013", -- Register 1951 => X"0108_0229", -- LOCKT[2:0] = 0b00152 => X"0108_01d0",53 => X"0108_0089", -- Register 13754 => X"0108_0201", -- FASTLOCK = 1-- Perform an internal calibration55 => X"0108_01d0",56 => X"0108_0088", -- Register 13657 => X"0108_0240", -- ICAL = 1others => (others => '0'));type state_type is (START, IDLE, AXI_WRITE, AXI_RESP, FINISH);signal axi_state : state_type := START;signal lut_address: unsigned(LUT_AWIDTH-1 downto 0);signal lut_commands: unsigned(LUT_AWIDTH-1 downto 0);signal lut_data: std_logic_vector(31 downto 0);signal axi_areset_n: std_logic;signal iic2intc_irpt : std_logic;signal s_axi_awaddr: std_logic_vector(31 downto 0);signal s_axi_awvalid : std_logic;signal s_axi_awready : std_logic;signal s_axi_wdata: std_logic_vector(31 downto 0);signal s_axi_wstrb: std_logic_vector( 3 downto 0);signal s_axi_wvalid: std_logic;signal s_axi_wready: std_logic;signal s_axi_bresp: std_logic_vector( 1 downto 0);signal s_axi_bvalid: std_logic;signal s_axi_bready: std_logic;signal s_axi_araddr: std_logic_vector(31 downto 0);signal s_axi_arvalid : std_logic;signal s_axi_arready : std_logic;signal s_axi_rdata: std_logic_vector(31 downto 0);signal s_axi_rresp: std_logic_vector( 1 downto 0);signal s_axi_rvalid: std_logic;signal s_axi_rready: std_logic;signal tx_fifo_empty : std_logic;signal bus_busy: std_logic;signal sda_buf: std_logic;signal scl_buf: std_logic;signal sda_o: std_logic;signal scl_o: std_logic;signal sda_t: std_logic;signal scl_t: std_logic;signal sda_i: std_logic;signal scl_i: std_logic; begin-- Synchronous read on rom to improve timingprocess(clk100)beginif rising_edge(clk100) then-- register rom data outputlut_data <= cmd_rom(to_integer(lut_address));end if;end process;--------------------------------------------------------------------------------- State machine for controlling writes to the AXI IIC corep_mgmnt_states : process(clk100, reset)beginif (reset = '1') thenaxi_state<= START;s_axi_awaddr <= (others => '0');s_axi_awvalid <= '0';s_axi_wstrb<= (others => '0');s_axi_wvalid <= '0';s_axi_bready <= '0';s_axi_araddr <= (others => '0');s_axi_arvalid <= '0';s_axi_rready <= '0';lut_address<= (others => '0');done<= '0';elsif rising_edge(clk100) thencase axi_state iswhen START =>-- Read the command count from location 0 in the LUTif (lut_address = 1) thenaxi_state <= IDLE;end if;lut_commands <= unsigned(lut_data(LUT_AWIDTH-1 downto 0));lut_address <= to_unsigned(1, lut_address'length);done<= '0';when IDLE =>-- writes_axi_awaddr<= (others => '0');s_axi_awvalid <= '0';s_axi_wstrb<= (others => '0');s_axi_wvalid<= '0';s_axi_bready<= '0';-- reads_axi_araddr<= (others => '0');s_axi_arvalid <= '0';s_axi_rready<= '0';done<= '0';if (lut_commands = 0) thenaxi_state <= FINISH;else-- bit 8 from LUT is 'START' bit indicating a new IIC command-- so we ensure the bus is not busy and the Tx FIFO is empty-- otherwise, just write data to the Tx FIFOif ( (lut_data(8) = '1') and (tx_fifo_empty = '1') and (bus_busy = '0') ) or( (lut_data(8) = '0') ) then-- Write operation, post address and dataaxi_state<= AXI_WRITE;s_axi_awaddr(15 downto 0) <= lut_data(31 downto 16);s_axi_awvalid<= '1';s_axi_wdata(15 downto 0) <= lut_data(15 downto 00);s_axi_wstrb<= (others => '1');s_axi_wvalid<= '1';end if;end if;when AXI_WRITE=>if (s_axi_wready = '1') and (s_axi_awready = '1') thenaxi_state<= AXI_RESP;s_axi_wstrb<= (others => '0');s_axi_awvalid <= '0';s_axi_wvalid<= '0';s_axi_bready<= '1';lut_commands<= lut_commands - 1;lut_address<= lut_address + 1;end if;when AXI_RESP =>if (s_axi_bvalid = '1') thenaxi_state<= IDLE;s_axi_bready <= '0';end if;when FINISH =>-- all commands executed, flag complete and hibernatedone <= '1';end case;end if;end process;--------------------------------------------------------------------------------- IIC control - uses AXI IIC controlleraxi_areset_n <= not reset;iic_ctrl : axi_iic_controlport map (S_AXI_ACLK=> clk100,S_AXI_ARESETN => axi_areset_n,IIC2INTC_Irpt => iic2intc_irpt,-- write portS_AXI_AWADDR => s_axi_awaddr,S_AXI_AWVALID => s_axi_awvalid,S_AXI_AWREADY => s_axi_awready,S_AXI_WDATA=> s_axi_wdata,S_AXI_WSTRB=> s_axi_wstrb,S_AXI_WVALID => s_axi_wvalid,S_AXI_WREADY => s_axi_wready,S_AXI_BRESP=> s_axi_bresp,S_AXI_BVALID => s_axi_bvalid,S_AXI_BREADY => s_axi_bready,-- read portS_AXI_ARADDR => s_axi_araddr,S_AXI_ARVALID => s_axi_arvalid,S_AXI_ARREADY => s_axi_arready,S_AXI_RDATA=> s_axi_rdata,S_AXI_RRESP=> s_axi_rresp,S_AXI_RVALID => s_axi_rvalid,S_AXI_RREADY => s_axi_rready,-- extra status signalstx_fifo_empty => tx_fifo_empty,bus_busy=> bus_busy,Sda_I=> sda_i,Sda_O=> sda_o,Sda_T=> sda_t,Scl_I=> scl_i,Scl_O=> scl_o,Scl_T=> scl_t,Gpo=> open);-- tristate buffers for IIC interfacesda_i <= iic_sda;scl_i <= iic_scl;sda_buf <= sda_o when (sda_t = '0') else 'Z';scl_buf <= scl_o when (scl_t = '0') else 'Z';iic_sda <= sda_buf;iic_scl <= scl_buf; end rtl;
within which I invoke the file AXI-IIC.
Here are the steps I've taken:
– I have set up the hardware as per the manufacturer's guidelines.
– For configuration, I followed the steps outlined in the datasheet, including setting specific registers and initialization sequences. The IIC slave bus address I use is 74(hexadecimal).
– I observed the SCL and SDA lines using an oscilloscope, which confirmed the single 9-bit transmission with the final bit as a NACK.
I am unsure what might be causing this problem and would appreciate any insights or suggestions on how to resolve it.
Thank you in advance for your help! Best regards.
Alice:
您好,
0X74地址对应的是A2 为高电平,A1 A0为低电平。
如果写入操作(8-6. Write to Control Register),第一个字节后PCA9548A没有ACK反馈,请检查芯片供电是否正常,
I2C时序是否正确(图 8-1. Definition of Start and Stop Conditions )。
支持复位的 PCA9548A 低电压 8 通道 I2C 开关 datasheet (Rev. G) (ti.com.cn)