This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problems with I2C communication between Stellaris Launchpad LM4F120 and MPU9150

Environment: CCS 5.2, Linux, target (master) Stellaris Launchpad LM4F120, slave device MPU-9150 breakout board from SparkFun.

I'm having a problem reading MPU9150 (Invensense IMU)  via I2C interface.  According to the MPU register map I should read 0x48 from reg 0x00, which is its ID.  I figured this would be the best way to get familiar with communicating to the MPU using I2C_Stellaris_API (from aBUGSworstnightmare).

Here's the code I'm using, which is similar to another post:

....

    I2CSetup(I2C0_MASTER_BASE, true);
    unsigned long rtn = I2CRegRead(I2C0_MASTER_BASE, 0x68, 0x00);
    UARTprintf("I2C received=0x%02x\n", rtn);
....

I've setup a 40MHz system clock, otherwise the rest of the code is typical.

The output I get is:

"I2C test ->I2C received=0x83", which is not what I'm expecting.  

I've connected a Link Instruments' MSO-19, USB scope with I2C mode, to the SDA/SCL  but I'm not sure its working.  I only seem to capture the pulse stream of 1 out of 4 runs.  I can attach a 3.4MB screen shot of an exchange if that will help but I'm not sure how appropriate it would be give image size.

According to the tag from the scope, 0x83 is also a NACK.  And, NACK seems to be part of the MPU's normal communication sequence.  Here's an excerpt from (MPU-Product Specification document, PS-MPU-9150A-00): 

"To read the internal MPU-9150 registers, the master sends a start condition, followed by the I C address and
a write bit, and then the register address that is going to be read. Upon receiving the ACK signal from the
MPU-9150, the master transmits a start signal followed by the slave address and read bit. As a result, the
MPU-9150 sends an ACK signal and the data. The communication ends with a not acknowledge (NACK)
signal and a stop bit from master. The NACK condition is defined such that the SDA line remains high at the
th 9 clock cycle. The following figures show single and two-byte read sequences."

I'm new to using I2C.  Are the read/write sequences the same for all I2C slaves?  Any idea what I might be doing or assuming wrong here? Would posting the 3.4MB screenshot help?

Update: The MPU-9150 id register's address is 0x75 and not 0x00.  I'm not getting the expected value.

Thanks

  • Hi Tim,

    well, you will have to deal with a 'real beast' in case of the MPU-9150! I know what I'm talking about: http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/664688.aspx

    I assume your MPU-9150 is connected correctly and is - in principle - working? Since you try to read from a Slave-ID = 0x68 = 0b1101000 your AD0 pin must be connected to GND. You can use the 'unsigned long I2CBusScan(unsigned long ulI2CBase)' routine to verify that your slave is ACK the address 0x68!

    PLS NOTICE: You should declare your variables before using it for the first time!

    I've tested this issue with correct results from my sensor:

    static unsigned char ucRegReadOrig = 0;

    ...

    I2CSetup(I2CSENSORBUS, true);

    ucRegReadOrig = I2CRegRead(I2CSENSORBUS, 0x68, 0x6B);

    This results in ucRegReadOrig = 0x40

    ucRegReadOrig = I2CRegRead(I2CSENSORBUS, 0x68, 0x75);

    This results in 0x68

    (with I2CSENSORBUS = I2C0_MASTER_BASE).

    All other register will read as 0x00 after Power-On.

    Place a breakpoint at your codeline 'UARTprintf("I2C received=0x%02x\n", rtn);' and watch the contents of 'rtn'. 

    aBUGSworstnightmare

  • aBugsWorstNightmare,

       My efforts to get the Stellaris Launchpad LM4F120 communicating with Sparkfun's MPU-9150 has been stop and go.  Do you have a blog where it might be more appropriate to discuss this topic?

    I've uncovered several significant bugs in the code from Sparkfun link.  Thanks

  • I've been getting mixed results when communicating between my Stellaris Launchpad LMF120 and slave (MPU-9150 breakout) and I'm now suspecting that the pull-ups built into the breakout board circuit are "conflicting" with the pull-ups possibly configured with the default I2C initialization.  The peripheral documentation doesn't specify what exactly it's doing to the pin type of SCL and SDA when calling GPIOPinTypeI2CSCL() and GPIOPinTypeI2C().   I plan to "get" the pintype of the SDA and SDL pins and print them out.   According to the breakout board schematic, there are 10K pull-ups in the circuit.

    Q1: Do  GPIOPinTypeI2CSCL() and GPIOPinTypeI2C() operations enable pull-up or pull-downs by default? I have not found this detail in any of the documentation.

    Q2: Assuming the answer is yes,  what is the best approach to overriding this setting?  Should I take on configuring all of the settings for SCL and SCA pins or follow current configuration operations with a call to override pintype using call to GPIOPadConfigSet()?

    I describe getting "mixed results" based on:

    - When i execute code that reads one register from slave I get the expected value, in several cases.  But, when i call mpu9160 api routines that perform several read/write operations to set bits, I don't get the expected result.  

    - When I write a value to a slave register I don't read back value I expect.

    - I've setup an arduino Mega 2650 with mpu9150 and I2C analyzer A LONG SIDE my Stellaris Launchpad with another mpu9150 and another I2C analyzer.  Except for compiler and I2C API  the software executing on both is nearly identical--After board target initialization stuff, I call the mpu9150 initialization() operation which sets three parameters in the IMU.     The I2C bus traffic should be similar if not identical, but only the Arduino setup generates the expected output.  The analyzer can't make sense of the stellaris' communication.  It's obvious from the waveforms that the Stellaris I2C bus traffic is much shorter

    Thanks


  • Feel your pain - but you have made progress - you should feel good about that.

    My belief is that you always require (and benefit) from external pull-up Rs.  The calls to both variants of GPIOPinType() do not cause pull-ups to be emplaced.  Do not over-ride w/ GPIOPadConfigSet() - do note that both "Bug" and earlier my I2C design post (targeting M4) succeeded nicely - minus any GPIOPadConfigSet().

    Suspect it would help us to better assist if you'd be so good as to supply actual code which worked.  (i.e. you read one register - obtain expected result)  This fact suggests that - your interconnect and set-up are mostly correct. 

    You're most troubled when calling the Slave's API routines - which appear to be multi-byte transactions.  (can't quite tell - from your writing)  Can you extract one of the simpler, such multi-byte transactions - and present it here?  (I've stared @ code for days - colleague sometimes goes, "Aha!" w/in minutes - always delightful!)

    Have you tried switching the remote Slaves - so that we have positive confirmation that this is primarily a Stellaris/code issue - and not a questionable Slave?  (you described as an Arduino - Slave "pair" worked - I'd like you to switch that Slave to the Stellaris...)

    Finally - do post data capture which illustrates, "can't make sense of Stellaris I2C communication."  Using a Stellaris 64 pin M4 MCU - our group executed a continuous sequence of read/write I2C transactions earlier today - and our transaction count passed 100K - without a "hiccup." 

    You must insure that both slave board and your Stellaris board are adequately powered - and ideally from the same source.  Stellaris I2C inputs may be more sensitive to noise and/or excess capacitance - which are less impacting to the simpler Arduino.  Interconnect length should be minimized - and there have been reports noting that your board's headers are somewhat "less than standard" (pins are too thin!) - an intermittent connection on either of your I2C lines could "exactly" cause your issues.

    One last "horror" involving your board - might your I2C pins be routed to other, interfering points on your board?  At least 2 pairs of pins are cross-connected (to maintain compatibility w/non ARM MCU) you must avoid these.  And - if possible - can you employ a different I2C pair - "just in case?"  (set-up config will change...)

    Good luck - hope something herein leads to success...

  • cb1- said:

    My belief is that you always require (and benefit) from external pull-up Rs. 

    Well that suggestion and a little experimentation seem to solve that problem!  The analyzer I have is an 1-ch O'scope w/ logic channels that can decode I2C.  I scoped the clock with higher resolution and saw a pretty poor clock.  Then tried several pull-ups, e.g. 10K...4.7k...2K...then 1.1k.  Each step the waveform improved and finally took shape with relatively minor high freq loss (leading edge) AND the I2C decoding resulted in more bus transactions being decoded and recognized.  It now appears I'm getting comparable bus transactions to the one I captured with Arduino.   

    Now, I've got to explain why I'm reading zeros from IMU's raw Accel, Gyro, and Magn regs.  Some of the values read  and written by the mpu's api and that I've been using during my bus troubleshooting are different between Arduino and Stellaris Launchpad.  I think I can proceed and assume the bus IO is working (while keeping in mind that there may still be a bus problem) and consider why the IMU might not be sampling sensors.

    cb1- said:

    Suspect it would help us to better assist if you'd be so good as to supply actual code which worked.  (i.e. you read one register - obtain expected result)  This fact suggests that - your interconnect and set-up are mostly correct. 

    You're most troubled when calling the Slave's API routines - which appear to be multi-byte transactions.  (can't quite tell - from your writing)  Can you extract one of the simpler, such multi-byte transactions - and present it here?  (I've stared @ code for days - colleague sometimes goes, "Aha!" w/in minutes - always delightful!)

    I considered this but wasn't sure how much to provide without confusion.  Actually I was in the process of capturing screenshots when I noticed the poor waveforms and dived into the ext Rp rat hole.  It would be interesting to redo the screenshots with improved response due to adding pull-ups.  Not sure if anyone wants to see that(?).

    Have you tried switching the remote Slaves - so that we have positive confirmation that this is primarily a Stellaris/code issue - and not a questionable Slave?  (you described as an Arduino - Slave "pair" worked - I'd like you to switch that Slave to the Stellaris...)

    Yes.  I did that.  I have two bus analyzers, two mpu-9150 breakout boards, and several Stellaris Launchpads and tried switching around to eliminate possibility that one might be bad.

    Finally - do post data capture which illustrates, "can't make sense of Stellaris I2C communication."  Using a Stellaris 64 pin M4 MCU - our group executed a continuous sequence of read/write I2C transactions earlier today - and our transaction count passed 100K - without a "hiccup." 

    I was working on that too.  One thing I realized is that my DSO/I2C analyzer doesn't have the storage depth to capture all the transaction waveforms I'd want to document. 

    You must insure that both slave board and your Stellaris board are adequately powered - and ideally from the same source.  Stellaris I2C inputs may be more sensitive to noise and/or excess capacitance - which are less impacting to the simpler Arduino.  Interconnect length should be minimized - and there have been reports noting that your board's headers are somewhat "less than standard" (pins are too thin!) - an intermittent connection on either of your I2C lines could "exactly" cause your issues.

    One last "horror" involving your board - might your I2C pins be routed to other, interfering points on your board?  At least 2 pairs of pins are cross-connected (to maintain compatibility w/non ARM MCU) you must avoid these.  And - if possible - can you employ a different I2C pair - "just in case?"  (set-up config will change...)

    Yes. I've been careful regarding these...thanks.  There are a lot of variables to watch to avoid symptom of test setup being misinterpreted as symptom of problem.

    Now I need to look at the operation of the IMU and figure out why it might not be getting initialized properly.  I've been worried about this, as I've heard this IMU is a pain due to poor documentation.  I hope I don't regret using MPU-9150!

    Thanks for your help.

  • Always good to see progress - good for you.

    Always find it best to start simple - assume minimal (i.e. nothing!) - and proceed by refinement.

    You've been warned by friendly Bug that your I2C Slave is "unfriendly!"  Suggest - during your test/verify process - that you build your mastery thru use of far more basic - low capacity - I2C EEprom.  Once you can perform several hundred, successive reads/writes w/that - you have far greater odds of "success" when battling more complex device.

    You are silent as regards reports (by others) of "too thin" header pins on your board.  I'd pay great attention to this - even a brief connection interruption during an I2C transaction may wreak havoc - and you'd likely blame everything but this!   Leads often to an unpleasant, "mental health day..."

  • 1+! Those headers are tra**h - o.k. 'too thin'! I suspect that my SSI0-problems - dealing with a microSD card - were also related to insufficient contact because of those connectors.

    I hope that TI will have samples of the LM4f devices soon (although slaughtering some Launchpads is an option ...; get's me rid of the connectors at least ...)

  • aBUGSworstnightmare said:
    slaughtering some Launchpads

    Slaughtering - this case - only leads to improvement...  (Was QC Dept - at some point - bit "asleep" @ the switch?)

    Purchase - w/price as sole/dominant criteria - may lead to "savings erosion" in long-term...   Caveat Emptor...

  • Is this issue with the pins with the 20-pin header socket (side) or the extended thru-hole pins that are found on the component side?

    If you are referring to the latter (extended thru-hole pins) then I guess I see them as a convenience for us.  These pins are probably not intended (as a part choice) to be used where you'd expect a square pin--these are solder tails pins.   I'm surprised they didn't just use the short thru-hole solder pins for the 20-bin header socket like most other boards.  

    I used these pins to connect my I2C analyzer, but first I tin the pins with soldering iron to "thicken" them up--but only so slightly.

    my two cents