I think, either correct data isn't written to or read from the device.
Logically if I consider I2C operation, then the library function sequence what is maintained for communication looks correct
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP430FR5994
Hi Everyone,
I am trying to implement I2C MASTER Read write operation in MSP430FR5994 using available library function to communicate with slave devices (RTC and Counter) as shown below but unfortunately it's not working as expected
We haven't observed below points while debugging,
-> Any infinite loop stuck condition while debugging
-> No hardware side issue like pullup
(Project execution priority level is high)
/* Code Start *********************************/
void i2cPinInt()
{
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,
GPIO_PIN0 | GPIO_PIN1,
GPIO_PRIMARY_MODULE_FUNCTION
);
}
// u16_i2cBase -> EUSCI_B1_BASE
void EUSCI_B_I2C_INIT(uint16_t u16_i2cBase, uint32_t u32_dataRate)
{
EUSCI_B_I2C_initMasterParam i2cParam = {0};
// i2c parameters
i2cParam.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
i2cParam.i2cClk = CS_getSMCLK();
i2cParam.dataRate = u32_dataRate;
i2cParam.byteCounterThreshold = 0;
i2cParam.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
// Initializing Master
EUSCI_B_I2C_initMaster(u16_i2cBase, &i2cParam);
// Enable I2C module
EUSCI_B_I2C_enable(u16_i2cBase);
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
return;
}
void i2cReadByte(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data
)
{
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendSingleByte(u16_i2cBase, u8_regAddr);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
// Receive data
*pu8_data = EUSCI_B_I2C_masterReceiveSingleByte(u16_i2cBase);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
return;
}
void i2cReadBytes(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data, uint16_t u16_length
)
{
uint16_t u16_index = 0;
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendSingleByte(u16_i2cBase, u8_regAddr);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
// Master receive begin
EUSCI_B_I2C_masterReceiveStart(u16_i2cBase);
// Receive data
for(u16_index = 0; u16_index < u16_length - 1; ++u16_index)
{
while(!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_RECEIVE_INTERRUPT0));
pu8_data[u16_index] = EUSCI_B_I2C_masterReceiveMultiByteNext(u16_i2cBase);
}
// Receive last byte
pu8_data[u16_index] = EUSCI_B_I2C_masterReceiveMultiByteFinish(u16_i2cBase);
return;
}
void i2cWriteByte(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data
)
{
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
EUSCI_B_I2C_masterSendMultiByteStart(u16_i2cBase, u8_regAddr);
while(!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_INTERRUPT0));
// Send data
EUSCI_B_I2C_masterSendMultiByteFinish(u16_i2cBase, pu8_data[0]);
return;
}
void i2cWriteBytes(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data, uint16_t u16_length
)
{
uint8_t u8_index = 0;
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendMultiByteStart(u16_i2cBase, u8_regAddr);
// Transmit data
for(u8_index = 0; u8_index < (u16_length - 1); ++u8_index)
{
while (!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_INTERRUPT0));
EUSCI_B_I2C_masterSendMultiByteNext(u16_i2cBase, pu8_data[u8_index]);
}
// Transmit last byte
EUSCI_B_I2C_masterSendMultiByteFinish(u16_i2cBase, pu8_data[u8_index]);
return;
}
/* ******************************** Code End */
Please assist us with validating the same
Thanks
2) How doesn't it work? Fails to start? Slave doesn't respond? Data isn't read? Written?
I think, either correct data isn't written to or read from the device.
Logically if I consider I2C operation, then the library function sequence what is maintained for communication looks correct
1) Use the "Insert: Code" feature of the editor for your code.
As per my understanding you are asking to include the driver code during project creation, if yes then we have done the same while creating the project
2) How doesn't it work? Fails to start? Slave doesn't respond? Data isn't read? Written?
I think, correct data isn't written to device or read from the device.
Logically if I consider I2C operation then the library function sequence what is maintained for i2c operation looks correct
void EUSCI_B_I2C_INIT(uint16_t u16_i2cBase, uint32_t u32_dataRate)
{
EUSCI_B_I2C_initMasterParam i2cParam = {0};
// i2c parameters
i2cParam.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
i2cParam.i2cClk = CS_getSMCLK();
i2cParam.dataRate = u32_dataRate;
i2cParam.byteCounterThreshold = 0;
i2cParam.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
// Initializing Master
EUSCI_B_I2C_initMaster(u16_i2cBase, &i2cParam);
// Enable I2C module
EUSCI_B_I2C_enable(u16_i2cBase);
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
return;
}
void i2cReadByte(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data
)
{
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendSingleByte(u16_i2cBase, u8_regAddr);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
// Receive data
*pu8_data = EUSCI_B_I2C_masterReceiveSingleByte(u16_i2cBase);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
return;
}
void i2cReadBytes(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data, uint16_t u16_length
)
{
uint16_t u16_index = 0;
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendSingleByte(u16_i2cBase, u8_regAddr);
while(EUSCI_B_I2C_isBusBusy(u16_i2cBase));
// Master receive begin
EUSCI_B_I2C_masterReceiveStart(u16_i2cBase);
// Receive data
for(u16_index = 0; u16_index < u16_length - 1; ++u16_index)
{
while(!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_RECEIVE_INTERRUPT0));
pu8_data[u16_index] = EUSCI_B_I2C_masterReceiveMultiByteNext(u16_i2cBase);
}
// Receive last byte
pu8_data[u16_index] = EUSCI_B_I2C_masterReceiveMultiByteFinish(u16_i2cBase);
return;
}
void i2cWriteByte(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data
)
{
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
EUSCI_B_I2C_masterSendMultiByteStart(u16_i2cBase, u8_regAddr);
while(!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_INTERRUPT0));
// Send data
EUSCI_B_I2C_masterSendMultiByteFinish(u16_i2cBase, pu8_data[0]);
return;
}
void i2cWriteBytes(uint16_t u16_i2cBase,
uint8_t u8_slaveId, uint8_t u8_regAddr,
uint8_t *pu8_data, uint16_t u16_length
)
{
uint8_t u8_index = 0;
// Set slave id in i2c bus
EUSCI_B_I2C_setSlaveAddress(u16_i2cBase, u8_slaveId);
// Switch to transmit mode
EUSCI_B_I2C_setMode(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_MODE);
// Send register address first
EUSCI_B_I2C_masterSendMultiByteStart(u16_i2cBase, u8_regAddr);
// Transmit data
for(u8_index = 0; u8_index < (u16_length - 1); ++u8_index)
{
while (!EUSCI_B_I2C_getInterruptStatus(u16_i2cBase, EUSCI_B_I2C_TRANSMIT_INTERRUPT0));
EUSCI_B_I2C_masterSendMultiByteNext(u16_i2cBase, pu8_data[u8_index]);
}
// Transmit last byte
EUSCI_B_I2C_masterSendMultiByteFinish(u16_i2cBase, pu8_data[u8_index]);
return;
}I2C initialization is successful (on successful initialization LED gets ON as per program)
.
All library function's return type is void, there is no success / fail indication
-> In write operation, the exact data is being written
-> In read operation, read data is different
The reason behind unable to decide where exactly it is getting wrong because of
-> The maintained sequence in read/write operation
(As per my understanding it looks correct)
-> Any other function which should be included but it's missed from our side
So I shared code, h/w side everything is fine
I don't see anything obviously wrong with the code.
1) How are you calling these functions? Maybe there's a clue there.
2) Your read sequence doesn't use Repeated-Start. Some devices require R-S, some prohibit it, most don't care (and it's not always easy to tell from the datasheet). Can you give us part numbers for the specific devices you're using?
3) General: The driverlib functions don't deal gracefully with NACK, so watch out for that.
If you have a scope, that could be very helpful.
Connected devices are DS3231 (RTC) and counter
(Both the devices are working fine with TI-RTOS package without fail)
.
As per the latest observation,
- > Read operation is working fine, default values are coming without any problem
-> But the moment we are performing write operation, read values are becoming random
**Attention** This is a public forum