i2c not working

Thread Starter

kingsloth

Joined Dec 28, 2015
12
Without more of your code no one could tell what that statement could possibly mean, though I do hope you enable the I2C before you attempt to use it.
It gives the right frequency so i suppose its correct. Actually MPLABX's help says :
The module should be appropriately configured (using I2CConfigure and I2CSetFrequency, and possibly I2CSetSlaveAddress) before being enabled(I2CEnable).
 

sailorjoe

Joined Jun 4, 2013
361
This is the only thing i get, ch1 - SCL ch2- SDA.
Looking at your scope picture, it appears your putting out a binary "00111100". Is that what you expected?
I'm still convinced that line 24 of your code is wrong, because it doesn't wait for data to be available. What do you think?
 

Thread Starter

kingsloth

Joined Dec 28, 2015
12
Looking at your scope picture, it appears your putting out a binary "00111100". Is that what you expected?
I'm still convinced that line 24 of your code is wrong, because it doesn't wait for data to be available. What do you think?
0x3C its the device write register, so it is the expected result, however stop bit never works. I tried to make my own i2c functions but the results are a bit odd. Sometimes it reads good values and others it reads values like 65300, however the "65" is fixed, the rest change while rotating....
 

ErnieM

Joined Apr 24, 2011
8,019
I've been hunting around for someone who has used this library with any success and have not found anyone. There are things I suspect are very wrong in the help files, meaning while they are correct code they do not perform the required tasks.

Example: you need to read some data, here is your code that seems to closely follow the help file:
Code:
  if (I2CReceivedDataIsAvailable(I2C1))
  {
      I2CAcknowledgeByte(I2C1, TRUE);
      msb = I2CGetByte(I2C1);
  }
So if the data is ready to read all should be good. But what if your processor if faster that I2C (because it is!)? The IF fails and the data is never read.

Perhaps this would be "better:"
Code:
  while (!I2CReceivedDataIsAvailable(I2C1));
  I2CAcknowledgeByte(I2C1, TRUE);
  msb = I2CGetByte(I2C1);
Now we wait until data is available. I put "better" in quotes as we have stalled the processor waiting for data that may never come, thus an infinite loop.

You initializing the I2C, are you initializing the HMC5833L?

I do note your read code assigns the read back to 0, which is what you get at the end. Looks like nothing is actually read; see if you change the initialization to 0xFF (lines 4&5) you get that same number back.

Again, I suggest getting each simple transaction to work before moving onto the next.
 

spinnaker

Joined Oct 29, 2009
7,837
Good catch Ernie. I use the XC8 version. It is a little different. This is what I do when reading data. It works. I work with the 8 bit series but the principal should be the same. Looks like calls to the libraries are a little different.


Code:
#ifndef DSRTCCHW_H
#define   DSRTCCHW_H

#define DSRTCCHW_initI2C() OpenI2C2(MASTER,SLEW_OFF);  SSP2ADD = 0x09;  // 100 khz with 4mhz clock
#define DSRTCCHW_idleI2C() IdleI2C2()
#define DSRTCCHW_startI2C() StartI2C2()
#define DSRTCCHW_stopI2C() StopI2C2()

#define DSRTCCHW_restartI2C() RestartI2C2()
#define DSRTCCHW_readByteI2C() ReadI2C2()
#define DSRTCCHW_writeByteI2C(byte) WriteI2C2(byte)
#define DSRTCCHW_sendAckI2C()  AckI2C2()
#define DSRTCCHW_sendNakI2C()  NotAckI2C2()
#define DSRTCCHW_clearCollisionI2C()  SSP2CON1bits.WCOL=0
#define DSRTCCHW_isTXInProgressI2C() SSP2STATbits.R_W
#define DSRTCCHW_isStartInProgressI2C()  SSP2CON2bits.SEN
#define DSRTCCHW_isStopInProgressI2C()  SSP2CON2bits.PEN
#define DSRTCCHW_isRestartInProgressI2C() SSP2CON2bits.RSEN
#define DSRTCCHW_isAckInProgressI2C() SSP1CON2bits.ACKEN
#define DSRTCCHW_isAckNotReceivedI2C()  SSP2CON2bits.ACKSTAT



Code:
DSRTCC_RESULT DSRTCC_getTime(struct DSRTCC_time *dsrtccTime)
{
  unsigned char data;


  DSRTCCHW_idleI2C(); //Check for bus idle condition in multi master communication
  DSRTCCHW_startI2C(); //Start I2Cz
  while (DSRTCCHW_isStartInProgressI2C());

  DSRTCC_transmitByte(DSRTCC_DS1337_I2C_ADDRESS | 0x00); //Write the address of slave for write

  while (DSRTCCHW_isTXInProgressI2C()); //Wait for the transmission to complete

  if (DSRTCCHW_isAckNotReceivedI2C())
  {
  //Send Stop
  DSRTCC_sendStop();
  return DSRTCC_ACK_NOT_RECEIVED;
  }


  DSRTCCHW_idleI2C(); //Check for bus idle condition in multi master communication

  DSRTCC_transmitByte(DSRTCC_REGISTER_SECONDS); //Send the seconds register address

  while (DSRTCCHW_isTXInProgressI2C()); //Wait for the transmission to complete

  if (DSRTCCHW_isAckNotReceivedI2C())
  {
  //Send Stop
  DSRTCC_sendStop();
  return DSRTCC_ACK_NOT_RECEIVED;
  }


  DSRTCCHW_idleI2C(); //Check for bus idle condition in multi master communication
  DSRTCCHW_restartI2C(); //Restart I2C

  while (DSRTCCHW_isRestartInProgressI2C());

  DSRTCCHW_idleI2C(); //Check for bus idle condition in multi master communication
  DSRTCC_transmitByte(DSRTCC_DS1337_I2C_ADDRESS | 0x01); //Write the address of slave for read

  while (DSRTCCHW_isTXInProgressI2C()); //Wait for the transmission to complete

  if (DSRTCCHW_isAckNotReceivedI2C())
  {
  //Send Stop
  DSRTCC_sendStop();
  return DSRTCC_ACK_NOT_RECEIVED;
  }


  DSRTCCHW_idleI2C();
  data = DSRTCCHW_readByteI2C(); // Read the seconds

  dsrtccTime->seconds10sBCD = (unsigned char)(data >> 4);
  dsrtccTime->seconds1sBCD = (unsigned char) (data & 0x0f);
  

  AckI2C2(); // Send an Ack
  DSRTCCHW_isAckInProgressI2C();

  DSRTCCHW_idleI2C();

  data = DSRTCCHW_readByteI2C(); // Read the minutes

  dsrtccTime->minutes10sBCD = (unsigned char)(data >> 4);
  dsrtccTime->minutes1sBCD = (unsigned char)(data & 0x0f);

  DSRTCCHW_sendAckI2C(); // Send an Ack
  DSRTCCHW_isAckInProgressI2C();

  data = DSRTCCHW_readByteI2C(); // Read the hours /

  dsrtccTime->clk_12_24 = (unsigned char)(data & 0b01000000);

  if (dsrtccTime->clk_12_24)
  {
  dsrtccTime->hours10sBCD = (unsigned char)(data & 0b0010000);
  dsrtccTime->AM_PM = 0;
  } else
  {
  dsrtccTime->hours10sBCD = (unsigned char)(data & 0b0110000);
  dsrtccTime->AM_PM = (unsigned char)((data & 0b00010000) >> 5);
  }


  dsrtccTime->hours1sBCD = (unsigned char)(data & 0x0f);
  

  DSRTCC_sendStop();

  return DSRTCC_SUCCESS;
}
 

Thread Starter

kingsloth

Joined Dec 28, 2015
12
I've been hunting around for someone who has used this library with any success and have not found anyone. There are things I suspect are very wrong in the help files, meaning while they are correct code they do not perform the required tasks.

Example: you need to read some data, here is your code that seems to closely follow the help file:
Code:
  if (I2CReceivedDataIsAvailable(I2C1))
  {
      I2CAcknowledgeByte(I2C1, TRUE);
      msb = I2CGetByte(I2C1);
  }
So if the data is ready to read all should be good. But what if your processor if faster that I2C (because it is!)? The IF fails and the data is never read.

Perhaps this would be "better:"
Code:
  while (!I2CReceivedDataIsAvailable(I2C1));
  I2CAcknowledgeByte(I2C1, TRUE);
  msb = I2CGetByte(I2C1);
Now we wait until data is available. I put "better" in quotes as we have stalled the processor waiting for data that may never come, thus an infinite loop.

You initializing the I2C, are you initializing the HMC5833L?

I do note your read code assigns the read back to 0, which is what you get at the end. Looks like nothing is actually read; see if you change the initialization to 0xFF (lines 4&5) you get that same number back.

Again, I suggest getting each simple transaction to work before moving onto the next.

I tried that but it just went to loop forever.To initialize the HMC it is necessary to start i2c configure it and then do stopi2c, that is never done (maybe a bug?) so it is impossible to do the rest.

I made new i2c functions and i think that part is working but negative numbers dont work. If X Y or Z are negative it just return value between 65240 and 65535, any ideias ?
 

spinnaker

Joined Oct 29, 2009
7,837
I tried that but it just went to loop forever.To initialize the HMC it is necessary to start i2c configure it and then do stopi2c, that is never done (maybe a bug?) so it is impossible to do the rest.

I made new i2c functions and i think that part is working but negative numbers dont work. If X Y or Z are negative it just return value between 65240 and 65535, any ideias ?
If it loops forever then you aren't getting a response from the slave.
 

ErnieM

Joined Apr 24, 2011
8,019
I tried that but it just went to loop forever.To initialize the HMC it is necessary to start i2c configure it and then do stopi2c, that is never done (maybe a bug?) so it is impossible to do the rest.

I made new i2c functions and i think that part is working but negative numbers dont work. If X Y or Z are negative it just return value between 65240 and 65535, any ideias ?
Why would you expect valid date from a device you did not initialize?

First step is to init. Then worry about reading. Post your init routine to sent that data. Only after that works would you try to read anything back.

Also, 65240 or 65535 would be negative number if held in a signed variable. In an unsigned variable they look like large numbers; in 2's complement anything with the leading bit a one is negative.
 

Thread Starter

kingsloth

Joined Dec 28, 2015
12
Why would you expect valid date from a device you did not initialize?

First step is to init. Then worry about reading. Post your init routine to sent that data. Only after that works would you try to read anything back.

Also, 65240 or 65535 would be negative number if held in a signed variable. In an unsigned variable they look like large numbers; in 2's complement anything with the leading bit a one is negative.
You understand it wrong. I did init HMC before reading, however it never reaches its end due to I2CStop not working. I dont have the code here at the moment.

I tried initialize them as Signed Int and as Double shouldn't it work? i'm using sprintf aswell...
 

ErnieM

Joined Apr 24, 2011
8,019
You understand it wrong. I did init HMC before reading, however it never reaches its end due to I2CStop not working.
What does "it" mean? What never reaches the end? The init routine?

If you don't stop a transaction the slave will get confused. You MUST start and stop each I2C transaction or what follows (like a read routine) will not work.
 

Thread Starter

kingsloth

Joined Dec 28, 2015
12
What does "it" mean? What never reaches the end? The init routine?

If you don't stop a transaction the slave will get confused. You MUST start and stop each I2C transaction or what follows (like a read routine) will not work.
The HMC init routine. My code to init HMC to be in "Continue Mode" is something like:
-Start i2c
-Send adress to Write
-Send Reg A adress
-Send value to "write" in REG A
-Sendo stopi2c

I did exactly what they say to do in HMC's datasheet.
 
Top