Hi,
I'm trying to implement an I2C driver as following for a MMA8452 (accelerometer)
I wrote following driver. However, I got some very strange output from the uC. When I tried to retrieve a single byte data from the bus, it always tried to get two bytes. And the I2C bus got locked up after the uC sent out clocks for the second byte. The only way to get out of the lockup is to power cycle the board. Why did the uC try to get the second byte? I even specifically used EUSCI_B_I2C_masterReceiveSingleByte, but the uC still tried to get the second byte.
uint8_t I2C_read_byte(uint8_t slave_address, uint8_t reg_address, uint8_t len, uint8_t *data){
uint8_t i;
uint16_t retry=0x1000;
//Enable I2C Module to start operations
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,slave_address);
//Set in transmit mode
EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Send the register address */
EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE,reg_address);
//Poll for transmit interrupt flag.
while(!(HWREG16(EUSCI_B0_BASE + OFS_UCBxIFG) & UCTXIFG) && retry)
{
retry--;
}
if(!retry) {
return I2C_TIME_OUT;
}
/* Set eUSCI_B0 in receive mode */
EUSCI_B_I2C_setMode(EUSCI_B0_BASE,EUSCI_B_I2C_RECEIVE_MODE);
data[0]=EUSCI_B_I2C_masterReceiveSingleByte(EUSCI_B0_BASE);
/*if(len==1){
data[0]=EUSCI_B_I2C_masterReceiveSingleByte(EUSCI_B0_BASE);
}
else
{
EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE);
for(i=0;i<len-1;i++)
data[i] = EUSCI_B_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
data[len-1]=EUSCI_B_I2C_masterReceiveMultiByteFinish(EUSCI_B0_BASE);
}*/
return 0;
}