Search

Technical Discussion Group Forum

This forum is provided for user discussion. While Beacon EmbeddedWorks support staff and engineers participate, Beacon EmbeddedWorks does not guarantee the accuracy of all information within in the Technical Discussion Group (TDG).

The "Articles" forums provide brief Articles written by Beacon EmbeddedWorks engineers that address the most frequently asked technical questions.

To receive email notifications when updates are posted for a Beacon EmbeddedWorks product download, please subscribe to the TDG Forum of interest.

TDG Forum

PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 25 Sep 2015 10:40 AM by  chad.grant
WinCE I2C
 13 Replies
Sort:
You are not authorized to post a reply.
Author Messages
chad.grant
New Member
New Member
Posts:18


--
21 Sep 2015 05:17 PM

    I'm trying to setup I2C2 as a master to communicate with a number of slaves, but I'm not able to get SDA or SCL to toggle at all.

    This is how I'm calling things:

        hI2C = CreateFile(
            TEXT("I2C2:"),
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_RANDOM_ACCESS,
            NULL );

        DWORD dwBaudIndex = SLOWSPEED_MODE;
        DeviceIoControl(
            hI2C,
            IOCTL_I2C_SET_BAUD_INDEX,
            &dwBaudIndex,
            sizeof(dwBaudIndex),
            NULL,
            0,
            NULL,
            NULL);
        DeviceIoControl(
            hI2C,
            IOCTL_I2C_SET_SLAVE_ADDRESS,
            &dwSlaveAddr,
            sizeof(dwSlaveAddr),
            NULL,
            0,
            NULL,
            NULL);
        SetFilePointer(hI2C, 0, NULL, FILE_BEGIN);
        ret = WriteFile(hI2C, command_string, command_bytes, &iResult, 0);
        ret = ReadFile(hI2C, output, bytes, &iResult, 0);

    Some interestings things (that to be honest I'm not sure if they are significant or not):

    1. When I don't get an ACK I get a dump of the value of all the registers, including: I2C: CON = 0x8200. This register doesn't have the MST bit set.

    2. I can't read from these registers by putting in the address found in the TI reference manual. I've been able to read from all the other registers I've tried. Including the I2C1 registers at 0x48070000, but trying to read from 0x48072000 throws a Data Abort exception.


     

    What am I missing?

    chad.grant
    New Member
    New Member
    Posts:18


    --
    22 Sep 2015 05:36 PM
    I tried accessing the I2C2 registers through Logic Loader and get an Unhandled Exception:

    losh> x /h 0x48072014
    0x48072014
    Unhandled Exception:
    exception mode: abort
    fsr: 0x00001048 far: 0x48072014

    **UNRECOVERABLE ERROR**
    There was a memory access exception at 0x48072014 of type 'extern fetch1'
    this may be due to an access to an invalid memory region,
    unaligned access, or a problem with the current memory map.
    Please check the memory layout section of your processor manual.
    For information about the active memory map type 'info cpu'.

    r00: 00000001 r01: 80083d74 r02: 00000001 r03: 00000000
    r04: 00000000 r05: 48072014 r06: 00000000 r07: 00000002
    r08: 48072014 r09: 00000008 r10: 00000000 r11: 80086888
    r12: 80083d74 sp: 80086834 lr: 8000e9a0 pc: 8000e9ec
    spsr:60000153 cpsr:600001d7
    bt: sp: 80086784 (stack: 80083dd4 - 80086dd4)
    0: fp:800867a8 + 36 80005d38() called from: 800867b4
    1: fp:800867ec +939608024 60000143() called from: 8000089c
    (fp:800867ec->48072014, sp:80086888)


    Is this an error with logic loader or is there something wrong with my DM3730 SOM?

    I've also noticed Unhandled Exceptions when doing other things like "ifconfig sm0 dhcp"
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    22 Sep 2015 10:26 PM
    Chad,

    What version of Logic Loader are you using?

    I am not seeing any errors when using 'ifconfig sm0 dhcp'.

    *****************************************************************

    LogicLoader

    (c) Copyright 2002-2013, Logic PD, Inc. All Rights Reserved.

    LoLo Version: 2.5.3
    SOM Model Number: SOMDM3730-10-2782IFCR-A
    SOM Part Number: 1017318
    SOM Serial Number: 1111M01833

    *****************************************************************

    losh> ifconfig sm0 dhcp
    Waiting for link to come up... up
    Starting DHCP on sm0 ...
    losh>




    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    22 Sep 2015 10:26 PM
    Chad,

    Try this code for initializing the I2C2 port in Logic Loader.

    
    # $addr is source I2C address
    # $reg is the internal register address
    # $dat = Data to write
    
    addr=0x48
    reg=0x40
    dat=0x08
    
    
    # Write I2Ci.I2C_PSC[7:0] PSC (prescaler)
    w /h 0x48072030 0x0004 #I2C_PSC
    
    # Write I2Ci.I2C_SCLL
    w /h 0x48072034 0x0b12 #I2C_SCLL
    
    # Write I2Ci.I2C_SCLH
    w /h 0x48072038 0x0d0A #I2C_SCLH
    
    # Write I2Ci.I2C_OA2
    w /h 0x48072028 0x400e #I2C_OA2
    
    # Set I2Ci.I2C_CON[15] I2C_EN bit to 1 (enable module)
    x /h 0x48072024 
    I2C_CON_val = $@ | 0x8000
    w /w 0x48072024 $I2C_CON_val
    
    # Write I2Ci.I2C_SA[9:0] SA bit field (master mode)
    if ($addr == 0 ) 
        echo "Set addr equal to the slave address of your I2C device and rerun the script."
    	exit 
    endif
    sa = $addr
    w /h 0x4807202c $sa
    
    # Write I2Ci.I2C_CNT[15:0] DCOUNT field (master mode)
    w /h 0x48072018 0x0002  #I2C_CNT    Length of 2 = one byte address, one byte data
    
    # Set CONTROL.CONTROL_PADCONF__[x] INPUTENABLE bit to 1
    # Configure I2C2_SCL
    x /w 0x480021bc
    scl = $@ & 0xFFFF
    scl = $scl | 0x01180000
    w /w 0x480021bc $scl
    
    # Configure I2C2_SDA
    x /w 0x480021c0
    sda = $@ & 0xFFFF0000
    sda = $sda | 0x0118
    w /w 0x480021c0 $sda
    
    
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    22 Sep 2015 10:27 PM
    After the port has been initialized, you can use this script to read the i2c2 port.

     
    #I2C1 base address is 0x48070000
    #I2C2 base address is 0x48072000
    #Bitrate is 100K bps to 400K bps
    #Fast/Standard speed mode
    
    
    #Read from an I2C register
    
    # $add is source I2C address
    # $reg is the internal register address
    
    # $val is the returned value
    
    #Have to first do a write of the register we are interested in, size must be 1
    w /h 0x48072014 0x0047 #I2C_BUF    Clear the TXFIFO
    x /h 0x48072014 
    w /h 0x4807202c $addr  #I2C_SA     Write the slave address $add
    x /h 0x4807202c 
    w /h 0x48072018 0x0001 #I2C_CNT    Length of 1 = one byte address
    x /h 0x48072018 
    w /h 0x48072024 0x8601 #I2C_CON    Enable port, High Speed, Master, TRX, STT
    x /h 0x48072024 
    sleep 5                #           Wait on I2C_SYS reset done
    x /h 0x48072010        #I2C_SYSS   See 0x0001 here
    x /h 0x48072024        #I2C_CON    See 0x8600 here
    w /h 0x48072024 0x8602 #I2C_CON    Enable port, High speed, Master, TRX, STP
    x /h 0x48072008        #I2C_STAT   See bit 14 or bit 4 set here, 0x5500 is Ok
                           #           Blat the transmit bytes, don't worry about FIFO space
    w /b 0x4807201c $reg   #I2C_DATA   Register address will be $reg
    
    sleep 5                #Pause after transmission
    w /h 0x48072008 0x5110 #I2C_STAT   Clear XDR, BB, BF and XRDY bits
    w /h 0x48072024 0x0000 #I2C_CON    Disable I2C port
    sleep 5                #Pause between transmissions
    
    #Now we do the read of the register data
    w /h 0x48072014 0x0047 #I2C_BUF    Clear the TXFIFO
    w /h 0x4807202c $addr  #I2C_SA     Write the slave address $add
    w /h 0x48072018 0x0001 #I2C_CNT    Length of 1 = 1 byte of data
    w /h 0x48072024 0x8401 #I2C_CON    Enable port, High Speed, Master, STT, TRX = 0 so receiving
    sleep 5                #           Wait on I2C_SYS reset done
    x /h 0x48072010        #I2C_SYSS   See 0x0001 here
    x /h 0x48072024        #I2C_CON    See 0x8600 here
    w /h 0x48072024 0x8402 #I2C_CON    Enable port, High speed, Master, TRX, STP
    x /h 0x48072008        #I2C_STAT   See bit 14 or bit 4 set here, 0x5500 is Ok
                           #           Blat the transmit bytes, don't worry about FIFO space
    
    x /h 0x4807201c        #           Read the data, written into $@ lolo variable					   
    val=$@
    
    sleep 50                #Pause after transmission
    w /h 0x48072008 0x5110 #I2C_STAT   Clear XDR, BB, BF and XRDY bits
    w /h 0x48072024 0x0000 #I2C_CON    Disable I2C port
    sleep 50                #Pause between transmissions
    
    echo "Value read from I2C register is $val"
    
    exit                   #End of script
    
    
    
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    22 Sep 2015 10:28 PM
    This script can be used to write to the I2C2 port.

     
    #TPS95650 is attached to I2C1
    #I2C1 base address is 0x48070000
    #I2C2 base address is 0x48072000
    #Bitrate is 100K bps to 400K bps
    #Fast/Standard speed mode
    
    # Write to an I2C register
    
    w /h 0x48072014 0x0047  #I2C_BUF    Clear the TXFIFO
    w /h 0x4807202c $addr   #I2C_SA     Write the slave address $add
    w /h 0x48072018 0x0002  #I2C_CNT    Length of 2 = one byte address, one byte data
    #Don't wait for busy bits to go away
    w /h 0x48072024 0x8601  #I2C_CON    Enable port, Fast/Standard Mode, Master, TRX, STT
    sleep 5                 #           Wait on I2C_SYS reset done
    x /h 0x48072010         #I2C_SYSS   See 0x0001 here
    x /h 0x48072024         #I2C_CON    See 0x8600 here
    w /h 0x48072024 0x8602  #I2C_CON    Enable port, Fast/Standard Mode, Master, TRX, STP
    #x /h 0x48072008         #I2C_STAT   See bit 14 or bit 4 set here, 0x5500 is Ok
                             #           Blat the transmit bytes, don't worry about FIFO space
    w /b 0x4807201c $reg    #I2C_DATA   $reg = I2C register to write
    w /b 0x4807201c $dat    #I2C_DATA   $dat = data to write
    sleep 5                 #Pause after transmission
    w /h 0x48072008 0x5110  #I2C_STAT   Clear XDR, BB, BF and XRDY bits
    w /h 0x48072024 0x0000  #I2C_CON    Disable I2C port
    sleep 5                #Pause between transmissions
    
    
    exit                   #End of script
    
    chad.grant
    New Member
    New Member
    Posts:18


    --
    23 Sep 2015 09:01 AM
    Hi bradb,

    Thanks for responding to this. I'm using LoLo 2.5.3. ifconfig sm0 dhcp will return and assign an IP address, but within 5 or 10 seconds it will raise an Unhandled Exception, as can be seen here:

    
    *****************************************************************
    
                             LogicLoader
    
     (c) Copyright 2002-2013, Logic PD, Inc. All Rights Reserved.
    
     LoLo Version:      2.5.3
     SOM Model Number:  SOMDM3730-10-1782IFXR-D
     SOM Part Number:   1023928
     SOM Serial Number: 2414M00680
    
    *****************************************************************
    
    losh> ifconfig sm0 dhcp
    Waiting for link to come up... up
    Starting DHCP on sm0 .
    losh>
    Unhandled Exception:
    exception mode: abort
    fsr: 0x00000001 far: 0x80061855
    
    **UNRECOVERABLE ERROR**
    There was a memory access exception at 0x80061855 of type 'alignment1'
    this may be due to an access to an invalid memory region,
    unaligned access, or a problem with the current memory map.
    Please check the memory layout section of your processor manual.
    For information about the active memory map type 'info cpu'.
    
    r00: 80061857 r01: 00000012 r02: 00007506 r03: 80061855
    r04: 00000000 r05: 00000000 r06: 00000661 r07: 000005c8
    r08: 80061855 r09: 80087d6c r10: 00000099 r11: 8008af5c
    r12: 800617f6 sp:  8008af50 lr:  80034bac  pc: 80034ad8
    spsr:20000153 cpsr:200001d7
    bt: sp: 8008aea0 (stack: 80087fe8 - 8008afe8)
     0: fp:8008aec4 +      36  80005d38() called from: 8008aed0
     1: fp:8008af08 +  169651  20000143() called from: 8000089c
    (fp:8008af08->00000000, sp:8008af5c)
    


    Thanks for the scripts, they look similar to the ones that are found in AN535 (i2c2read.losh and i2c2write.losh). I couldn't get them to work because reading/writing to any of the I2C2 registers causes an exception:
    
    losh> addr=0x48
    losh> reg=0x40
    losh> dat=0x08
    losh> w /h 0x48072030 0x0004
    writing: (/h) *48072030 = 00000004
    
    Unhandled Exception:
    exception mode: abort
    fsr: 0x00001848 far: 0x48072030
    
    **UNRECOVERABLE ERROR**
    There was a memory access exception at 0x48072030 of type 'extern fetch1'
    this may be due to an access to an invalid memory region,
    unaligned access, or a problem with the current memory map.
    Please check the memory layout section of your processor manual.
    For information about the active memory map type 'info cpu'.
    
    r00: 00000024 r01: 80083d74 r02: 80086494 r03: 00000004
    r04: 00000004 r05: 00000004 r06: 48072030 r07: 00000000
    r08: 800868e4 r09: 80086f54 r10: 00000004 r11: 800868d8
    r12: 80083d74 sp:  80086894 lr:  800102a0  pc: 800102cc
    spsr:60000153 cpsr:600001d7
    bt: sp: 800867e4 (stack: 80083dd4 - 80086dd4)
     0: fp:80086808 +      36  80005d38() called from: 80086814
     1: fp:8008684c +    -152  60000143() called from: 8000089c
    (fp:8008684c->00000004, sp:800868d8)
    


    I'm starting to wonder if I just have a bad SOM.
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    23 Sep 2015 12:43 PM
    Chad,

    I am not sure on the 'ipconfig sm0 dhcp' question. I grabbed a board similar to yours and still don't see that issue.

     
    *****************************************************************
    
                             LogicLoader
    
     (c) Copyright 2002-2013, Logic PD, Inc. All Rights Reserved.
    
     LoLo Version:      2.5.3
     SOM Model Number:  SOMDM3730-10-1782JFIR-A
     SOM Part Number:   1017377
     SOM Serial Number: 2211M00170
    
    *****************************************************************
    
    losh> ifconfig sm0 dhcp
    Waiting for link to come up... up
    Starting DHCP on sm0 ...
    losh>
    


    As for the I2C2 scripts, I verified I also see similar issues. After further investigating I recalled there was additional support added to LOLO 2.5.x which gives users access to I2C1 and I2C2 ports without having to use the scripts provided earlier.

    Run this command to see the supported devices.

     
    losh> ls /dev/
      S  :                              id0        0
      S  :                              pm0        0
      S  :                             i2c0        0
      S  :                             i2c1        0
      S  :                            ata0d        0
      S  :                            ata0c        0
      S  :                            ata0b        0
      S  :                            ata0a        0
      S  :                             ata0        0
      S  :                          flash0d        0
      S  :                          flash0c        0
      S  :                          flash0b        0
      S  :                          flash0a        0
      S  :                           flash0  8388608
      S  :                             null        0
      S  :                            uart0        0
      S  :                          sdmmc0d        0
      S  :                          sdmmc0c        0
      S  :                          sdmmc0b        0
      S  :                          sdmmc0a        0
      S  :                           sdmmc0        0
      S  :                           nand0d        0
      S  :                           nand0c        0
      S  :                           nand0b        0
      S  :                           nand0a        0
      S  :                            nand0        0
    


    Device i2c0 is for I2C1 port and device i2c1 is for I2C2 port.

    Below are commands using the /dev/pm0 device which accesses the PMIC over the I2C port. Hopefully the information below will help you develop the commands needed for accessing your device on the I2C2 port within Logic Loader.

     
    -  Read the pm0 device:
    			losh> x /w 0x004a00ee 1 /dev/pm0
    		-  Verify that the location was read and does not contain “nand”
    		-  Write the word “nand” to the pm0 device
    			losh> w /w 0x004a00ee 0x646e616e /dev/pm0
    		-  Read the pm0 device:
    			losh> x /w 0x004a00ee 1 /dev/pm0
    


    Additional examples can be seen below.

     
    info device /dev/pm0 - Information on the ADC values and main battery charge state
    
    w /b 0x9b 0xff /dev/pm0 - Write to the PMIC main battery charger to raise the current to the max.
    
    w /b 0x004b006d 0x1c /dev/pm0 - Write to the PMIC backup battery charger to enable it with the lowest setting
    
    w /b 0x004b006d 0x1f /dev/pm0 - Write to the PMIC backup battery charger to enable it with the highest setting
    
    


    Regards,
    Brad
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    23 Sep 2015 01:20 PM
    Chad,

    Concerning the unhandled exception seen when using the 'ipconfig sm0 dhcp' command, does this error occur when using the SOM on the development baseboard that comes within the development kit or when using the SOM in your design?

    Regards,
    Brad
    chad.grant
    New Member
    New Member
    Posts:18


    --
    23 Sep 2015 01:53 PM
    It happens on our own hardware. This is hardware that was originally created for the iMX31 SOM, and it worked great with that card engine. With the end of life of the iMX31 we are trying to move to the DM3730. I was hoping to get a development kit, but there was a longer lead time to get one so we decided to just get a card engine and see how it goes. So far I've been able to get GPIO, interrupts, the display, and memory mapped io working, but this I2C is giving a lot of problems.

    I've stepped back to logic loader just so I can see if I can get anything on the lines, but really ultimately I just need it to work in WindowsCE. I think it is strange that both in logic loader and WinCE I can access the I2C1 registers, but I get errors if I try to access the I2C2 registers.

    I'm playing with the commands you just posted. I'll post anything that I can get working.
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    23 Sep 2015 02:13 PM
    Chad,

    O.k.  Yes, the i.MX31 uses the LAN 91C117 10/100 Base-T Ethernet controller and the DM37x SOM-LV uses the LAN 9221 10/100 Base-T Ethernet controller.  

    The suggested magnatics for the LAN 9221 Ethrenet controller can be found here.

     

    It might be worth comparing your board's Ethernet interface to the SOM with the DM37x SOM-LV baseboard design.  The DM37x SOM-LV baseboard schematics (page 04-Ethernet) shows a table with different recommended resistor population options when using the LAN 9117 versus the LAN 9221 Ethernet controllers.

     

    Thanks,

    Brad

    chad.grant
    New Member
    New Member
    Posts:18


    --
    24 Sep 2015 03:42 PM
    Brad,

    Thanks for the info about the ethernet. Our electrical engineer is taking a look at it.

    I was afraid that my SOM was bad so yesterday I ordered another one from digikey and had it overnighted (A SOMDM3730-10-2782IFCR-D this time). I'm seeing all the same issues, so I guess my first one was probably OK.

    Going through your instructions regarding the pm0 device I was able to detect activity on the I2C1 (i2c0) device. I could detect it if I wrote to pm0 or even i2c0. I connected a logic analyzer to TP12 and TP13 to detect this activity. But trying to write to or examine I2C2 (i2c1) I can't detect anything on those lines.

    I still think it interesting that I can read/write I2C1 registers (0x48070000) but not I2C2 registers (0x48072000).

    Can you confirm that the I2C2 works on any of your boards? Ultimately I need this to work on WinCE, but even if you have logic loader information it may be helpful to try and get it started.

    Thanks,
    Chad
    bradb
    Basic Member
    Basic Member
    Posts:203


    --
    24 Sep 2015 07:55 PM
    Chad,

    That was good information. Since you were able to access I2C1 but not I2C2 registers I thought it best to look for I2C2 specific registers in the Power/Clocks chapter. In doing so I found the following control bits specific to the I2C2 interface that appears to have been cleared.

    Controls the modules interface clock activity.
    0x48004A10 PRCM.CM_ICLKEN1_CORE[16] EN_I2C2

    Controls the module functional clock activity.
    0x48004A00 PRCM.CM_FCLKEN1_CORE[16] EN_I2C2

    
    *****************************************************************
    LogicLoader
    (c) Copyright 2002-2011, Logic PD, Inc. All Rights Reserved.
    LoLo Version:      2.5.2
    SOM Model Number:  SOMDM3730-10-1782JFIR-A
    SOM Part Number:   1017377
    SOM Serial Number: 2211M00170
    *****************************************************************
    losh> x /w 0x48004A10
    0x48004a10  0100a042                             B...
    losh> x /w 0x48004A00
    0x48004a00  0100a000                             ....
    losh> w /w 0x48004A10 0x0101a042
    writing: (/w) *48004a10 = 0101a042 
    

    losh> w /w 0x48004A00 0x0101a000 writing: (/w) *48004a00 = 0101a000 losh> x /w 0x48072000 0x48072000 00400040 @.@. losh>



    After setting the clock control bits I am able to read the I2C2 Rev register without problems using the following command. This is a read-only register so I did not attempt a write to this register.

    x /w 0x48072000


    chad.grant
    New Member
    New Member
    Posts:18


    --
    25 Sep 2015 10:40 AM
    Brad,
    You are right, with those register modifications I can finally write to the I2C2 registers! The other thing we are just now noticing is that the voltage of the I2C coming off the card engine is 1.8V on the DM3730 SOM, but it was 3.3V on the iMX31 SOM. We have a level shifter that doesn't go down to 1.8V so that is the other things that is causing problems.
    You are not authorized to post a reply.