• 0

AD2: how to avoid I2C conflicting with DIOs?


Question

Hello,

I wrote a Python script to use AD2 as I2C master, controlling two additional digital pins at the same time.

I2C is set as per example:

dwf.FDwfDigitalI2cRateSet(hdwf, c_double(1e5)) # 100kHz
dwf.FDwfDigitalI2cSclSet(hdwf, c_int(0)) # SCL = DIO-0
dwf.FDwfDigitalI2cSdaSet(hdwf, c_int(1)) # SDA = DIO-1

dwf.FDwfDigitalI2cClear(hdwf, byref(iNak))

While I though that setting DIO2 and DIO3 as outputs would no conflict with I2C:

#dwf.FDwfDigitalIOOutputEnableSet(hdwf, c_int(0x00C0))    
#dwf.FDwfDigitalIOOutputSet(hdwf, c_int(0x000C))            

But this is not what I observe... If I comment the DIOs setting, no prob with I2C...

Where am I wrong?

Thank you!

 

 

 

Link to post
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Hi @Walter76

With the default clock-stretching option the I2C uses the least significant IOs (DIO 0-9) for state machine, "ROM logic".

You could use the higher DIO lines (10-15) :
dwf.FDwfDigitalIOOutputEnableSet(hdwf, c_int(0xFC00))    
dwf.FDwfDigitalIOOutputSet(hdwf, c_int(0xFC00)) 

or disable the clock stretching with
dwf.FDwfDigitalI2cStretchSet(hdwf, c_int(0))

Also note that you have set output-enable and high-value to different bits, 0x00C0 and 0x000C

image.png.b56ebd6f87dc574622d9f4a6de96598e.png

Link to post
Share on other sites
  • 0

@attila I am trying something similar.  One issue I keep running into is that when I disable the clock stretching, I no longer have data on my I2C lines.

dwf.FDwfDigitalI2cStretchSet(hdwf, c_int(0)) # Disable clock stretching
dwf.FDwfDigitalI2cRateSet(hdwf, c_double(5e4)) # 50kHz
dwf.FDwfDigitalI2cSclSet(hdwf, c_int(0)) # SCL = DIO-0
dwf.FDwfDigitalI2cSdaSet(hdwf, c_int(1)) # SDA = DIO-1
dwf.FDwfAnalogIOChannelNodeSet(hdwf, c_int(0), c_int(2), c_double(0x0003)) # Enable IO Pulls
dwf.FDwfAnalogIOChannelNodeSet(hdwf, c_int(0), c_int(3), c_double(0x0003)) # Enable pull-up for I2C ports
dwf.FDwfDigitalI2cClear(hdwf, byref(iNak))

If I comment out the first line, I can see the data on the I2C lines.  When I execute the first line, the I2C lines stay HIGH (pulled up) with no data on them.

Is there a specific order to disable the clock stretching and enable the pull-ups?

Thank you!

Link to post
Share on other sites
  • 0

Using Waveforms, this is the signal when clock stretching is enabled:

image.png.6faf34e9cb79b408b348153c66340a8d.png

Also using Waveforms, this is the signal when clock stretching is disabled:

image.thumb.png.cb6252bda70f34916c3c240eedd2810a.png

Here is the configuration for Waveforms:

image.png.dac9490b4a580a30353e45a5ee0949fe.png

Using the python script, with clock stretching enabled, I get the following signal (trigger on address 0x3F, SCL = CH0, SCA = CH1)

image.png.fcec2a51a1bce1acfa2dd68b385e1f11.png

When I disable clock stretching in the python script, the scope does not trigger on an address.

image.thumb.png.208f7a3d51fb7d1dbd735b3280cb8315.png

Please let me know if there is any additional information that I can provide to help address this!

And again, Thank you!

Link to post
Share on other sites
  • 0

@attila, I am still running into the issue, using the python script, where I disable clock stretching and I do not see any toggling on the I2C lines at all.  I have configured DIO ports 24 (SCL) and 25 (SDA) (ports 0 and 1 for the script).  With clock stretching enabled, I see the write and read commands transmitted on the lines.  With clock stretching disabled, nothing shows up on the scope.  The scope is configured to trigger on the first falling edge of the SDA line.

I am including the python test script along with the command window responses, one with stretching enabled and one with stretching disabled.  I'm expecting both responses to be the same.  What am I missing?  Thanks!

Here is the python test script:

"""
   DWF Python Example
   Author:  Digilent, Inc.
   Modified:  David L. Johnson
   Revision:  2021-03-12

   Requires:                       
       Python 2.7, 3
"""

from ctypes import *
import math
import sys
import time

if sys.platform.startswith("win"):
    dwf = cdll.LoadLibrary("dwf.dll")
elif sys.platform.startswith("darwin"):
    dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
else:
    dwf = cdll.LoadLibrary("libdwf.so")

hdwf = c_int()

print("Opening first device")
#dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
# device configuration of index 3 (4th) for Analog Discovery has 16kS digital-in/out buffer
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))

if hdwf.value == 0:
    print("failed to open device")
    szerr = create_string_buffer(512)
    dwf.FDwfGetLastErrorMsg(szerr)
    print(str(szerr.value))
    quit()

print("Configuring I2C...")

iNak = c_int()

dwf.FDwfDigitalI2cStretchSet(hdwf, c_int(0)) # Disable clock stretching
dwf.FDwfDigitalI2cRateSet(hdwf, c_double(5e4)) # 50kHz
dwf.FDwfDigitalI2cSclSet(hdwf, c_int(0)) # SCL = DIO-0
dwf.FDwfDigitalI2cSdaSet(hdwf, c_int(1)) # SDA = DIO-1
dwf.FDwfDigitalI2cClear(hdwf, byref(iNak))
if iNak.value == 0:
    print("I2C bus error. Check the pull-ups.")
    quit()
#time.sleep(.1)

rgTX = (c_ubyte*6)(0x04,0x00,0x01,0x00,0x30,0xA5)
rgRX = (c_ubyte*27)()

#                                8bit address  
dwf.FDwfDigitalI2cWriteRead(hdwf, c_int(0x3F<<1), rgTX, c_int(6), rgRX, c_int(27), byref(iNak)) # write 6 bytes restart and read 27 bytes
if iNak.value != 0:
    print("NAK "+str(iNak.value))
print(list(rgRX))

dwf.FDwfDeviceCloseAll()

 

Here is the response with clock stretching enabled:

C:\...\Python>I2C_Test.py

Opening first device

Configuring I2C...

[26, 0, 0, 2, 2, 5, 0, 33, 0, 19, 144, 3, 11, 128, 164, 121, 175, 131, 29, 78, 95, 128, 30, 0, 245, 1, 99]

 

Here is the response with clock stretching disabled:

C:\...\Python>I2C_Test.py

Opening first device

Configuring I2C...

NAK 1

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Link to post
Share on other sites
  • 0

The first issue I am running into is that I do not see the TX data or clock when I use an oscilloscope on the SDA and SCL lines when clock stretching is disabled.  As soon as I enable clock stretching, I see the clock and data signals.  It appears that as soon as I disable clock stretching, I disable I2C completely.  I posted images of the scope response on Sunday.  The first image shows the address byte being transmitted with no ACK.  The second image shows that the SDA and SCL lines do not change state at all.  The first image was taken with clock stretching enabled, while the second image was taken with clock stretching disabled.

When I use Wafeforms, everything works.  It's when I try to do this programmatically that I am having problems.

Link to post
Share on other sites
  • 0

Hi @DavidLee1997

I will post a new software version fixing this issue tomorrow.

Thank you for the observation.

However I see the problem a bit differently...
Here the I2C is generated with one device using WF API and it is captured with another device using the WF app.
In the first pic the SDA is constant low due to a bug in the API with no clock stretching implementation.
In the second pic it is fixed.

image.thumb.png.d2a82a413189dd8681f624f616ed12b9.png

image.thumb.png.c9f300dea337648ee6e24be0386cc31a.png

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now