Jump to content
rycco1426459928

I2C on Stellaris Launchpad

Recommended Posts

1.Does Energia need some more definitions to the above sketch for I2C to work?

2. How do I define which I2C pinns I use in Tiva C as there are I2C0...I2C3?

3. Can someone give a link to a working library?

You need to initialise the I²C with

 

void setup()
{
Wire.begin();
// ...
}
Sorry, none of the formatting buttons work, I had to enter the HTML codes manually.

Share this post


Link to post
Share on other sites

Thanks for all help, I got it work:

 

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 character, 2 line display
 
void setup()
{
  Wire.begin(3);
  Wire.setModule(3);
  pinMode(15,INPUT_PULLUP); // I2C3SDA 
  pinMode(14,INPUT_PULLUP); // I2C3SCL
  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("I2C display OK!    ");
  lcd.setCursor(0,1); 
  lcd.print("on Tiva C...");
}
 
void loop()
{
}
 
I2C.jpg

 

I am using YwRobot LCM1602 I2C adapter

Share this post


Link to post
Share on other sites
I think it is only necessary to use Wire.setModule(3) before Wire.begin() because it is necessary to inform what module will be used before initializing it.

 

In the LCD, I think there is a Wire.begin() inside lcd.init(). The first Wire.begin(3) is useless, because you are defining the I2C module (probably the module 0) as slave with address 3 and after that, changing to module 3 and finally, reconfiguring the module with Wire.begin().

 

It worked for me in the Senshub boosterpack.

Share this post


Link to post
Share on other sites

#5RM, what library have you used for that sketch. Can you please share the link to download?

 

I'm having a headache with i2c and Stellaris.

Tried everything (diferent modules, pullups, wire start sequences, every i2c port on stellarpad) in every related post, and can't get the I2C working.

I have i2c RTC modules, 3 kinds of i2c lcd adapters and one mpu6050 module. No one works or get detected with i2c scanner sketch or works with their specific library.

 

But if I plug  a buspirate in parallel with the sdl/sda pins/module used in stellaris, the Bus Pirate comunicate and find the i2c address of the i2c module (i2clcd adapter, mpu,...) in a blink.

The Bus pirate it's only using 3 wires, gnd, scl and sda. So, i'ts not the pullups, power supply or module tested.

All the modules work fine with Arduino too.

It's the same with every i2c scanner script used in any i2c/port, detect i2c devices in every address, .

 

I'm willing to help trace where is the problem (I think there's more people having issues with i2c and stellaris in Energia).

Share this post


Link to post
Share on other sites

#5RM, what library have you used for that sketch. Can you please share the link to download?

 

Sorry Stendall, I have been off this forum for long time.

I cannot remember where I got the library from, but you can get the files from here:

 

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/LiquidCrystal_I2C.h

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/keywords.txt

 

 

Hope this helps.

Share this post


Link to post
Share on other sites

Sorry Stendall, I have been off this forum for long time.

I cannot remember where I got the library from, but you can get the files from here:

 

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/LiquidCrystal_I2C.h

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp

https://dl.dropboxusercontent.com/u/32143987/LiquidCrystal_I2C/keywords.txt

 

 

Hope this helps.

 

 

It will help for sure.

Thank you for the links.

Share this post


Link to post
Share on other sites

Thank you Rei.

I got running all my I2C modules.

Hi Stendall,

 

Would you please explain how did you solve your problem with I2C? I guess I tried all suggested solutions in this (and other) threads, including:

- checking with other modules

- different combinations of initializations, setModule statements, and begin()

- checking with lower Rpu (according to the philips document it should be approx 1kΩ

 

My conclusion is that no matter which module I use I get always get 0 (null) back from endTransmission(), no matter if there is ACK or not. That makes the detection of I2C failed transaction wrong: i2csdetect erroneously detect a device under each scanned address:

Scanning: 
.....................................................................................................................

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
01: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
02: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
03: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
04: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
05: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
06: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
07: 70 71 72 73 74 75 76 77                        

My logic analyzer is showing the following traffic during execution of i2cdetect:

 

post-1536-14264605415285_thumb.png

 

This is identical for each and every module I tried. I did not try though with another I2C master - such as AVR arduino or such.

s.

post-1536-14264605414848_thumb.jpg

i2cdetect.txt

Edited by sq7bti

Share this post


Link to post
Share on other sites

[...] I've discovered that "Wire.endTransmission()" always returns a zero both on the MSP430 and the Stellaris launchpads. Apparently this is also an issue with some arduino like boards (like the  teensy). [...]

It is indeed true for i2c-scanners as far as I can see in the code:

uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
  uint8_t error = I2C_MASTER_ERR_NONE;

  if(TX_BUFFER_EMPTY) return 0;
  //Wait for any previous transaction to complete
  while(ROM_I2CMasterBusBusy(MASTER_BASE));
  while(ROM_I2CMasterBusy(MASTER_BASE));

  //Select which slave we are requesting data from
  //false indicates we are writing to the slave
  ROM_I2CMasterSlaveAddrSet(MASTER_BASE, txAddress, false);

  while(ROM_I2CMasterBusy(MASTER_BASE));
  unsigned long cmd = RUN_BIT | START_BIT;

  error = sendTxData(cmd,txBuffer[txReadIndex]);
  txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
  if(error) return error;
  while(!TX_BUFFER_EMPTY) {
          error = sendTxData(RUN_BIT,txBuffer[txReadIndex]);
          txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH;
          if(error) return getError(error);
  }

  if(sendStop) {
          while(ROM_I2CMasterBusy(MASTER_BASE));
          HWREG(MASTER_BASE + I2C_O_MCS) = STOP_BIT;
          while(ROM_I2CMasterBusy(MASTER_BASE));
          currentState = IDLE;
  }
  else {
          currentState = MASTER_TX;
  }

  // indicate that we are done transmitting
  transmitting = 0;
  return error;

}

endTranmission returns null (line 5) in a typical scanner attempt to trigger a slave with beginTransmission and entail it with immediate endTransmission. Shouldn't there be an actual check for the ACK to give a status back of the device responding or not?

 

s.

Share this post


Link to post
Share on other sites

Hi sq7bti.

I will try to put a little of light in this topic.

 

The first problem that I faced was to find a i2c scanner sketch that worked on Stellaris.

There are some Arduino i2c scanners out there that compile flawlessly but don't work because find i2c devices in each address.

The one I'm using and it's working is this:

#include <Wire.h>

void setup()
{
   Wire.begin();
   Wire.setModule(3);
   Serial.begin(9600);
   Serial.println("\nI2C Scanner");
}

void loop()
{
   byte error, address;
   int nDevices;
   uint8_t c;

   Serial.println("Scanning...");

   nDevices = 0;
   for(address = 1; address < 127; address++ ) 
   { 
     error = I2C_read (address, &c, 1);  
     if (error == 0)
     {
       Serial.print("I2C device found at address 0x");
       if (address<16) 
         Serial.print("0");
       Serial.print(address,HEX);
       Serial.println("  !");

       nDevices++;
     }
  
   }
   if (nDevices == 0)
     Serial.println("No I2C devices found\n");
   else
     Serial.println("done\n");

   delay(1000);           // wait 5 seconds for next scan
}

int I2C_read(int start, uint8_t *buffer, int size)
{
  int i, n, error;

  Wire.beginTransmission(start);
  n = Wire.write(start);
  if (n != 1)
    return (-10);

  n = Wire.endTransmission(false);    // hold the I2C-bus
  if (n != 0)
    return (n);

  // Third parameter is true: relase I2C-bus after data is read.
  Wire.requestFrom(start, size, true);
  i = 0;
  while(Wire.available() && i<size)
  {
    buffer[i++]=Wire.read();
  }
  if ( i != size)
    return (-11);

  return (0);  // return : no error
}

Looks like in Stellaris it's not enough to Wire.beginTransmission and Wire.endTransmission to get the error code and thus detect the i2c address of the module.

We need to actually try to send some data, and there are more error cases to manage than just the error code returned from endTransmission.

 

Once I get the i2c module address detected (PCF8574 LCD adapter, Tiny RTC, MPU6050, ... ) I haven't any problem regardles the different pullup resistors values that comes with every module. So I do not needed to use externals pullup resistors or use INPUT_PULLUP on the i2c pins used o the Stellaris.

 

Some modules uses  3v3 voltage  but comes with a 3v3 LDO regulator. Even being a low dropout regulator, sometimes the voltage drop is enough to give you problems.

In that case it's better to just feed it using the vbus instead the 3v3.

 

Hope it helps.

 

Edited.

Forgot to say that this code it's not mine.

Mine it's a striped down version of (I think. I don't remmember for sure right now) the one found here:

http://playground.arduino.cc/Main/MPU-6050

Edited by Stendall

Share this post


Link to post
Share on other sites

Hope it helps.

 

 Thank you Stendall. It helped a lot. In my case there was another issue caused by the following feature i overlooked: (page 6 of DS1307):

Upon power-up, the device switches from battery to VCC when VCC is greater than 
VBAT +0.2V and recognizes inputs when VCC is greater than 1.25 x VBAT.

The chip was responding correctly when powered from launchpad 3.3V bus, even though nominally it is 5V device, but played dead when 3V battery was connected to it at the same time. DS1307 is fine when powered from 5V, with SDA and SCL pulled up from 3.3V.

 

s.

Share this post


Link to post
Share on other sites

Have you tried the NXP PCF2129A instead?

 

The PCF2129A operates at 3.3V, embeds the quartz crystal and requires no passive components, except the 10kΩ pull-up resistors for the I²C bus.

 

Actually, the LM4F120 / TM4C123 already includes a RTC, but the battery power line for LPM is connected to the main power line.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...