Page 1 of 2

Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 10:17 am
by barttech
I'm having trouble using the other I2C ports on the MOD54415. The supplied files only access port 0.
I need to use I2C port 1 for my current project. I've made the following changes to the I2CMaster files:

in I2CMaster.h:
// Added #define I2C_PORT_NO to allow for using other than standard I2C port on MOD54415
#define I2C_PORT_NO 1 // This uses pins 44 for SCL and 41 for SDA
//#define I2C_PORT_NO 0 // This uses pins 42 for SCL and 39 for SDA

Then I changed the #defines as follows so that the proper registers would be addressed:
// 05/16/2013 Bartlett Technologies, I2C_PORT_NO allows changing I2C ports, see #define above.
#if defined (MCF5441X)
#if I2C_PORT_NO==0
#define I2C_SR sim2.i2c0.i2sr
#define I2C_CR sim2.i2c0.i2cr
#define I2C_DR sim2.i2c0.i2dr
#define I2C_FDR sim2.i2c0.i2fdr
#define I2C_ADR sim2.i2c0.i2adr
#elif I2C_PORT_NO==1
#define I2C_SR sim2.i2c1.i2sr
#define I2C_CR sim2.i2c1.i2cr
#define I2C_DR sim2.i2c1.i2dr
#define I2C_FDR sim2.i2c1.i2fdr
#define I2C_ADR sim2.i2c1.i2adr
#endif


In I2CMaster.cpp I changed:

In Init() I changed it so the right pins would be used:
#if (I2C_PORT_NO==0) // Bartlett Technologies, added ability to switch ports
J2[39].function( PINJ2_39_I2C0_SDA); // Set Pins to I2C
J2[42].function( PINJ2_42_I2C0_SCL);
#elif (I2C_PORT_NO==1) // Bartlett Technologies, added ability to switch ports
J2[41].function( PINJ2_41_I2C1_SDA);// Set Pins to I2C
J2[44].function( PINJ2_44_I2C1_SCL);
#endif

I changed the interrupts to use the right source:
#if (I2C_PORT_NO==0) // 05/16/2013 Bartlett Technologies, allows I2C_PORT_NO to select which I2C port to use.
SetIntc(0, ( long ) &i2c_master_int_routine, 30, 3 /* IRQ 3 */);
#elif (I2C_PORT_NO==1)
SetIntc(0, ( long ) &i2c_master_int_routine, 57, 3 /* IRQ 3 */);
#endif

I'm reading a TC74A temperature sensor, connected to port 1 with pullups. If I set the code to port 0 (no hardware connected to it) I get the expected errors, device not found. If I set it to port 1 I get a reading w/o errors, even with no device connected. The reading usually 0 now, but was 26 for a while.

I suspect I'm either reading some other device that is attached to port 0, or haven't completely migrated to Port 1 and am getting garbage somehow.
I've done some tests to be sure my code is getting compiled and is running.
Anyone see anything I've missed?
Thanks,
sam

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 12:09 pm
by mbrown
Hi Sam,

I've been down this road trying to get a multichannel i2c driver for Netburner. I think you've hit all the right notes and to me it doesn't look like you're leaving anything out. I have gotten this working before as an upgrade for the i2cmutli driver and was planning on including it in the next update for our tools. If you'd like to try using this to get your system communicating, I've attached here the files I've been working with. There may be alterations to the comments, but functionally the code works for the mcf5441x platforms. To use this code, you will have to update your sim file (instead of using ifdefs for the I2SR, I2CR, ..., I used structures and we were using redundant structures in previous sim file). You shouldn't need to change any of your function calls, just include the new files. Though if you want to use multiple i2c channels at the same time, I've added arguments to allow you to differentiate different i2c modules. The module selector is at the top of the multichanneli2c.h file called DEFAULT_I2C_MODULE.

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 12:21 pm
by barttech
Thanks!
I get:
'i2cModule' was not declared in this scope
I can see where it is used in multichanneli2c.h, but not where it is defined.
Did you change basictypes or ucos.h?
Sam

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 1:02 pm
by mbrown
It was redefined in the sim file. See the attached sim5441x.h file.

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 1:18 pm
by barttech
I added that file the first time, and I don't see i2cModule in there.
Sam

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 2:08 pm
by mbrown
Sam,

Sorry about that. I thought you had meant the i2cstrut. I do remember running into this problem once while debugging this, but having done a clean build on this recently, I've been unable to recreate the problem you're seeing. We even just tried building this on a different machine without any of my other working files on it and it seems to work fine.

Can you give me any more information about the error? A line number or something more descriptive?

And just as a sanity check maybe just make sure you've got both the source and header file in a project and do a clean build of your project?

Re: Accessing other I2C ports on MOD54415

Posted: Thu May 16, 2013 7:33 pm
by barttech
When I use I2C_SR in my code, it reads your macro
#define I2C_SR i2cModule->i2sr
and says
Description Resource Path Location Type
'i2cModule' was not declared in this scope

The line number is from my file where I call I2C_SR.

Where is i2cModule defined in your files?

I tried copying I2cmultichannel.h and .cpp and sim5441x.h into my project (is that what you meant?) and cleaning, same problem. But it seems to still be looking in /include and /system, not in my project for these files.

I have sim5441x Rev 1.1, is that right?
And i2cmultichannel is 1.7?
sim5441x.h has:
typedef i2cstruct i2c25struct;
typedef i2cstruct i2c1struct;
typedef i2cstruct i2c0struct;

but no i2cModule is defined in there.

Sam

Re: Accessing other I2C ports on MOD54415

Posted: Fri May 17, 2013 7:42 am
by dciliske
I'll try to weigh in on this here. The i2cModule reference is probably in the wrong location. If you look into the multichanneli2c.cpp you'll find that all of the i2c driver functions take a module number which is then used to lookup which sim structure to use for the operation. In all cases, this knowledge is stored as a pointer to an i2cstruct called 'i2cModule'. If you are not using the given multichanneli2c.cpp, or, rather, if you are attempting to use this header with the standard i2c driver, then you will get that compilation error.

Can you please post your compiler output and a list/screenshot of your project files?

-Dan

Re: Accessing other I2C ports on MOD54415

Posted: Fri May 17, 2013 2:59 pm
by barttech
Dan et al,
I renamed all the i2c*.* (.cpp, .h, .o) so that the compiler cannot find them, and I get the expected errors when I try to compile with these includes (1 commented out):
#include <i2cmaster.h> //Used for Master Only I2C
//#include <multichanneli2c.h> //Used for Master Only I2C

Then I switch the comments (I really appreciate that all I have to do is this to (soon) get the multichannel functionality):
//#include <i2cmaster.h> //Used for Master Only I2C
#include <multichanneli2c.h> //Used for Master Only I2C
and get this compiler output:

17:51:42 **** Incremental Build of configuration Release for project BT2DC2STEP_EN ****
Info: Internal Builder is used for build
m68k-elf-g++ -O2 -falign-functions=4 "-IG:\\nburn/include" "-IG:\\nburn/MOD5441X/include" "-IG:\\nburn/gcc-m68k/m68k-elf/include" -gdwarf-2 -Wall -Wno-write-strings -c -fmessage-length=0 -fno-rtti -fno-exceptions -mcpu=5206e -DMOD5441X -DMCF5441X -o Interface.o "..\\Interface.cpp"
m68k-elf-g++ -O2 -falign-functions=4 "-IG:\\nburn/include" "-IG:\\nburn/MOD5441X/include" "-IG:\\nburn/gcc-m68k/m68k-elf/include" -gdwarf-2 -Wall -Wno-write-strings -c -fmessage-length=0 -fno-rtti -fno-exceptions -mcpu=5206e -DMOD5441X -DMCF5441X -o I2CBase.o "..\\I2CBase.cpp"
..\I2CBase.cpp: In member function 'void I2CBase::I2CReset() const':
..\I2CBase.cpp:37: error: 'i2cModule' was not declared in this scope
..\I2CBase.cpp: In member function 'void I2CBase::TransmitNoPend(char*, int)':
..\I2CBase.cpp:61: error: 'i2cModule' was not declared in this scope

17:51:43 Build Finished (took 665ms)

Here is the I2CBase file:
/********************************************************************* * I2CBase.cpp
* I2CBase.cpp Bartlett Technologies June 28, 2012
**********************************************************************/

#include <basictypes.h>
#include <string.h>
#include <sim5441x.h>
#include <ucos.h>
//#include <i2cmaster.h> //Used for Master Only I2C
#include <multichanneli2c.h> //Used for Master Only I2C

#include "BTDefine.h"
#ifdef USE_I2C
#include "I2CBase.h"

I2CBase::I2CBase(void) {
}

I2CBase::~I2CBase(void) {
}

//****************************** Init(void) *****************************
// Call this first for each device.
// 08/25/2012 Bartlett Technologies for I2C based devices.
void I2CBase::Init(void) {
// PEND_FOR_I2C(@) // Wait for any other tasks to release the I2C busy flag;
CLEAR_I2C_FLAG
I2CReset();
SET_I2C_FLAG
// allprintf(DEBUG_OUT,"I2C Init.\n");
}

//****************************** I2CReset(void) *****************************
// 08/25/2012 Bartlett Technologies for I2C based devices.
void I2CBase::I2CReset(void) const {
// Always call this within a PEND_FOR_I2C(@)/SET_I2C_FLAG block.
I2C_SR = I2C_SR&0x80;
I2C_SR = I2C_SR|0x7f;
I2CInit(I2C_CLK_DIV);
// allprintf(DEBUG_OUT,"I2C Reset.\n");
} // end of I2CReset(void)

//****************************** Transmit(char *TransmitStr,int len) *****************************
// 08/25/2012 Bartlett Technologies for I2C based devices.
// Sends string of length 'len' to I2C device.
void I2CBase::Transmit(char *TransmitStr, int len) {
PEND_FOR_I2C($) // Wait for any other tasks to release the I2C busy flag;
CLEAR_I2C_FLAG
TransmitNoPend(TransmitStr, len);
SET_I2C_FLAG
} // end of Transmit(char *TransmitStr,int len)

//****************************** TransmitNoPend(char *TransmitStr,int len) *****************************
// 08/25/2012 Bartlett Technologies for I2C based devices.
// Sends string of length 'len' to I2C device.
// Call this only if surrounded by a PEND_FOR_I2C(@), CLEAR_I2C_FLAG & SET_I2C_FLAG block.
void I2CBase::TransmitNoPend(char *TransmitStr, int len) {
bool Success = false;
int Tries = 10;
while ((!Success)&&(Tries-->0)){
if (I2C_SR_BUSY){
allprintf(DEBUG_OUT, " I2C busy for device 0x%02x.\n", DeviceAddr);
I2CReset();
}
// if (IsOK())
I2CStatus = I2CSendBuf(DeviceAddr, (unsigned char*) TransmitStr, len);
// ShowData((unsigned char*)TransmitStr,len);
if (I2CStatus>I2C_OK){
allprintf(DEBUG_OUT, " I2C Error %d for Device 0x%02x Tx.\n", I2CStatus, DeviceAddr);
I2CReset();
}
else
Success = true;
}
if ((!Success)&&(Tries==0))
allprintf(INFO_OUT, " I2C Error %d for Device Addr=0x%02x Tx.\n", I2CStatus, DeviceAddr);
} // end of Transmit(char *TransmitStr,int len)

//****************************** Transmit(char *TransmitStr) *****************************
// 08/25/2012 Bartlett Technologies for I2C based devices.
// Sends null-terminated string to I2C device.
void I2CBase::Transmit(char *TransmitStr) {
PEND_FOR_I2C(+) // Wait for any other tasks to release the I2C busy flag;
CLEAR_I2C_FLAG
TransmitNoPend(TransmitStr, strlen(TransmitStr));
SET_I2C_FLAG
} // end of Transmit(char *TransmitStr)

//****************************** TransmitNoPend(char *TransmitStr) *****************************
// 08/25/2012 Bartlett Technologies for I2C based devices.
// Sends null-terminated string to I2C device.
void I2CBase::TransmitNoPend(char *TransmitStr) {
TransmitNoPend(TransmitStr, strlen(TransmitStr));
} // end of Transmit(char *TransmitStr)

#endif // #ifdef USE_I2C

It complains about the I2C_SR macro, defined in Multichanneli2c.h as:
#define I2C_SR i2cModule->i2sr

I cannot find where i2cModule is supposed to be defined.
Sam

Re: Accessing other I2C ports on MOD54415

Posted: Fri May 17, 2013 5:00 pm
by dciliske
Please look at the file multichanneli2c.cpp and look carefully at the function definitions and where it declares an 'i2cStruct' in the function. You will note that these functions have a different signature (what arguments they take) than the normal ones. You are using the wrong functions and are compiling the wrong file.

I2CBase.cpp DOES NOT WORK WITH 'multichanneli2c.h'! You must not do that. You MUST be using 'multichanneli2c.cpp' to use 'multichanneli2c.h'.