# HW i2c & DC

**URL:** <https://forums.digi.com/t/hw-i2c-dc/10598>\
**Category:** Rabbit\
**Created:** [March 25, 2011, 10:56pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598 "2011-03-25T22:56:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![SeeCwriter](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@SeeCwriter](https://forums.digi.com/u/SeeCwriter)\
**Post date:** [March 25, 2011, 10:56pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598/1 "2011-03-25T22:56:42Z")

</div>

The DC Function reference doesn’t appear to document the  
i2c API for the R6000. And my manual has a copyright date  
of 2011. Nor do there appear to be any examples of using  
the HW i2c API in DC v10.64. Is there any documention  
available other than the source code?

---

<div class="post-metadata">

**Author:** ![Margaret](https://avatars.discourse-cdn.com/v4/letter/m/a88e57/32.png) [@Margaret](https://forums.digi.com/u/Margaret)\
**Post date:** [March 25, 2011, 11:04pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598/2 "2011-03-25T23:04:24Z")

</div>

It is not in the Dynamic C Users manual. You might want to look at Tech Note TN215 Using the i2c Bus that is located in the Tech notes section under DC 10 documentation

---

<div class="post-metadata">

**Author:** ![SeeCwriter](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@SeeCwriter](https://forums.digi.com/u/SeeCwriter)\
**Post date:** [March 25, 2011, 11:53pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598/3 "2011-03-25T23:53:27Z")

</div>

I should have mentioned that I also checked TN215 under  
DC10. But TN215 only applies to R2000 and R3000. Go  
figure!

For the R2000 & R3000, if I wanted to read a 2-bytes from a  
slave device, I would do something like this:

i2c\_startw\_tx(); // generate i2c start condition  
i2c\_wr\_wait( slave\_adr ); // address slave device to write.  
i2c\_wr\_wait( control\_word ); // write control word to slave.  
i2c\_startw\_tx(); // generate another start condition  
i2c\_wr\_wait( slave\_adr+1); // Put slave device in read mode.  
i2c\_read\_char( &byte1 ); // read back 2-bytes  
i2c\_read\_char( &byte2 );  
i2c\_stop\_tx();

But in the new i2c.lib, the only read function is  
I2C\_ReadFromSlave( slave\_adr, data, len, mode, timeout);

I don’t see how to do the equivalent of above.

Steve

---

<div class="post-metadata">

**Author:** ![petermcs](https://avatars.discourse-cdn.com/v4/letter/p/4af34b/32.png) [@petermcs](https://forums.digi.com/u/petermcs)\
**Post date:** [March 26, 2011, 10:36am UTC](https://forums.digi.com/t/hw-i2c-dc/10598/4 "2011-03-26T10:36:06Z")

</div>

The documention in the function description block in I2C\_HW.LIB for this function is quite clear. For this you would do something like:

char cBytes[2];  
int iStatus;

iStatus = I2C\_ReadFromSlave(slave\_adr, (char far \*)&cBytes[0], 2, 1, 100);

if(iStatus != 0)  
{  
/// Handle error  
}

For a blocking read with 100mS timeout.

Regards,  
Peter

---

<div class="post-metadata">

**Author:** ![sportsag](https://avatars.discourse-cdn.com/v4/letter/s/f19dbf/32.png) [@sportsag](https://forums.digi.com/u/sportsag)\
**Post date:** [September 17, 2011, 12:53am UTC](https://forums.digi.com/t/hw-i2c-dc/10598/5 "2011-09-17T00:53:38Z")

</div>

I was tying these functions on the RCM6700 development board. For me, the board just locks up. It never does time out. Have you ever seen this?

I tried the I2C\_24LC16.c example too. Same thing, just locks up. I figured it would return after the timeout.

I also tried this on a few dev kits (all RMC6700)

This is another file I tried. I wrote it to read a 24C02 EEPROM. Also locks up. I never get the second print. Any suggestions?

#use I2C\_HW.LIB

I2C\_initIO(1, 0);  
I2C\_initClk(\_I2C\_computeCLKdiv(40000.0));  
WrPortI32(SGCDR, I2C\_CLK\_COUNT);

function()  
{

char Data[5];

printf("here1  
");  
I2C\_ReadFromSlave(0xA2, (char far \*)&Data[0], 2, 1, 500);  
printf("here2  
");

)

---

<div class="post-metadata">

**Author:** ![jovald\_at\_vhe.is](https://avatars.discourse-cdn.com/v4/letter/j/5f9b8f/32.png) [@jovald\_at\_vhe.is](https://forums.digi.com/u/jovald_at_vhe.is)\
**Post date:** [September 23, 2011, 12:32pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598/6 "2011-09-23T12:32:01Z")

</div>

You are using 8 bit slave address. It should be 7-bit.  
The library adds r/w bit to the address. This is what i use for 24AA02 chip.

//Note Address is 7bit NOT 8 bit library adds r/w bit  
#define EEPROM 0x50 //Mac address and EEPROM  
#define BusReset\_ADDRESS 0x00 //I2C bus Slave address

#use RCM67xx.LIB //library used for RCM67xx modules  
#use I2C.lib //library used for I2C comms

int EEPROMerr; //i2c error code from EEPROM 0=noerror  
char cBytes[258];  
unsigned char calibrat[256] , \*cal; //Calibration constants EEPROM  
unsigned char wEEPROM[9] , \*wEEP; //EEPROM working string

brdInit(); //Initialize RCM ports  
if(EEPROMerr = i2c\_init()) //Initialize i2c  
{   
// Error handler here  
}  
if(EEPROMerr = resetI2C()) //Reset i2c bus this is optional  
{   
// Error handler here  
}  
if(EEPROMerr = Read\_EEPROM());  
{   
// Error handler here  
}

int resetI2C(void)  
{  
int len;  
wEEPROM[0] = 6; //Command SoftReset  
len = 1; //No of chars to write  
EEPROMerr = I2C\_WriteToSlave(BusReset\_ADDRESS,(char far \*)&wEEPROM[0],len,1,5);  
return EEPROMerr;  
}

int Read\_EEPROM(void)  
{  
cal = calibrat;  
cBytes[1] = 0x00;  
for(i = 0; i \< 256; i+=8) //Read EEPROM data max 8 bytes at a time  
{  
if(EEPROMerr = I2C\_WriteToSlaveNoStop(EEPROM, (char far \*)&cBytes[1], 1, 1, 5))  
{  
// Error handler here  
}  
if(EEPROMerr = I2C\_ReadFromSlave(EEPROM, (char far \*)cal, 8, 1, 5))  
{  
// Error handler here  
}  
cal+=8;  
cBytes[1]+=8;  
}  
return EEPROMerr;  
}

---

<div class="post-metadata">

**Author:** ![sportsag](https://avatars.discourse-cdn.com/v4/letter/s/f19dbf/32.png) [@sportsag](https://forums.digi.com/u/sportsag)\
**Post date:** [September 26, 2011, 4:06pm UTC](https://forums.digi.com/t/hw-i2c-dc/10598/7 "2011-09-26T16:06:57Z")

</div>

Thanks, I will try your code when I get a chance. I did notice awhile back my I2C address was incorrect. It is supposed to be 7 bit. But even after using the right address, the board just locks up. That was the bigger issue. Even with a wrong address, it should not lock up.  
I ran the sample I2C examples that came with the install and they too would lock up. So, I submitted a ticket and I believe it is being looked into.

In the meantime, my fix was to use the I2C\_DEVICES.LIB instead. See the code below.

#define I2C\_CLOCKPIN 1  
#define I2C\_DATAPIN 0  
//#use I2C\_HW.LIB  
#use I2C\_DEVICES.LIB  
unsigned I2C\_ISR\_State;  
i2cTransaction I2Cdata;  
unsigned long I2C\_CLK\_COUNT;

in the function, I used

unsigned int I2C\_Address=0x00;  
char sData[32];

i2c\_init();  
I2C\_initIO(1, 0); // Set 1=PE1 as clock, 0=PE0 as data  
//Example (Sets I2C bus speed to 40 Kbits/second):  
I2C\_initClk(\_I2C\_computeCLKdiv(40000.0));  
WrPortI32(SGCDR, I2C\_CLK\_COUNT);

Result=I2C\_WriteToSlave(I2C\_Address, (char far \*)&sData, 1, 1, 250);
