Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

I2C Bus Problem - Debugging

I2C I2C bus

  • Please log in to reply
39 replies to this topic

#1 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 18 February 2014 - 11:36 PM

Hey Everyone,

 

I've been trying to resolve an I2C issue. I've got an N2 with 4.2.2.2. Briefly, I was using a DS1307 and 24c32 Module with built in pull-ups. I hooked it up and the DS1307 worked right away with some code from here:

http://netduinohelpe...dware/DS1307.cs

 

Pretty easy. I wrote some drivers for the EEPROM chip and that worked as well...All fine until here.

 

I've been testing some other I2C devices, (ATtiny85 and ATtiny84 with I2C Slave code), and still debugging them, but testing communication with I2C with Netduino. I was able to detect the devices on the bus with an Arduino I2C scanner, so I moved to Netduino. 

 

After moving back to Netduino, I first hooked up the SDA/SCL swapped. Fixed that and still had a few bugs and exceptions on the read/write commands. I cleared them up somehow and it was kind of working..by kind of, I mean i would boot up and I would get an exception. I would reboot and it would work. Slowly, I would get more exceptions and now I get nothing on the Netduino I2C bus. :blink:

 

I read a lot of threads here where people are discussing some issues about the current capability and pull-ups on the Netduino and I2C. More fiddling with no luck. I swapped only the SDA and SCL lines back to Arduino and it the devices work just fine. Move the lines back to Netduino, and it throws exceptions. I tried the devices individually and no luck. 

 

Is it possible that the SDA and SCL pins went bad? For example, I don't remember doing this, or if I did it at all, but If I hooked up the SDA and SCL pins directly to 5V, would that destroy them?

 

Is there any code or a proper way to test the pins?

 

I don't have an Oscope yet or a logic analyzer, but I might try this: http://codinglab.blo...d-parallax.html



#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 19 February 2014 - 01:00 AM

Hi gizmo, If you connect an LED between the SDA (or SCL) pin and GND, you should be able to turn it on/off via the pins. If that works, connect it between the SDA (or SCL) pin and 3.3V and you should get inverted state on the LED. With I2C, you're only driving pins _low_. The SDA/SCL pins should be plenty strong to pull-down against any normal pull-up resistor. The bigger issue is usually software logic...or that your pull-ups are sized properly. One final note: don't enable the internal pull-ups on the SDA/SCL pins when using I2C. You want external pull-ups on those pins, not internal pull-ups. The internal pull-ups are too weak unless you're doing very slow I2C communication. Finally...a logic analyzer (including using a second board like that as a pseudo-analyzer) should help diagnose. Chris

#3 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 19 February 2014 - 04:30 AM

[color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]If you connect an LED between the SDA (or SCL) pin and GND, you should be able to turn it on/off via the pins. If that works, connect it between the SDA (or SCL) pin and 3.3V and you should get inverted state on the LED.[/color]

 

Works! (On a side note, that's neat!...An OutputPort.Write(false) will sink current.)

Here's the code: 

public static void Main()        {            OutputPort sda = new OutputPort(Pins.GPIO_PIN_SDA, true);            OutputPort scl = new OutputPort(Pins.GPIO_PIN_SCL, true);            while (true)            {                sda.Write(true);                scl.Write(true);                Thread.Sleep(250);                sda.Write(false);                scl.Write(false);                Thread.Sleep(250);            }        }

[color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]With I2C, you're only driving pins _low_. The SDA/SCL pins should be plenty strong to pull-down against any normal pull-up resistor. The bigger issue is usually software logic...or that your pull-ups are sized properly.[/color]

It's funny...As I mentioned, nothing in my setup/code changed and it stopped working after I started fiddling with the ATTinys. I will try again with a new project in VS.

 

[color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]One final note: don't enable the internal pull-ups on the SDA/SCL pins when using I2C. You want external pull-ups on those pins, not internal pull-ups. The internal pull-ups are too weak unless you're doing very slow I2C communication.[/color]

How would internal pull-ups get enabled? I'm just using the I2C calls from netmf. Is there somewhere else to make sure they're disabled?

 

[color=rgb(40,40,40);font-family:helvetica, arial, sans-serif;]Finally...a logic analyzer (including using a second board like that as a pseudo-analyzer) should help diagnose.[/color]

 

So, after running the code above and seeing that SDA and SCL are responsive, I went back to the original DS1307 code and it magically ran just fine. Did the running code above have anything to do with this?? seems so...

 

I hooked it up to this little arduino scope and the results are below. [color=#ff0000;]Red[/color] is SCL and [color=#0000ff;]Blue[/color] is SDA. the resolution isn't great, but you can see the SCL line clocking and also where the SDA line is held low. This is the first few bits of the I2C transaction... (The software graphing isn't great and the digital graph option wasn't working, so I had to take the analog version.)

 

Here's the weird part. When I connect the ATTiny to the bus and rerun the code, the DS1307 transaction fails. I pull it off the bus and reboot the Netduino and then the DS1307 works again. I suspect something funny is happening with the ATtiny, but funny how it seemed to work at some point and no complaints on the code from the Arduino forums.

Posted Image

 

 

Thanks Chris!! I thought the I2C was dead! Phew!



#4 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 19 February 2014 - 06:21 AM

It still seems to get "locked up" every now and then.. and I don't have an exact solution on getting it the I2C to work again. Even after a few reboots of only using the DS1307 RTC code only. I've played with dropping the speed down to 10kHz, but nothing specific works to get it back.

 

 

I spent some time and found a better Arduino Logic Analyzer and UI. Logic Sniffer OLS. Results are pretty good:

Posted Image

 

Posted Image

 

Surprisingly, it seems to look right. This code is for reading a 24c32 EEPROM. The first two writes are addressing which byte in the memory register to read. In my case, 3, then it spits back 6. I previously stored that value to the eeprom. I write a little loop to write to the first 20 bytes in the EEPROM and write 2*LocationByte. hence 3 and 6.  I don't know what what 160 and 161 are and I don't see where it addresses the 24c32, Maybe I'm not getting all the data captured. It's address is 0x50. Still some kinks with triggering on this analyzer. 

 

I'm still having problems with the bus.

 

I'm off to bed!



#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 19 February 2014 - 06:26 AM

Hi gismo, When you say "locked up", do you mean that I2C calls are never returning? Or are you seeing something else? If the drivers are literally locking up, that's something we want to address. Chris

#6 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 19 February 2014 - 05:22 PM

Hi gismo, When you say "locked up", do you mean that I2C calls are never returning? Or are you seeing something else? If the drivers are literally locking up, that's something we want to address. Chris

Yes, the calls aren't returning. They're timing out.

 

I'm using the term "locked up" when I2C calls work and then I make some changes to my code and/or I2C bus and reload the new code and then the I2C doesn't want to work. Then, I revert the code and hardware setup and it still won't work.Then, I just try different things like unplugging, loading the SDA/SCL blinking LED code, etc and then reloading the I2C code and then the I2C will work temporarily...It's somewhat cyclic. I'm still trying to pinpoint it. I want to see what's going on the line when it fails. 

 

Timeout here:

            if (Clock.Execute(transaction, TimeOutMs) == 0) //Timeout            {                throw new Exception("I2C transaction failed");            }


#7 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 19 February 2014 - 11:15 PM

Hi gismo, So sorry; now I'm confused. The calls are both not returning (i.e. the board locks up forever) and also timing out (the calls return with exceptions or with no data)? :) If the function calls are never returning (the board locks up hard, no more code executes, you have to reset the board to make anything happen) then we need to find a way to repo and dig into that. Another thing to be aware of: I2C devices are generally state machines. They should "reset" when you move them between systems, power cycle, etc. -- but there's always a chance that they're just not responding to I2C messages. Chris

#8 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 20 February 2014 - 03:22 PM

The board doesn't lock up. The lock up that I'm referring to is the I2C specifically won't work until I just fiddle with some things and reboot several times then it works again. When I start testing the ATtiny, it happens. Then I have to go through the above steps to somehow get I2C to work again.

 

For example, while debugging, and when the I2C Execute command fails, I Break the code and move the line back up to execute in VS to try the command again. it fails again. I also put a break point there so I can capture the action with the logic analyzer.

 

RE state machines, the power cycle thing is interesting..The DS1307 module has a battery backup, so something is always on... I2C is hot swappable on the bus...So my ATTiny it always reset when remove and insert as it's a sole chip. I'm not sure this is the problem. 

 

Here's a shot from the Arduino based logic analyzer. Capture works better to slow down the I2C to 50kHz. This is from a 24C32 EEPROM read. 

 

Posted Image

 

I think there's some issues with the ATtiny doing something weird to the bus and other devices.



#9 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 25 February 2014 - 01:02 AM

OK, did a little more debugging and sifting through the code again, and I don't think it shouldn't be this difficult. I went back to the Arduino and setup a Duemilanove as an I2C master. I just ran a little loop that sniffs the buffer via incrementing addresses and prints out if a device is found and then I just do a read from the ATTiny running the slave code at 0x05. This works without any errors and I can freely disconnect and reconnect devices from the bus while the code is running. When I swap the setup back to the Netduino, one for one- 5v, ground, SDA, SCL and run my code, I typically get an exception when reading the ATTiny@0x05. If I break the code, move back up to the i2c execute line pull the attiny out of the breadboard, and pop it back in, and re-run it, and sometimes it'll start reading and won't throw an exception. Usually I have to try it about 5-7 times before it'll start reading. I've got the timeout set to 1000ms. I'll try bumping it up. Another thing, when it's throwing exceptions, the logic analyzer isn't even triggered. The SDA Line doesn't pull low. I'm looking for other ways to debug what's going on...

#10 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 25 February 2014 - 04:32 PM

This is what the analyzer shows when I get the ATTiny85 to work. It should Write the address and then Read the next two bytes from the ATTiny. The analyzer shows some "garbage", but oddly enough I get the correct data returned into the Netduino. 100, and 200. I'm not really sure what's happening.

 

Posted Image



#11 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 26 February 2014 - 01:34 AM

Hi gismo, What does the logic analyzer look like when you _don't_ get the ATTiny85 to work? Chris

#12 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 26 February 2014 - 02:39 AM

When the ATTiny isn't working... SDA and SCL Remain high and it doesn't seem to trigger the logic analyzer. So I'm just getting a high signals. Another detail..When I remove the ATTiny from the bus, dispose it, and try jump code to another device on the bus and the bus fails, the logic analyzer shows the same. Both lines stay high. Sometimes rebooting and only trying a 24c32 on the bus I will get the same results. Rebooting and fiddling with the bus device(s), and it'll magically work again. Thanks!

#13 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 27 February 2014 - 03:45 AM

Hey Chris, I came across this thread: http://forums.netdui...c-lockup-issue/ Did this ever make it into 4.3?

#14 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 27 February 2014 - 09:36 AM

Hi gismo,

We will be digging into I2C more deeply in a follow-up firmware release for this spring.

The best circumstance is if we can reproduce something consistently.

If we can't get a good repro, then a peripheral reset is something that can be theoretically be added in the core. We just need to set aside some time to help avoid any unintentional side effects: the STM32 peripheral features can be a bit particular about how things are initialized, when peripheral resets occur, etc.

Chris

#15 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 27 February 2014 - 01:59 PM

Hey Chris,

As of now, It seems I'm out of options and I'm happy to be a guinea pig and test it in my setup. Have you made the N2 4.3 source available to download yet?

Is there a straight forward way I could test the modification from that thread? Or does the firmware need to be recompiled? (It seems a little daunting as I haven't done it before).

I found this tutorial: http://wiki.netduino...to-GCC-4-6.ashx

Any other references or a step by step for N2?

I'd really love to try it out and hopefully either rule out this option or resolve it :)

Thanks!

#16 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 27 February 2014 - 02:54 PM

Hi gismo,

Here is the forum thread for the 4.3.1 source code:
http://forums.netdui...es-source-code/

You would need to compile the firmware with the custom code. If you need help compiling with GCC, let's create a thread for that and see if we can provide a good public set of instructions/compiler files.

In the meantime...if you do apply that modification to custom firmware and everything starts working...please let us know. If we have an in-field test case (running on a Netduino 2/Plus 2 board), we can work with you to test everything and get updated code into the core.

I really appreciate your sleuthing skills on this. Thanks, gismo!

Chris

#17 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 27 February 2014 - 03:57 PM

Thanks Chris! Thanks for that 4.3 source link(that was right under my nose!)

I'll give it a shot and start a new thread regarding compiling custom firmware. I'm looking forward to giving it a go.

Chad

#18 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 16 March 2014 - 03:12 PM

Hey Chris,

 

Re-compiling has become quite the task and have since been unable to figure it out with GCC. I wanted to rule out some other options, so I picked up a Fez Cerb 40 II from GHI and reading the ATtiny via I2C is successful without any hickups on the bus. Now, I'm a little more convinced that I think there is some I2C bug with the Netduino firmware. Any chance you could investigate a little further and maybe push out an update sooner?..I'm still partial to my Netduino... :)

 

Thanks!

DffKWUl.jpg



#19 Frode

Frode

    Advanced Member

  • Members
  • PipPipPip
  • 202 posts
  • LocationNorway

Posted 17 March 2014 - 09:43 AM

I've also tested my I2C device, which is flaky on a Netduino Plus 2, on an Arduino Leonardo and it works just fine there. So I agree with gismo that there is an I2C issue on the Netduino (or in the I2CBus.cs code I got from another thread in this forum). 



#20 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 17 March 2014 - 09:43 PM

Update: Thanks to CW2 for getting GCC compiler to work to compile 4.3 firmware, I was able to make the changes to the I2c code based on this thread: http://forums.netdui...-issue/?p=45679

 

 

 

I was able fix my problem by modifying the firmware from the source that is available for download, I think it is 4.2.2.0, and made some simple modifications.  I do not have my debugger yet so I cannot say what the exact state of the I2C peripheral was however I have gone through the steps of my previous debugging to verify that this does fix the issue that I was seeing.

 

In DeviceCodeTargetsNativeSTM32DeviceCodeSTM32_I2CSTM32_i2c_functions.cpp

 

function : I2C_Internal_Initialize()

I added :

 

        I2Cx->CR1 = I2C_CR1_SWRST;

 
on the line before :
 
        I2Cx->CR1 = I2C_CR1_PE; // enable peripheral
 
function : I2C_Internal_Uninitialize()
I added :
 
    I2Cx->CR1 = I2C_CR1_SWRST;
 
on the line before :
 
    I2Cx->CR1 = 0; // disable peripheral
 
 
My modification to I2C_Internal_Uninitialize() is redundant but I like the idea of leaving it in a known state when everything is done.
 
Can this change be merged into the next firmware release?

 

Assuming I was successful at making the changes and then compiling, I've installed the updated firmware and, sadly, still see the same problem...Intermittent, at best, response on the I2c bus.

 

 

That file lives in two places:

C:\MicroFrameworkPK_v4_3\DeviceCode\Targets\Native\Netduino_STM32\DeviceCode\STM32_I2C\STM32_i2c_functions.cpp

and

C:\MicroFrameworkPK_v4_3\DeviceCode\Targets\Native\STM32\DeviceCode\STM32_I2C\STM32_i2c_functions.cpp

 

(I modified both)







0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.