i2c call back is not getting called

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

i2c call back is not getting called

830 Views
sushmasan
Contributor II

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

 

0 Kudos
Reply
8 Replies

639 Views
sushmasan
Contributor II

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

 

0 Kudos
Reply

792 Views
Harry_Zhang
NXP Employee
NXP Employee

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

0 Kudos
Reply

771 Views
sushmasan
Contributor II

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

0 Kudos
Reply

678 Views
Harry_Zhang
NXP Employee
NXP Employee

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

0 Kudos
Reply

600 Views
sushmasan
Contributor II

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

0 Kudos
Reply

327 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi  @sushmasan 

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

BR

Harry

0 Kudos
Reply

288 Views
sushmasan
Contributor II

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);
}
0 Kudos
Reply

110 Views
Harry_Zhang
NXP Employee
NXP Employee

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

0 Kudos
Reply