Skip to content

Commit

Permalink
Fix I2C Read Sequence extra unused byte transmission error
Browse files Browse the repository at this point in the history
Due to extra unused byte transmission in the Read Sequence,causing I2C cannot successfully pass
test_connection function.

Bug discription:

Predicted Reading Sequence
Master   |S|AD+W|   |RA|   |S|AD+R|   |    |NACK|P|
Slave    | |    |ACK|  |ACK| |    |ACK|DATA|    | |

But,in the second Start condition,original code could cause extra byte(because using RestartI2C() function).
Using StopI2C() and then StartI2C() can fix this error
  • Loading branch information
Daichou committed Apr 4, 2017
1 parent 43cf365 commit 86c4e0e
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 98 deletions.
@@ -1,5 +1,5 @@
#
#Tue Apr 04 10:56:56 CST 2017
#Tue Apr 04 21:56:23 CST 2017
default.com-microchip-mplab-nbide-toolchainXC16-XC16LanguageToolchain.md5=ebaa75370c1463d650408e4144ba15de
default.languagetoolchain.dir=/opt/microchip/xc16/v1.30/bin
configurations-xml=e23099a44127c530cab293bfc5554ec5
Expand Down
43 changes: 30 additions & 13 deletions dsPIC30F/MPU6050/Examples/MPU6050_example.X/I2Cdev.c
Expand Up @@ -101,7 +101,7 @@ int8_t I2Cdev_readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
IFS0bits.MI2CIF = 0; // Clear interrupt flag
//while(I2CSTATbits.ACKSTAT);
//delay_ms_I2C(10);
//delay_us_I2C(100);
/*Master send RA*/
/* Write Register Address */
MasterWriteI2C(regAddr);
Expand All @@ -114,36 +114,43 @@ int8_t I2Cdev_readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
IFS0bits.MI2CIF = 0; // Clear interrupt flag
while(I2CSTATbits.ACKSTAT);

//delay_ms_I2C(10);
//delay_us_I2C(100);

/*Master Pause*/
StopI2C();
/* Wait till stop sequence is completed */
while(I2CCONbits.PEN);

/*Master Start*/
RestartI2C();
StartI2C();
/* Wait till Start sequence is completed */
while(I2CCONbits.SEN);

/*Master send AD+R*/
/* Write Slave Address (Read)*/
MasterWriteI2C(devAddr << 1 | 0x01);
//while(!MasterWriteI2C(devAddr << 1 | 0x01));
/* Wait until address is transmitted */
while(I2CSTATbits.TBF); // 8 clock cycles

/*Slave send Ack*/
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
IFS0bits.MI2CIF = 0; // Clear interrupt flag
while(I2CSTATbits.ACKSTAT);
//delay_ms_I2C(10);
//delay_us_I2C(100);

/*Slave send DATA*/
//uint16_t flag = MastergetsI2C(length,data,I2C_DATA_WAIT);

/*Slave send NACK*/
//MastergetsI2C(length,data,100);
//NotAckI2C();

data[0] = MasterReadI2C();
unsigned int i;
for (i = 1 ; i < length ; i++ ){
AckI2C();
while(I2CCONbits.ACKEN == 1);
//delay_ms_I2C(10);
data[i] = MasterReadI2C();
}
NotAckI2C();
Expand All @@ -153,8 +160,8 @@ int8_t I2Cdev_readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_
/* Wait till stop sequence is completed */
while(I2CCONbits.PEN);
//CloseI2C();
IdleI2C();
return true;
//IdleI2C();
return length;
}

/** Read single byte from an 8-bit device register.
Expand Down Expand Up @@ -290,7 +297,6 @@ bool I2Cdev_writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t
while(I2CCONbits.SEN);
/* Clear interrupt flag */
IFS0bits.MI2CIF = 0;
//delay_ms_I2C(10);

/*Master send AD+W*/
/* Write Slave address (Write)*/
Expand All @@ -302,7 +308,7 @@ bool I2Cdev_writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
IFS0bits.MI2CIF = 0; // Clear interrupt flag
while(I2CSTATbits.ACKSTAT);
//delay_ms_I2C(10);
//delay_us_I2C(100);

/*Master send RA*/
/* Write Slave address (Write)*/
Expand All @@ -313,20 +319,31 @@ bool I2Cdev_writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t
/*Slave send ACK*/
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
IFS0bits.MI2CIF = 0; // Clear interrupt flag
//delay_ms_I2C(10);
//delay_us_I2C(100);
while(I2CSTATbits.ACKSTAT);

/*Master send data*/
/* Transmit string of data */
MasterputsI2C(data);
//uint8_t i;
//for (i = 0 ; i < length ; i++){
// MasterWriteI2C(data[i]);
/* Wait till address is transmitted */
// while(I2CSTATbits.TBF); // 8 clock cycles

/*Slave send ACK*/
// while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
// IFS0bits.MI2CIF = 0; // Clear interrupt flag
//delay_us_I2C(100);
//}
while(!IFS0bits.MI2CIF); // Wait for 9th clock cycle
IFS0bits.MI2CIF = 0; // Clear interrupt flag

StopI2C();
/* Wait till stop sequence is completed */
while(I2CCONbits.PEN);
//CloseI2C();
IdleI2C();
//IdleI2C();
return true;
}

Expand Down Expand Up @@ -419,7 +436,7 @@ bool I2Cdev_writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_
data &= mask; // zero all non-important bits in data
b &= ~(mask); // zero all important bits in existing byte
b |= data; // combine data with existing byte
delay_ms_I2C(10);
//delay_ms_I2C(10);
return I2Cdev_writeByte(devAddr, regAddr, b);
} else {
return false;
Expand Down
15 changes: 4 additions & 11 deletions dsPIC30F/MPU6050/Examples/MPU6050_example.X/MPU6050.c
Expand Up @@ -90,17 +90,10 @@ void MPU6050(uint8_t address)
*/
void MPU6050_initialize()
{


MPU6050_setSleepEnabled(
false); // thanks to Jack Elston for pointing this one out!
delay_ms(20);
MPU6050_setClockSource(MPU6050_CLOCK_PLL_XGYRO);
delay_ms(20);
MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
delay_ms(20);
MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_250);
delay_ms(100);
MPU6050_setClockSource(MPU6050_CLOCK_PLL_XGYRO);
MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_250);
MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
MPU6050_setSleepEnabled(false);
}

/** Verify the I2C connection.
Expand Down

0 comments on commit 86c4e0e

Please sign in to comment.