2289725_en-US

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2289725_en-US

2289725_en-US

i2c call back is not getting called

Hello Team,

I am working with a DAC module (MCP47FEB21A0) that is interfaced with an LPC55S69 over I²C.

I observed that I2C_MasterTransferBlocking() works correctly, but when I use I2C_MasterTransferNonBlocking(), the I²C callback is never invoked.

I2C_MasterTransferNonBlocking() is returning kStatus_Success.

For reference, I2C_MasterTransferCreateHandle() is called once during I²C initialization.

Could someone please explain why the I²C callback is not getting called when using I2C_MasterTransferNonBlocking()?

Regards,
Santhosh


Re: i2c call back is not getting called

Hi @sushmasan 

I think you can refer to the  lpcxpresso55s69_lpc_i2c_interrupt_b2b_transfer_master_cm33_core0 SDK demo.

Harry_Zhang_0-1767855362914.png

BR

Harry

Re: i2c call back is not getting called

Hi @Harry_Zhang ,

Thanks for your response.

I have other sensor modules that are working with non-blocking calls.

I am using a BMP390 sensor, and the I²C communication works fine with non-blocking calls. For example, if one of the register addresses is 0x01, I assign the subaddress as shown below:

masterXfer.subaddress = (uint32_t)0x01;


However, for the DAC (MCP47FEB21A0) module, the subaddress is assigned differently:

uint8_t subAddress;
subAddress = (uint8_t)(reg_addr << 3); // Based on the MCP47FEB21A0 datasheet, the register address must be shifted left by 3
masterXfer.subaddress = (uint32_t)subAddress;

Is it going to make any difference?

Regards,
San

Re: i2c call back is not getting called

Hi @sushmasan 

I think you can try to set subaddressSize = 0 and put the DAC’s command byte(s) and data bytes directly in masterXfer.data, then start a write transfer.

BR

Harry

Re: i2c call back is not getting called

Hi @Harry_Zhang ,

I even tried it,

uint8_t txData[3] = {0};

txData[0] = (uint8_t) (reg_addr << 3);

txData[1] = (uint8_t)(data >> 8); /* Data high byte */

txData[2] = (uint8_t)(data & 0xFFU); /* Data low byte */


masterXfer.data = txData;

masterXfer.dataSize = 3; /* 3 bytes total */


I have some data which is of 2 bytes, so after the adding reg addr it becomes 3 bytes.

Still I²C callback is not getting called when I use I2C_MasterTransferNonBlocking().


Regards,

San


Re: i2c call back is not getting called

Yesterday I replied to your message, but mistakenly I did a reply to the topic. I am not sure whether you have noticed it or not, that's why responding to your message again here.


Hi @Harry_Zhang ,

I even tried it,

uint8_t txData[3] = {0};

txData[0] = (uint8_t) (reg_addr << 3);

txData[1] = (uint8_t)(data >> 8); /* Data high byte */

txData[2] = (uint8_t)(data & 0xFFU); /* Data low byte */


masterXfer.data = txData;

masterXfer.dataSize = 3; /* 3 bytes total */


I have some data which is of 2 bytes, so after the adding reg addr it becomes 3 bytes.

Still I²C callback is not getting called when I use I2C_MasterTransferNonBlocking().


Regards,

San

Re: i2c call back is not getting called

Hi  @sushmasan 

Can you share the your code so I can take a look?

BR

Harry

Re: i2c call back is not getting called

Hi @Harry_Zhang ,

Please find the code snippet for your reference,

#define I2C5_BASE                                (0x40096000u)
#define I2C5_MASTER_BASE    (I2C5_BASE)
#define I2C5_MASTER_CLOCK_FREQUENCY (12000000)
#define I2C5_MASTER ((I2C_Type *) I2C5_MASTER_BASE)

static void i2c_master_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
{		
	/* Signal transfer success when received success status. */
	if (status == kStatus_Success)
	{
		// Successfully completed data transfer
		g_MasterCompletionFlag = true;
		g_i2cCallBackStatus = kStatus_Success;
	}
	/* Signal transfer failure when received failure status. */
	else
	{
		if(status == kStatus_I2C_Nak)
		{			
			g_i2cCallBackStatus = kStatus_I2C_Nak;
		}
		else if (status == kStatus_I2C_Addr_Nak)
		{		
			g_i2cCallBackStatus = kStatus_I2C_Addr_Nak;
		}
		else if (status == kStatus_I2C_ArbitrationLost)
		{		
			g_i2cCallBackStatus = kStatus_I2C_ArbitrationLost;
		}
		else
		{		
			g_i2cCallBackStatus = false;
		}
	}

	return;
}

bool i2c_readwrite(i2c_master_transfer_t *masterXfer)
{
	status_t status = kStatus_Fail;
	status_t finalStatus = kStatus_Fail;
	bool retVal = false;
	
	g_MasterCompletionFlag = false;
	g_i2cCallBackStatus = kStatus_Fail;

	/* Send master non-blocking data to slave (Performing the write operation) */
	/* Allowing the CPU to continue executing other tasks in parallel while the I2C transfer is being handled in the background. */
	status = I2C_MasterTransferNonBlocking(I2C5_MASTER, &g_m_handle, masterXfer);

	PRINTF("(%s() => Wait for the data transfer to slave completion. status:%d \r\n",__func__,status);

	/*  Wait for transfer completed. */
	while (!g_MasterCompletionFlag)
	{
	}
	g_MasterCompletionFlag = false;

	// Driver-level error (could not start transfer)
	if(status == kStatus_Success)
		retVal = true;
	// Transfer completed
	else
		retVal = false;
	
	g_i2cCallBackStatus = kStatus_Fail;

	return retVal;
}

// THIS IS WITH I2C NON BLOCKING CALL -> CALL BACK IS NOT GETTING INVOKED.
bool dac_write_reg(uint8_t reg_addr, uint16_t data)
{
	/* The DAC needs 1 address byte + 2 data bytes. */
	static i2c_master_transfer_t masterXfer = {0};
	static uint8_t txData[3] = {0};	
	bool retVal = false;
	bool write_status = false;

	memset(&masterXfer, 0, sizeof(masterXfer));
	
	txData[0] = (uint8_t) (reg_addr << 3); 
	txData[1] = (uint8_t)(data >> 8);     
	txData[2] = (uint8_t)(data & 0xFFU);  

	masterXfer.slaveAddress   = 0x60;     
	masterXfer.direction      = kI2C_Write;
	masterXfer.subaddress     = 0;
	masterXfer.subaddressSize = 0;                      
	masterXfer.data           = txData;
	masterXfer.dataSize       = 3;          
	masterXfer.flags          = kI2C_TransferDefaultFlag; 

	write_status = i2c_readwrite(&masterXfer);
	if(true == write_status)
	{
		PRINTF("(%s) -> I2C write PASS @line:%d \r\n",__func__,__LINE__);

		retVal = true;
	}
	else
	{
		PRINTF("(%s) -> I2C write failed with status %d \r\n",__func__,write_status);

		retVal = false;
	}
	
	return retVal;
}


// THIS IS WITH I2C BLOCKING CALL -> WORKING FINE
int8_t dac_write_reg(uint8_t reg_addr, uint16_t data)
{
	/* The DAC needs 1 address byte + 2 data bytes. */
	i2c_master_transfer_t masterXfer;
	uint8_t txData[2];
	uint8_t subAddress;
	
	memset(&masterXfer, 0, sizeof(masterXfer));

	subAddress = (uint8_t)(reg_addr << 3); /* DAC  reg  byte */
	txData[0] = (uint8_t)(data >> 8);     /* Data high byte */
	txData[1] = (uint8_t)(data & 0xFFU);  /* Data low  byte */

	masterXfer.slaveAddress   = 0x60;      
	masterXfer.direction      = kI2C_Write;
	masterXfer.subaddress     = (uint32_t) subAddress;
	masterXfer.subaddressSize = 1;                      
	masterXfer.data           = txData;
	masterXfer.dataSize       = 2;          
	masterXfer.flags          = kI2C_TransferDefaultFlag; 

	status_t status = I2C_MasterTransferBlocking(I2C5_MASTER, &masterXfer);
	if (status == kStatus_Success) {
		PRINTF("(%s) -> dac_write_reg PASS @line:%d \r\n",__func__,__LINE__);

		status = 1;
	}
	else
	{
		PRINTF("(%s) -> I2C_MasterTransferBlocking() failed with status %d \r\n",__func__,status);

		status = -1;
	}

	return status;
}


int main()
{
	I2C_MasterGetDefaultConfig(&masterConfig);
	
	I2C_MasterInit(I2C5_MASTER, &masterConfig, I2C5_MASTER_CLOCK_FREQUENCY);
	
	I2C_MasterTransferCreateHandle(I2C5_MASTER, &g_m_handle, i2c_master_callback, NULL);

	dac_write_reg(0x08, 0x0001);
}
Re: i2c call back is not getting called

Hi @sushmasan 

i have reviewed your code. 

But I'm sorry, I couldn't find a clear error. I think you can also use an oscilloscope to check if the data transmission is correct and if the returned data is correct.

BR

Harry

Tags (1)
No ratings
Version history
Last update:
‎01-23-2026 04:25 AM
Updated by: