Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The LogiCORE™ IP AXI IIC Bus Interface connects to the AMBA® AXI specification and provides a low-speed, two-wire,serial bus interface to a large number of popular devices. This product specification defines the architecture,hardware (signal) interface, software (register) interface, and parameterization options for the AXI IIC Bus Interface module.

Table of Contents

Table of Contents
excludeTable of Contents

HW IP Features

  • Compliant to industry standard I2C protocol
  • Register access through AXI4-Lite interface
  • Master or

    The LogiCORE™ IP AXI IIC Bus Interface connects to the AMBA® AXI specification and provides a low-speed, two-wire,serial bus interface to a large number of popular devices. This product specification defines the architecture,hardware (signal) interface, software (register) interface, and parameterization options for the AXI IIC Bus Interface module.


    Table of Contents

    Table of Contents
    excludeTable of Contents


    HW IP Features

    • Compliant to industry standard I2C protocol
    • Register access through AXI4-Lite interface
    • Master or slave operation
    • Multi-master operation
    • Software selectable acknowledge bit
    • Arbitration lost interrupt with automatic mode switching from master to slave
    • Calling address identification interrupt with automatic mode switching from master to slave
    • START and STOP signal generation and detection
    • Repeated START signal generation •
    • Acknowledge bit generation and detection
    • Bus busy detection •
    • Fast-Mode Plus 1 MHz, Fast Mode 400 kHz, or Standard Mode 100 kHz operation
    • 7-bit or 10-bit addressing • General call enable or disable
    • Transmit and receive FIFOs – 16 bytes deep
    • Throttling
    • General purpose output, 1-bit to 8 bits wide
    • Dynamic Start and Stop generation

    Known Issues and limitations

    • No slave mode support as of now.
    • No bus recovery. This is because the controller does not give the status of the scl / sda pins and therefore getting the status may be difficult.
    • Receive data length maximum up to 255 bytes.

    Kernel Configuration

    I2C is not enabled in the current default kernel configuration. The following steps may be used to enable the driver in the kernel configuration
    Code Block
    themeMidnight
    CONFIG_I2C_XILINX=y
     
     
    Devicetree
    CONFIG_I2C_XILINX=y
     
     

    Devicetree

    https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/i2c/i2c-xiic.txt

    Code Block
    themeMidnight
    IIC: i2c@81600000 {
        compatible = "xlnx,xps-iic-2.00.a";
        interrupt-parent = <&xps_intc_0>;
        interrupts = < 6 2 >;
        #address-cells = <1>;
        #size-cells = <0>;
     
        m24c08@50 {
            compatible = "at,24c08";
            reg = <0x50>;
        };
    } ;

    Test procedure

    I2C EEPROM From A User Space Application

    The following example reads and writes through the I2C EEPROM on the KC705 board. This example can be downloaded at the following link.
    View file
    nameiic_test.rar



    This assumes the /dev/i2c device file was created by the user or using udev.

    NOTE: The EEPROM higher level driver referenced below cannot be built into the kernel for this example to work. An error that indicates the application cannot set the I2C address will occur if this is the case.

    Code Block
    themeMidnight
    /*****************************************************************************/
    /**
    * @file i2c_test.c
    * This file contains the linux example for i2c.
    * Note:    10-bit addressing is not supported in the current linux driver.
    * Repeated start also not supported in the current linux driver.
    *
    *
    *
    * @note     None.
    *
    *
    ******************************************************************************/
     
    /***************************** Include Files *********************************/
     
    #include <fcntl.h>
    #include <stdio.h>
    #include <linux/i2c-dev.h>
     
    /************************** Constant Definitions *****************************/
     
    #define I2C_SLAVE_FORCE 0x0706
    #define I2C_SLAVE    0x0703    /* Change slave address            */
    #define I2C_FUNCS    0x0705    /* Get the adapter functionality */
    #define I2C_RDWR    0x0707    /* Combined R/W transfer (one stop only)*/
     
    #define MUX_ADDR            0x74
    #define EEPROM_ADDR            0x54
    #define MUX_CHANNEL_KINTEX7        0x04
     
    /*
     * Page size of the EEPROM. This depends on the type of the EEPROM available
     * on board.
     */
    #define PAGESIZE                            16
     
    /**************************** Type Definitions *******************************/
     
    typedef unsigned char   Xuint8;
    typedef char            Xint8;      /**< signed 8-bit */
    typedef unsigned short  Xuint16;    /**< unsigned 16-bit */
    typedef short           Xint16;     /**< signed 16-bit */
    typedef unsigned long   Xuint32;    /**< unsigned 32-bit */
    typedef long            Xint32;     /**< signed 32-bit */
    typedef float           Xfloat32;   /**< 32-bit floating point */
    typedef double          Xfloat64;   /**< 64-bit double precision floating point */
    typedef unsigned long   Xboolean;   /**< boolean (XTRUE or XFALSE) */
    typedef  Xuint8 AddressType;
     
    /***************** Macros (Inline Functions) Definitions *********************/
     
    /************************** Function Prototypes ******************************/
     
    static int IicRead(void);
    static int IicWrite(void);
    static Xuint8 ReadEepromData(Xuint8 ReadBuffer[], Xuint8 NoOfBytes);
    static Xuint8 WriteEepromData(Xuint8 ReadBuffer[], Xuint8 NoOfBytes);
    static int IicMuxEnable(void);
     
    /************************** Variable Definitions *****************************/
     
    /*
     * FD of the IIC device opened.
     */
    int Fdiic;
     
     
    /**************************** Function Definitions ***************************/
     
    /*****************************************************************************/
    /**
    *
    * Entry point for integration tests on IIC.
    *
    * @param    .
    *
    * @return   0 if successful else -1.
    *
    * @note     None.
    *
    ******************************************************************************/
    int main()
    {
        int Status;
        int TestLoops=1;
     
        /*
         * Open the device.
         */
        Fdiic = open("/dev/i2c", O_RDWR);
        if(Fdiic < 0)
        {
            printf("Cannot open the IIC device\n");
     
            return 1;
        }
     
        Status = IicMuxEnable();
         if (Status)
        {
            printf("Cannot Enable Mux device\n");
            close(Fdiic);
            return 1;
        }
     
        Status = IicWrite();
         if (Status)
        {
            printf("Cannot Wtite into EEPROM device\n");
            close(Fdiic);
            return 1;
        }
     
        Status = IicRead();
         if (Status)
        {
            printf("Cannot Read from EEPROM \n");
            close(Fdiic);
            return 1;
        }
     
        printf("eerprom test successfull \n");
        close(Fdiic);
     
        return 0;
    }
     
     
     
    /*****************************************************************************/
    /**
    *
    * Read the data from the EEPROM.
    *
    * @param    TestLoops - indicates the number of time to execute the test.
    *
    * @return   Status of the read from EEPROM
    *
    * @note     None.
    *
    ******************************************************************************/
    static int IicRead()
    {
        Xuint8 WriteBuffer [2];    /* Buffer to hold location address.*/
        Xuint8 ReadBuffer [PAGESIZE];    /* Buffer to hold data read.*/
        Xuint16 BytesToRead=PAGESIZE;
        Xuint8 BytesWritten;
        Xuint8 BytesRead=0;            /* Number of Bytes read from the IIC device. */
        Xuint16 Index;                /* Loop variable. */
        Xuint16 OffsetAddr = 0x0;    /* Address offset in EEPROM to be written. */
        Xuint8 ReadBytes;
        int Status = 0;
        Status = ioctl(Fdiic, I2C_SLAVE_FORCE, EEPROM_ADDR);
        if(Status < 0)
        {
            printf("\n Unable to set the EEPROM address\n");
     
            return -1;
        }
     
        OffsetAddr = EEPROM_ADDR;
        if(sizeof(AddressType) == 1)
        {
            WriteBuffer[0] = (Xuint8)(OffsetAddr);
        }
        else
        {
            WriteBuffer[0] = (Xuint8)(OffsetAddr >> 8);
            WriteBuffer[1] = (Xuint8)(OffsetAddr);
        }
     
        /*
         * Position the address pointer in EEPROM.
         */
        BytesWritten = write(Fdiic, WriteBuffer, sizeof(AddressType));
     
     
        /*
         * limit the bytes to be read to the Page size.
         */
        if(BytesToRead > PAGESIZE)
        {
            ReadBytes = PAGESIZE;
        }
        else
        {
            ReadBytes = BytesToRead;
        }
     
        /*
         * Read the bytes.
         */
        while(BytesToRead > 0)
        {
            printf ("Performing Read operation\n");
            BytesRead = ReadEepromData(ReadBuffer, ReadBytes);
            if(BytesRead != ReadBytes)
            {
                printf("\nITP_IIC_TEST1: Test Failed in read\n");
     
                return -1;
            }
     
            /*
             * Update the read counter.
             */
            BytesToRead -= BytesRead;
            if(BytesToRead > PAGESIZE)
            {
                ReadBytes = PAGESIZE;
            }
            else
            {
                ReadBytes = BytesToRead;
            }
     
        }
     
        printf("\nRead EEPROM Succesful\n");
     
        return 0;
    }
     
    /*****************************************************************************/
    /**
    *
    * Write data to the EEPROM.
    *
    * @param    TestLoops - indicates the number of time to execute the test.
    *
    * @return   None.
    *
    * @note     None.
    *
    ******************************************************************************/
    static int IicWrite()
    {
        Xuint8 WriteBuffer[PAGESIZE + sizeof(AddressType)]; /* Buffer to hold data to be written */
        Xuint16 BytesToWrite = PAGESIZE;
        Xuint8 BytesWritten;    /* Number of Bytes written to the IIC device. */
        Xuint16 Index;                /* Loop variable. */
        Xuint16 OffsetAddr = 0x0;    /* Address offset in EEPROM to be written. */
        Xuint16 OffsetAddrNew = 0x0;
        Xuint8 WriteBytes;
        Xuint8 Data = 0x0;
        char Input[8];
        int Status = 0;
        Status = ioctl(Fdiic, I2C_SLAVE_FORCE, EEPROM_ADDR);
        if(Status < 0)
        {
            printf("\n Unable to set the EEPROM address\n");
     
            return -1;
        }
     
        Data = 0x11;
        OffsetAddr = EEPROM_ADDR;
        /*
         * Load the offset address inside EEPROM where data need to be written.
         */
            if(sizeof(AddressType) == 1)
        {
            WriteBuffer[0] = (Xuint8)(OffsetAddr);
         }
        else
        {
            WriteBuffer[0] = (Xuint8)(OffsetAddr >> 8);
            WriteBuffer[1] = (Xuint8)(OffsetAddr);
        }
     
        /*
         * Load the data to be written into the buffer.
         */
        for(Index = 0; Index < PAGESIZE; Index++)
        {
            WriteBuffer[Index + sizeof(AddressType)] = Data;
        }
     
        /*
         * Limit the number of bytes to the page size.
         */
        if(BytesToWrite > PAGESIZE)
        {
            WriteBytes = PAGESIZE + sizeof(AddressType);
        }
        else
        {
            WriteBytes = BytesToWrite + sizeof(AddressType);
        }
     
        while(BytesToWrite > 0)
        {
            /*
             * Write the data.
             */
            BytesWritten = WriteEepromData(WriteBuffer, WriteBytes);
            if(BytesWritten != WriteBytes)
            {
                printf("\nTest Failed in write\n");
                return -1;
            }
     
            /*
             * Update the write counter.
             */
            BytesToWrite -= (BytesWritten - sizeof(AddressType));
            if(BytesToWrite > PAGESIZE)
            {
                WriteBytes = PAGESIZE + sizeof(AddressType);
            }
            else
            {
                WriteBytes = BytesToWrite + sizeof(AddressType);
            }
     
            /*
             * Increment the offset address.
             */
            OffsetAddr += PAGESIZE;
     
            /*
             * Increment the data.
             */
            Data++;
     
            /*
             * load the new offset address.
             */
            if(sizeof(AddressType) == 1)
            {
                WriteBuffer[0] = (Xuint8)(OffsetAddr);
            }
            else
            {
                WriteBuffer[0] = (Xuint8)(OffsetAddr >> 8);
                WriteBuffer[1] = (Xuint8)(OffsetAddr);
             }
     
            /*
             * load the new data into buffer.
             */
            for(Index = 0; Index < PAGESIZE; Index++)
            {
                WriteBuffer[Index + sizeof(AddressType)] = Data;
            }
        }
     
        printf("\nWrite EEPROM Succesful\n");
     
        return 0;
    }
     
    /*****************************************************************************/
    /**
    *
    * Write the data to the Slave device.
    *
    * @param    WriteBuffer - Buffer to hold the data to be transmitted on the Bus.
    * @param    NoOfBytes    - Number of bytes to be written onto the bus.
    *
    * @return   Number of bytes written onto the bus.
    *
    * @note     None.
    *
    ******************************************************************************/
    static Xuint8 WriteEepromData(Xuint8 WriteBuffer[], Xuint8 NoOfBytes)
    {
        Xuint8 BytesWritten;    /* Number of Bytes written to the IIC device. */
     
        /*
         * Write the bytes onto the bus.
         */
        BytesWritten = write(Fdiic, WriteBuffer, NoOfBytes);
     
        /*
         * Wait till the EEPROM internally completes the write cycle.
         */
        sleep(1);
     
        return BytesWritten;
    }
     
    /*****************************************************************************/
    /**
    *
    * Read the data from the Slave device.
    *
    * @param    ReadBuffer  - Buffer to hold the data received on the bus.
    * @param    NoOfBytes    - Number of bytes to be read from the bus.
    *
    * @return   Number of bytes read from the bus.
    *
    * @note     None.
    *
    ******************************************************************************/
    static Xuint8 ReadEepromData(Xuint8 ReadBuffer[], Xuint8 NoOfBytes)
    {
        Xuint8 BytesRead;    /* Number of Bytes read from the device. */
     
        /*
         * Read the bytes from the bus.
         */
        BytesRead = read(Fdiic, ReadBuffer, NoOfBytes);
     
        return BytesRead;
    }
     
     
     
    /*****************************************************************************/
    /**
    *
    * Enable the MUX Switch that routes to EEPROM. Mux Reg = 0x04 for Kintex-7
    *
    * @return   None.
    *
    * @note     None.
    *
    ******************************************************************************/
     
     
    static int IicMuxEnable(void)
    {
        Xuint8 WriteBuffer[2];    /* Buffer to hold location address.*/
        Xuint8 ReadBuffer = 0x0;    /* Buffer to hold data read.*/
        Xuint16 BytesToRead;
        Xuint8 BytesWritten;
        Xuint8 BytesRead;            /* Number of Bytes read from the IIC device. */
        Xuint16 Index;                /* Loop variable. */
        Xuint16 Sel_Channel = 0x0;
        Xuint32 Mux_Reg = 0x1;
        Xuint8 ReadBytes;
        int Status;
        char Input[8];
     
        Status = ioctl(Fdiic, I2C_SLAVE_FORCE, MUX_ADDR);
        if(Status < 0)
        {
            printf("\n Unable to set the Mux address\n");
     
            return -1;
        }
     
        Sel_Channel = MUX_CHANNEL_KINTEX7;
     
        Mux_Reg = Mux_Reg << (Sel_Channel - 1);
        WriteBuffer[0] = Mux_Reg;
     
        printf("Selected Channel [%d] Mux Reg Value[%x]\n", Sel_Channel, Mux_Reg);
     
        /*
         * Position the address pointer in EEPROM.
         */
        BytesWritten = write(Fdiic, WriteBuffer, 1);
        if(BytesWritten != 1)
        {
            printf("Write Mux Reg failed\n");
            return -1;
        }
     
        BytesToRead = read(Fdiic, &ReadBuffer, 1);
        if(BytesToRead != 1)
        {
            printf("Read Mux Reg failed\n");
            return -1;
        }
        printf("Mux Reg Expected[%x] Actual[%x]\n", Mux_Reg, ReadBuffer);
     
        printf("\nMux Enable for EEPROM Succesful\n");
     
        return 0;
    }
    Using An I2C EEPROM Driver As A Higher Layer

    I2C EEPROM Driver Kernel Configuration

    There are higher layer drivers that allow the I2C driver to be used to access other devices such as the I2C serial EEPROM on the ML507 board. The following steps may be used to enable the driver in the kernel configuration.

    1. From the device drivers menu, select Misc devices
    2. Select EEPROM Support
    3. Select I2C EEPROMs from most vendors
    Adding An I2C EEPROM To The Device Tree

    The following example shows adding the I2C EEPROM for the ML507 to it's device tree. The value of 0x050 is the I2C address of the EEPROM.

    The device-tree generator for the EDK does not create this device on the I2C bus.

    Code Block
    themeMidnight
    IIC: i2c@81600000 {
        compatible = "xlnx,xps-iic-2.00.a";
        interrupt-parent = <&xps_intc_0>;
        interrupts = < 6 2 >;
        reg = < 0x81600000 0x10000 >;
        #address-cells = <1>;
        #size-cells = <0>;
     
        m24c08@50 {
            compatible = "at,24c08";
            reg = <0x50>;
        };
    } ;

    Expected Output


    The following kernel output (or similar) shows the EEPROM driver was started.

    Device Tree Probing 'i2c'
    81600000.i2c #0 at 0x81600000 mapped to 0xD1020000, irq=20
    at24 0-0050: 1024 byte 24c08 EEPROM (writable)
    Code Block
    themeMidnight
    U-Boot 2016.07 (Nov 30 2016 - 10:58:35 +0530)
     
     
     
    DRAM:  ECC disabled 1 GiB
     
    MMC:   sdhci@e0100000: 0
     
    SF: Detected N25Q128A with page size 256 Bytes, erase size 64 KiB, total 16 MiB
     
    *** Warning - bad CRC, using default environment
     
     
     
    In:    serial
     
    Out:   serial
     
    Err:   serial
     
    Net:   ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id
     
    eth0: ethernet@e000b000
     
    U-BOOT for
     
     
     
    ethernet@e000b000 Waiting for PHY auto negotiation to complete...... done
     
    BOOTP broadcast 1
     
    BOOTP broadcast 2
     
    BOOTP broadcast 3
     
    DHCP client bound to address 10.10.70.5 (1003 ms)
     
    Hit any key to stop autoboot:  4  0
     
    U-Boot-PetaLinux> bootm 0x3000000
     
    ## Loading kernel from FIT Image at 03000000 ...
     
       Using 'conf@1' configuration
     
       Verifying Hash Integrity ... OK
     
       Trying 'kernel@1' kernel subimage
     
         Description:  PetaLinux Kernel
     
         Type:         Kernel Image
     
         Compression:  gzip compressed
     
         Data Start:   0x030000f0
     
         Data Size:    7967175 Bytes = 7.6 MiB
     
         Architecture: ARM
     
         OS:           Linux
     
         Load Address: 0x00008000
     
         Entry Point:  0x00008000
     
         Hash algo:    crc32
     
         Hash value:   12d074ef
     
       Verifying Hash Integrity ... crc32+ OK
     
    ## Loading fdt from FIT Image at 03000000 ...
     
       Using 'conf@1' configuration
     
       Trying 'fdt@1' fdt subimage
     
         Description:  Flattened Device Tree blob
     
         Type:         Flat Device Tree
     
         Compression:  uncompressed
     
         Data Start:   0x0379939c
     
         Data Size:    15832 Bytes = 15.5 KiB
     
         Architecture: ARM
     
         Hash algo:    crc32
     
         Hash value:   d105e61e
     
       Verifying Hash Integrity ... crc32+ OK
     
       Booting using the fdt blob at 0x379939c
     
       Uncompressing Kernel Image ... OK
     
       Loading Device Tree to 07ff9000, end 07fffdd7 ... OK
     
     
     
    Starting kernel ...
     
     
     
    Booting Linux on physical CPU 0x0
     
     
    Linux version 4.6.0-xilinx (sivaraj@xhdrfl23) (gcc version 5.2.1 20151005 (Linaro GCC 5.2-2015.11-2) ) #2 SMP PREEMPT Wed Nov 30 11:01:30 IST 2016
     
     
    CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
     
     
    CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
     
     
    Machine model: Xilinx-ZC702-2016.3
     
     
    bootconsole [earlycon0] enabled
     
     
    cma: Reserved 16 MiB at 0x3f000000
     
     
    Memory policy: Data cache writealloc
     
     
    percpu: Embedded 12 pages/cpu @ef7d1000 s19968 r8192 d20992 u49152
     
     
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260608
     
     
    Kernel command line: console=ttyPS0,115200 earlyprintk
     
     
    PID hash table entries: 4096 (order: 2, 16384 bytes)
     
     
    Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
     
     
    Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
     
     
    Memory: 1010264K/1048576K available (5280K kernel code, 221K rwdata, 1812K rodata, 5120K init, 211K bss, 21928K reserved, 16384K cma-reserved, 245760K highmem)
     
     
    Virtual kernel memory layout:
     
     
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
     
     
        fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
     
     
        vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)
     
     
        lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)
     
     
        pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
     
     
        modules : 0xbf000000 - 0xbfe00000   (  14 MB)
     
     
          .text : 0xc0008000 - 0xc07ed3f4   (8085 kB)
     
     
          .init : 0xc0800000 - 0xc0d00000   (5120 kB)
     
     
          .data : 0xc0d00000 - 0xc0d37760   ( 222 kB)
     
     
           .bss : 0xc0d37760 - 0xc0d6c700   ( 212 kB)
     
     
    Preemptible hierarchical RCU implementation.
     
     
        Build-time adjustment of leaf fanout to 32.
     
     
        RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
     
     
    RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
     
     
    NR_IRQS:16 nr_irqs:16 16
     
     
    efuse mapped to f0802000
     
     
    slcr mapped to f0804000
     
     
    L2C: platform modifies aux control register: 0x72360000 -> 0x72760000
     
     
    L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000
     
     
    L2C-310 erratum 769419 enabled
     
     
    L2C-310 enabling early BRESP for Cortex-A9
     
     
    L2C-310 full line of zeros enabled for Cortex-A9
     
     
    L2C-310 ID prefetch enabled, offset 1 lines
     
     
    L2C-310 dynamic clock gating enabled, standby mode enabled
     
     
    L2C-310 cache controller enabled, 8 ways, 512 kB
     
     
    L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76760001
     
     
    zynq_clock_init: clkc starts at f0804100
     
     
    Zynq clock init
     
     
    sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns
     
     
    clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns
     
     
    Switching to timer-based delay loop, resolution 3ns
     
     
    clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 537538477 ns
     
     
    timer #0 at f080c000, irq=17
     
     
    Console: colour dummy device 80x30
     
     
    Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333)
     
     
    pid_max: default: 32768 minimum: 301
     
     
    Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
     
     
    Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)
     
     
    CPU: Testing write buffer coherency: ok
     
     
    CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
     
     
    Setting up static identity map for 0x100000 - 0x100058
     
     
    CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
     
     
    Brought up 2 CPUs
     
     
    SMP: Total of 2 processors activated (1333.33 BogoMIPS).
     
     
    CPU: All CPU(s) started in SVC mode.
     
     
    devtmpfs: initialized
     
     
    VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
     
     
    clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
     
     
    pinctrl core: initialized pinctrl subsystem
     
     
    NET: Registered protocol family 16
     
     
    DMA: preallocated 256 KiB pool for atomic coherent allocations
     
     
    cpuidle: using governor ladder
     
     
    cpuidle: using governor menu
     
     
    hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
     
     
    hw-breakpoint: maximum watchpoint size is 4 bytes.
     
     
    zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xf0880000
     
     
    zynq-pinctrl 700.pinctrl: zynq pinctrl initialized
     
     
    GPIO IRQ not connected
     
     
    XGpio: /amba_pl/gpio@41200000: registered, base is 902
     
     
    vgaarb: loaded
     
     
    SCSI subsystem initialized
     
     
    usbcore: registered new interface driver usbfs
     
     
    usbcore: registered new interface driver hub
     
     
    usbcore: registered new device driver usb
     
     
    media: Linux media interface: v0.10
     
     
    Linux video capture interface: v2.00
     
     
    pps_core: LinuxPPS API ver. 1 registered
     
     
    pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
     
     
    PTP clock support registered
     
     
    EDAC MC: Ver: 3.0.0
     
     
    Advanced Linux Sound Architecture Driver Initialized.
     
     
    clocksource: Switched to clocksource arm_global_timer
     
     
    NET: Registered protocol family 2
     
     
    TCP established hash table entries: 8192 (order: 3, 32768 bytes)
     
     
    TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
     
     
    TCP: Hash tables configured (established 8192 bind 8192)
     
     
    UDP hash table entries: 512 (order: 2, 16384 bytes)
     
     
    UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
     
     
    NET: Registered protocol family 1
     
     
    RPC: Registered named UNIX socket transport module.
     
     
    RPC: Registered udp transport module.
     
     
    RPC: Registered tcp transport module.
     
     
    RPC: Registered tcp NFSv4.1 backchannel transport module.
     
     
    hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
     
     
    futex hash table entries: 512 (order: 3, 32768 bytes)
     
     
    workingset: timestamp_bits=28 max_order=18 bucket_order=0
     
     
    jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
     
     
    bounce: pool size: 64 pages
     
     
    io scheduler noop registered
     
     
    io scheduler deadline registered
     
     
    io scheduler cfq registered (default)
     
     
    dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330
     
     
    dma-pl330 f8003000.dmac:     DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
     
     
    e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 144, base_baud = 3125000) is a xuartps
     
    àconsole [ttyPS0] enabled
     
    console [ttyPS0] enabled
     
     
    bootconsole [earlycon0] disabled
     
    bootconsole [earlycon0] disabled
     
     
    xdevcfg f8007000.devcfg: ioremap 0xf8007000 to f0904000
     
    [drm] Initialized drm 1.1.0 20060810
     
    brd: module loaded
     
    loop: module loaded
     
    m25p80 spi0.0: found n25q128a11, expected n25q128a13
     
    m25p80 spi0.0: n25q128a11 (16384 Kbytes)
     
    4 ofpart partitions found on MTD device spi0.0
     
    Creating 4 MTD partitions on "spi0.0":
     
    0x000000000000-0x000000500000 : "boot"
     
    0x000000500000-0x000000520000 : "bootenv"
     
    0x000000520000-0x000000fa0000 : "kernel"
     
    0x000000fa0000-0x000001000000 : "spare"
     
    CAN device driver interface
     
    gpiod_set_value: invalid GPIO
     
    libphy: MACB_mii_bus: probed
     
    mdio_bus e000b000.etherne:07: mdio_device_register
     
    macb e000b000.ethernet eth0: no PHY found
     
    e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
     
    e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
     
    ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
     
    ehci-pci: EHCI PCI platform driver
     
    usbcore: registered new interface driver usb-storage
     
    e0002000.usb supply vbus not found, using dummy regulator
     
    ULPI transceiver vendor/product ID 0x0424/0x0007
     
    Found SMSC USB3320 ULPI transceiver.
     
    ULPI integrity check: passed.
     
    ci_hdrc ci_hdrc.0: EHCI Host Controller
     
    ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
     
    ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
     
    hub 1-0:1.0: USB hub found
     
    hub 1-0:1.0: 1 port detected
     
    mousedev: PS/2 mouse device common for all mice
     
    i2c /dev entries driver
     
    i2c i2c-0: Added multiplexed i2c bus 1
     
    i2c i2c-0: Added multiplexed i2c bus 2
     
    at24 3-0054: 1024 byte 24c08 EEPROM, writable, 1 bytes/write
     
    i2c i2c-0: Added multiplexed i2c bus 3
     
    i2c i2c-0: Added multiplexed i2c bus 4
     
    rtc-pcf8563 5-0051: chip found, driver version 0.4.4
     
    rtc-pcf8563 5-0051: rtc core: registered rtc-pcf8563 as rtc0
     
    i2c i2c-0: Added multiplexed i2c bus 5
     
    i2c i2c-0: Added multiplexed i2c bus 6
     
    i2c i2c-0: Added multiplexed i2c bus 7
     
    i2c i2c-0: Added multiplexed i2c bus 8
     
    pca954x 0-0074: registered 8 multiplexed busses for I2C switch pca9548
     
    Xilinx Zynq CpuIdle Driver started
     
    sdhci: Secure Digital Host Controller Interface driver
     
    sdhci: Copyright(c) Pierre Ossman
     
    sdhci-pltfm: SDHCI platform and OF driver helper
     
    mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using DMA
     
    ledtrig-cpu: registered to indicate activity on CPUs
     
    usbcore: registered new interface driver usbhid
     
    usbhid: USB HID core driver
     
    si570 1-005d: registered, current frequency 148500000 Hz
     
    NET: Registered protocol family 17
     
    can: controller area network core (rev 20120528 abi 9)
     
    NET: Registered protocol family 29
     
    can: raw protocol (rev 20120528)
     
    can: broadcast manager protocol (rev 20120528 t)
     
    can: netlink gateway (rev 20130117) max_hops=1
     
    Registering SWP/SWPB emulation handler
     
    rtc-pcf8563 5-0051: setting system clock to 2016-11-30 05:34:07 UTC (1480484047)
     
    ALSA device list:
     
      No soundcards found.
     
    Freeing unused kernel memory: 5120K (c0800000 - c0d00000)
     
     
    INIT: version 2.88 booting
     
     
    usb 1-1: new high-speed USB device number 2 using ci_hdrc
     
    mmc0: new high speed SDHC card at address 1234
     
    mmcblk0: mmc0:1234 SA04G 3.64 GiB
     
     mmcblk0: p1
     
    usb-storage 1-1:1.0: USB Mass Storage device detected
     
    scsi host0: usb-storage 1-1:1.0
     
    FAT-fs (mmcblk0p1): Invalid FSINFO signature: 0x00000689, 0x00000702 (sector = 1)
     
    FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
     
    bootlogd: cannot allocate pseudo tty: No such file or directory
     
    Creating /dev/flash/* device nodes
     
    random: dd urandom read with 4 bits of entropy available
     
    Starting internet superserver: inetd.
     
     
    INIT: Entering runlevel: 5
     
     
    Configuring network interfaces... ifconfig: SIOCGIFFLAGS: No such device
     
    scsi 0:0:0:0: Direct-Access     SanDisk  Cruzer           1.26 PQ: 0 ANSI: 6
     
    sd 0:0:0:0: Attached scsi generic sg0 type 0
     
    sd 0:0:0:0: [sda] 15633408 512-byte logical blocks: (8.00 GB/7.45 GiB)
     
     
     
     
    PetaLinux 2016.3 Xilinx-ZC702-2016_3 /dev/ttyPS0
     
     
    Xilinx-ZC702-2016_3 login: sd 0:0:0:0: [sda] Write Protect is off
     
    sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
     
     sda: sda1
     
    sd 0:0:0:0: [sda] Attached SCSI disk
     
    root
     
    Password:
     
    login[966]: root login on 'ttyPS0'
     
     
     
     
    7[r[999;999H[6n8root@Xilinx-ZC702-2016_3:~# pwd
     
    /home/root
     
    root@Xilinx-ZC702-2016_3:~# i2cdetect -l | grep  xiic-i2c
     
    i2c-0    i2c           xiic-i2c                            I2C adapter
     
    root@Xilinx-ZC702-2016_3:~# i2cdetect -y 0x3
     
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
     
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
     
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     
    50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
     
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
     
    70: -- -- -- -- UU -- -- --
     
    root@Xilinx-ZC702-2016_3:~#  i2cdump -y  -f 0x3 0x54
     
    No size specified (using byte-data access)
     
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
     
    00: 01 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    10: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    20: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    30: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    40: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    50: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    60: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    70: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    80: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    90: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    a0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    b0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    c0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    d0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    e0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    f0: 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19    ????????????????
     
    root@Xilinx-ZC702-2016_3:~# i2cget -y -f 0x3 0x54 0
     
    0x01
     
    root@Xilinx-ZC702-2016_3:~# i2cset -y -f  0x3 0x54 0 1
     
    root@Xilinx-ZC702-2016_3:~# i2cget -y -f 0x3 0x54 0 | grep 0x01
     
    0x01
     
    root@Xilinx-ZC702-2016_3:~# i2cget -y -f 0x3 0x54 0 | grep 0x01 | if [ $? -ne 0
     
     
    ]; then echo Unsuccessful ;else echo Passed;  fi
     
    Passed
     
    root@Xilinx-ZC702-2016_3:~#
     
    root@Xilinx-ZC702-2016_3:~#
     


    Code Block
    themeMidnight
    root@Xilinx-KC705-2013:~#

    SysFS Interface.
    The EEPROM driver allows the contents of the EEPROM to be seen in the sys file system at /sys/bus/i2c/devices/0-0050/eeprom.
    The file,eeporm, is a file that can be read and written from user space.
    If the sys file system is not mounted (no /sys dir), then the following commands will create and mount it.

    bash > mkdir /sys/
    bash > mount -t sysfs sysfs sys

    The following shell commands can view the contents of the eeprom by 1st capturing it and then displaying the file as binary data.

    bash> more /sys/bus/i2c/devices/0-0050/eeprom > eeprom.txt | od -x

    Code Block
    themeMidnight
    The following command will write "01234567890DEADBEEFCAFE" to the EEPROM. Be careful as the ethernet MAC address is in the EEPROM and can be overwritten.


    Code Block
    themeMidnight
    echo 0123456789DEADBEEFCAFE > /sys/bus/i2c/devices/0-0050/eeprom
    code
    Using An Aardvark I2C/SPI Activity Board For I2C EEPROM Testing

    TotalPhase, the company that sells the Aardvark I2C test equipment, also sells a small board that we can use for our own testing, independent of the Aardvark. The board has an I2C EEPROM and an SPI EEPROM on it such that it can be connected to an FPGA board pretty easy.

    http://www.totalphase.com/products/activity_board/
    http://www.totalphase.com/download/pdf/activity-board-v1.00.pdf
    http://www.totalphase.com/products/split_cable/

    The point of this exercise is to have a standard test for the I2C that can be used across all boards.

    See the following page, I2C With The Aardvark Board, for more information on how to do it.

    Mainline Status

    • This driver is currently in sync with mainline kernel except for the following:

      • i2c: xiic: Fix Rx and Tx paths in standard mode repeated start
      • i2c: xiic: Correct the datatype for rx_watermark
      • i2c: xiic: Add standard mode support for > 255 byte read transfers
      • i2c: xiic: Fix Tx Interrupt path for grouped messages

    Change Log

    • 2016.3
    •  
      • None
    • 2016.4
      • None
    • 2017.1
      • None
    • 2017.2
      • None
    • 2017.3
      • None
    • 2017.4
      • None
    • 2018.1
      • Summary:
        • i2c: xiic: defer the probe if clock is not found
      • Commits:
        • d8aad33 i2c: xiic: defer the probe if clock is not found

    • 2018.2
      • None
    • 2018.3
      • Summary
        i2c: xiic: Make the start and the byte count write atomic
        i2c: xiic: Fix the clocking across bind unbind
      • Commits
        • ae7304c i2c: xiic: Make the start and the byte count write atomic
        • fc008f848 i2c: xiic: Fix the clocking across bind unbind
    • 2019.1
      • Summary:
        • i2c: xiic: Add timeout to the rx fifo wait loop
      • Commits:
        • b74ba1c14 i2c: xiic: Add timeout to the rx fifo wait loop