Stellaris® ARM® Microcontrollers
Forum
Options
Subscribe via RSS
Helpful Stellaris® LM4F Series Links
LM4F Series
Stellaris PinMux Utility
Stellaris® LM4F120 LaunchPad
LM4F MCU Applications
LM4F MCU Video
ARM Cortex-M4F Whitepaper
Stellaris MCU Brochure
LM4F232 Eval Kit
Forums
I2C not working on LM3S9B90
Posted by
Peter2009
on
Mar 09 2010 08:04 AM
Prodigy
190
points
sakul,
Here is a sample code for LM3S9B90 I2C config (I2C0 channel).
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2|GPIO_PIN_3);
I2CMasterEnable(I2C0_MASTER_BASE);
I2CMasterInitExpClk(I2C0_MASTER_BASE,
SysCtlClockGet(),TRUE); //400 kHz
After this configuration you may use the library functions for read and write except
I2CMasterSlaveAddrSet() because there is a big bug inside it.
Use the following direct register set:
HWREG(I2C0_MASTER_BASE) = (address&0xFE)|0x00; //Slave address for write, zero offset
HWREG(I2C0_MASTER_BASE) = (address&0xFE)|0x01;
//Slave address for read, zero offset
My I2C module works correctly using the above codes.
Peter2009
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
sakul
on
Mar 09 2010 08:16 AM
Prodigy
230
points
Peter, thank you
you are really talking about a 90er device? and it is a tempest class device? really stunning......
From what I have learned recently, this code MUST NOT work as it contains no stuff to enable the peripheral muxes (check older posts in this thread)
jrmymllr, thx too.
thats what I did meanwhile - of course.
In my opinion, average clever guys should be able to get such a dumb interface up and running in a reasonable time.
So I decided to write mails to TI and go on with other work as the calender keeps on moving and schedules really don't care bout my probs :::::
whatever news come up, I'll keep you updated
cheers
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
TI Alex
on
Mar 09 2010 08:58 AM
Expert
8210
points
sakul,
So I guess the loopback code didn't show you anything you missed in your source code?
And since you can send and receive successfully in loopback mode, I am starting to think the problem may be with the device you are trying to talk to.
Alex
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Peter2009
on
Mar 09 2010 09:07 AM
Prodigy
190
points
sakul,
Sorry the very first line is: SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
The others are correct.
It seems that the controller doesn't know that it must not operate. :)
Peter2009
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Sue Cozart
on
Mar 09 2010 09:17 AM
Mastermind
49630
points
sakul,
The I2C0 pins are configured to operate as I2C0 by default at reset. As a result, they don't require the GPIOPinConfigure() call. Your code used I2C1 which is why the calls are required.
Regards,
Sue
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
sakul
on
Mar 09 2010 09:35 AM
Prodigy
230
points
Sue: Oh I see, the bootloader - right !
Alex: no, unfortunately loopback did not help. As I said, to eliminate all external influences, I am now testing without any external device (see one of the earlier posts)
I am aware that there will be no positive acknowledge, all I'd like to see is any motion on the clock line. (the lines are pulled up properly).
the device I initailly wanted to drive is well known and operates just perfectly on NXP ;)
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Sue Cozart
on
Mar 09 2010 12:06 PM
Mastermind
49630
points
Hi sakul,
Is it possible that you could zip up your project and send it to me at support_lmi@ti.com?
Sue
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
sakul
on
Mar 09 2010 12:29 PM
Prodigy
230
points
Sue,
I can send you the entire project, but the point is, if you go back 5 or 6 posts or so, I already posted THE ENTIRE CODE that i am using in order to just get the clock pin to move after main().
It is just 15 lines of bare code. I tried it in the flavour "StellarisWare" and with plain register accesses ..
Will strip the project back to the bare minimum tomorrow and send the entire Keil project then.
In the meantime thanks to all for attention, ideas and participation
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Sue Cozart
on
Mar 09 2010 12:43 PM
Mastermind
49630
points
Hi sakul,
I appreciate you sending the project. I know you had posted your code, but having the project makes things easier and speedier for us.
Regards,
Sue
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
TI Alex
on
Mar 10 2010 14:21 PM
Expert
8210
points
sakul,
I worked on the I2C issue you are having and I was able to successfully view the I2C0SCL and I2C0SDA signals on the EKK-LM3S9B90 using a scope.
Here's what I did:
1) Used 9kOHM pull-ups on PB2 and PB3 (I used a 5V regulated supply for convenience of wiring, but 3.3V will work just fine)
2) Modified the code to not use the internal pull-ups. They are not strong enough (i.e. quick enough) for I2C operation.
3) Removed "SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);" that you call in the for(;;) loop. This will essentially put the I2C0 in the starting state, overwriting all the master and clock setup you did previously.
Here is the code I used:
//
// Setup clock for 20Mhz
//
SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
//
// Turn on I2S0 and reset to a known state
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
//
// Configure the PortB pins for I2C0
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
//
// Set GPIO Pins for Open-Drain operation
//
GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
//
// Give control to the I2C Module
//
GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_2, GPIO_DIR_MODE_HW);
//
// Enable and Initalize Master module and Master Clk using 100kbps
//
I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), 0);
//
// Set the slave address, and set the Master to Transmit mode
//
I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x3C, false);
//
// Place the character to be sent in the data register
//
I2CMasterDataPut(I2C0_MASTER_BASE, 'J');
//
// Initiate send of character from Master to Slave
//
I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
//
// Delay until transmission completes
//
while(I2CMasterBusy(I2C0_MASTER_BASE)){}
while(1){}
Please try this setup with the provided code and let me know if you see the signals on PB2 and PB3.
Alex
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
sakul
on
Mar 10 2010 16:48 PM
Prodigy
230
points
Alex, again many thanx for your attention and time.
I took your code right from the post. The only thing I changed was SYSCTL_XTAL_12MHZ instead of your 16. And I added a LED at SYSCTL_PERIPH_GPIOF for a convenient trigger. The pullups I already had soldered there were 10k, so I ignored the difference.
Result: Not a single move.
IMPORTANT HINT FOR OTHER USERS OF TEMPEST CLASS DEVICES:
the above sample code by TI Alex will work only on I2C0, as the two I/O pins needed for this interface default to I2C0 after reset (for bootloader usage)
I2C1 defaults to GPIO and thus needs additional code to set the IO multiplexer to proper values (check GPIOPinConfigure() in Stellaris docs)
Post edited by: sakul, at: 2010/03/10 16:51
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Dave Wilson
on
Mar 11 2010 09:29 AM
Mastermind
22830
points
Peter2009, you mentioned a "big bug" in I2CMasterSlaveAddrSet() in one of your previous posts. As far as I can tell, this function is fine but, looking at your solution, I think I see what's wrong. You are assuming 8 bit I2C addresses which include the read/write bit. The API, however, assumes 7 bit addresses (the 8 bit address shifted right 1 bit) and a separate parameter to indicate whether you are going to be doing a read or write operation to that slave.
For every I2C driver that uses a 7 bit address, there is another that uses 8 bit address definitions so it is very important to know which you are working with and shift your addresses if required to match the parameter definitions. We just happen to use the 7 bit version.
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Dave Wilson
on
Mar 11 2010 09:45 AM
Mastermind
22830
points
Sakul,
Please could you run exactly the code Alex posted with only the crystal frequency change in the SysCtlClockSet call (assuming your board has a 12MHz crystal rather than the 16MHz one on the eval kit) and see what happens? If you see the same failure (nothing on the output), take a look at the contents of the I2C Master Control and Status Register at 0x40020004 and post what you see there.
I spent a couple of days last week investigating an I2C problem that has been seen on some Tempest chips that results in exactly the symptom you are seeing. It looks like a chip test escape since it's only seen on some ICs but in the failing cases, the status reports arbitration lost (bit 4 set) and a power cycle is required to clear the error.
If you have more than 1 board or if you can try the test on more than 1 chip, that would be helpful too.
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
sakul
on
Mar 11 2010 10:55 AM
Prodigy
230
points
-> Dave <-> Peter "big bug"
ACK - I checked this and stepped thru, cannot see a bug
its only a matter of viewpoint regarding the shift of the address
-> Dave
will do.
We got two of our own boards here and they behaved the same all the time - but they were obiously out of the same lot. Will try one of our LMI eva boards asap.
more tomorrow
->
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
Posted by
Peter2009
on
Mar 12 2010 01:42 AM
Prodigy
190
points
TI Dave,
Thank you for your comment.
My opinion is that as the I2C communication works on 8 bit bases it is not practical to use 7 bit address as the address and the direction bit is transmitted together in a byte.
For example if the manufacturer of my slave chip says that the address is 0xD0/0xD1 it requires additional program step to shift it first right by one to be able to input it into I2CMasterSlaveAddrSet() which will shift it back left and after that will add the direction bit.
None of the APIs in my practice works in this way.
That's why I decided to use the direct register access (without shifting).
Peter2009
Report Abuse
Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
1
2
3