Other Parts Discussed in Thread: LDC1614, HALCOGEN
Hello,
I'm implementing my firmware to communicate with an LDC1614 through I2C protocol. I want to implement interrupt based communication.
However, I noticed that when I set the data length to '1', the interrupt is not generated. I'm reading a register here, for that I need to send the register address (8 bit) and then read two bytes for data.
If I write 1 byte as follows, it does not generate the TX interrupt.
i2cSend(i2cREG1, 1U, LDC1614_TX_Data_Buffer);
However, if I change the code as follows, it generates the TX interrupt.
i2cSend(i2cREG1, 2U, LDC1614_TX_Data_Buffer);
Please note that i2cREG1 and buffer has correct data.
Please let me know whether I'm doing something irregular here.
Thanks.
PS:
I dug into the i2c library and found something which looks like a bug,
void i2cSend(i2cBASE_t *i2c, uint32 length, uint8 * data)
{
/* USER CODE BEGIN (17) */
/* USER CODE END */
if ((g_i2cTransfer_t.mode & (uint32)I2C_TX_INT) != 0U)
{
/* Interrupt mode */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
g_i2cTransfer_t.data = data;
/* start transmit by sending first byte */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
i2c->DXR = (uint32)(*g_i2cTransfer_t.data);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_i2cTransfer_t.data++;
/* Length -1 since one data is written already */
g_i2cTransfer_t.length = (length - 1U);
/* Enable Transmit Interrupt */
i2c->IMR |= (uint32)I2C_TX_INT;
}
When i2cSend deals wtih 1 byte messages as above, it sets the g_i2cTransfer_t.length to 0.
In the interrupt function,
case 5U:
/* USER CODE BEGIN (42) */
/* USER CODE END */
/* transmit */
if (g_i2cTransfer_t.length > 0U)
{
i2cREG1->DXR = *g_i2cTransfer_t.data;
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_i2cTransfer_t.data++;
g_i2cTransfer_t.length--;
if(g_i2cTransfer_t.length == 0U)
{ /* Disable TX interrupt after desired data count transfered*/
i2cREG1->IMR &= (uint32)(~(uint32)I2C_TX_INT);
i2cNotification(i2cREG1, (uint32)I2C_TX_INT);
}
}
break;
The notification is generated only if 'length > 0'. I think the (length == 0) condition should come out from (length > 0) condition as this will never generate a notification when i2c data length is 1.
I will check this further tomorrow, please confirm.
Thanks!