2289725_ja-JP

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

2289725_ja-JP

2289725_ja-JP

i2cコールバックが呼び出されない

こんにちは、チームの皆さん

私は、I²C 経由で LPC55S69 とインターフェースされた DAC モジュール (MCP47FEB21A0) を使用しています。

I2C_MasterTransferBlocking() は正常に動作することを確認しましたが、I2C_MasterTransferNonBlocking() を使用すると、I²C コールバックが呼び出されません。

I2C_MasterTransferNonBlocking() は kStatus_Success を返します。

参考までに、I2C_MasterTransferCreateHandle() は I²C 初期化中に 1 回呼び出されます。

I2C_MasterTransferNonBlocking() を使用しているときに I²C コールバックが呼び出されない理由を説明していただけますか?

よろしくお願いいたします。
サントシュ


Re: i2c call back is not getting called

こんにちは@sushmasan

lpcxpresso55s69_lpc_i2c_interrupt_b2b_transfer_master_cm33_core0 SDK デモを参照できると思います。

Harry_Zhang_0-1767855362914.pngHarry_Zhang_0-1767855362914.png

BR

ハリー

Re: i2c call back is not getting called

こんにちは@Harry_Zhang

ご回答ありがとうございます。

非ブロッキング呼び出しで動作している他のセンサ モジュールがあります。

私は BMP390 センサを使用しており、I²C 通信は非ブロッキング呼び出しで正常に動作します。たとえば、レジスタ アドレスの 1 つが 0x01 の場合、サブアドレスを次のように割り当てます。

マスターXfer.サブアドレス = (uint32_t)0x01;


ただし、DAC (MCP47FEB21A0) モジュールの場合、サブアドレスの割り当ては異なります。

uint8_t サブアドレス;
subAddress = (uint8_t)(reg_addr << 3); // MCP47FEB21A0データシートによると、レジスタアドレスは3だけ左にシフトする必要がある。
masterXfer.subaddress = (uint32_t)subAddress;

何か違いはあるでしょうか?

よろしくお願いいたします。
サン

Re: i2c call back is not getting called

こんにちは@sushmasan

subaddressSize = 0 に設定して、DACのコマンドバイトとデータバイトをmasterXfer.dataに直接配置してみるといいと思います。次に書き込み転送を開始します。

BR

ハリー

Re: i2c call back is not getting called

こんにちは@Harry_Zhang

私も試してみましたが、

uint8_t txData[3] = {0};

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

txData[1] = ( uint8_t )(data >> 8); /* データ上位バイト */

txData[2] = ( uint8_t )(data & 0xFFU); /* データ下位バイト */


マスターXfer.data = txData;

masterXfer. dataSize = 3; /* 合計3バイト */


2 バイトのデータがあるため、reg addr を追加すると 3 バイトになります。

I2C_MasterTransferNonBlocking() を使用すると、依然として I²C コールバックが呼び出されません。


よろしくお願いいたします。

サン


Re: i2c call back is not getting called

昨日あなたのメッセージに返信しましたが、誤ってトピックに返信してしまいました。あなたが気づいているかどうかわかりませんが、ここで再度あなたのメッセージに返信します。


こんにちは@Harry_Zhang

私も試してみましたが、

uint8_t txData[3] = {0};

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

txData[1] = ( uint8_t )(data >> 8); /* データ上位バイト */

txData[2] = ( uint8_t )(data & 0xFFU); /* データ下位バイト */


マスターXfer.data = txData;

masterXfer. dataSize = 3; /* 合計3バイト */


2 バイトのデータがあるため、reg addr を追加すると 3 バイトになります。

I2C_MasterTransferNonBlocking() を使用すると、依然として I²C コールバックが呼び出されません。


よろしくお願いいたします。

サン

Re: i2c call back is not getting called

こんにちは@sushmasan

確認できるようにコードを共有していただけますか?

BR

ハリー

Re: i2c call back is not getting called

こんにちは@Harry_Zhang

参考までにコードスニペットをご覧ください。

#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

こんにちは@sushmasan

あなたのコードを確認しました。

しかし、申し訳ありませんが、明らかな誤りは見つかりませんでした。オシロスコープを使用して、データの送信が正しいかどうか、返されたデータが正しいかどうかを確認することもできると思います。

BR

ハリー

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