Poling problem for I2C

Hello,

I trying to use I2C on the RSL10 for take some data from sensors. I have an issue with the pending argument of the function I2C_MasterTransmit.

I start my code from the I2C_cmsis_driver example and I made a few change. First I remove all the call back from I2c and I had while(i2c->info->status.busy){} just before the return of the I2C_MasterTransmit() function. Like sugest in this post : RSL 10 I2C setup doubt

For testing, I plug an sensor with the adress 0x48 and in my main, I just call the fonction Initialize(); and then I send to I2C message
uint8_t data[3]={0,0,0};
i2c->MasterTransmit( 0x48,data, 3, true);
i2c->MasterTransmit( 0x48,data, 3, false);
But the problem is in my oscilocope I have for both of my message the stop at the end of the frame (the orange square in the screenshot)

I don’t know how not generate the stop. I use the RLS10SIP and i use the pin11 for clk and 10 for data.

Do you have any suggestion ?

Alban

Greetings Alban - welcome to the community!

You have correctly identified a mismatch between the comment and the actual function of the driver. We will work on addressing this for a future release. In the meantime, a suggested work-around is to modify the I2Cx_MasterIRQHandler() code that checks for the end of the data transmission as follows:

                /* Check the data counter */
                if (i2c->xfer->cnt == i2c->xfer->num)
                {
                	if (!i2c->xfer->pending) {
                		/* Set last data flag */
                		I2C_CTRL1->LAST_DATA_ALIAS = I2C_LAST_DATA_BITBAND;
                	} else {
                		/* Indicate transfer incomplete */
                		event |= ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
                		i2c->info->status.busy = I2C_FREE;
                	}
                }

I’ve been able to test the I2C operation with a typical I2C slave with that modification and sample I2C read/write routines as follows:

int32_t I2C0Write(uint8_t slvAddr, uint8_t regAddr, uint8_t val) {
	int32_t result = 0;
	uint8_t buf[2];

	buf[0] = regAddr;
	buf[1] = val;
	result = i2c->MasterTransmit((uint32_t)slvAddr, buf, 2, false);
	i2cBusyWait();

	return(result);
}

int32_t I2C0WriteN(uint8_t slvAddr, uint8_t regAddr, uint8_t *buf, uint8_t count) {
	int32_t result = 0;
	uint8_t _buf[17];
	int32_t i;

	_buf[0] = regAddr;
	if (count > 16) return (-1);
	for (i = 0; i < count; i++)
		_buf[i+1] = buf[i];
	result = i2c->MasterTransmit((uint32_t)slvAddr, _buf, count + 1, false);
	i2cBusyWait();

	return(result);
}

int32_t I2C0Read(uint8_t slvAddr, uint8_t regAddr, uint8_t *val) {
	int32_t result = 0;

	result = i2c->MasterTransmit((uint32_t)slvAddr, &regAddr, 1, true);
	i2cBusyWait();
	if (result == ARM_DRIVER_OK) {
		result = i2c->MasterReceive((uint32_t)slvAddr, val, 1, false);
		i2cBusyWait();
	}
	return(result);
}

int32_t I2C0ReadN(uint8_t slvAddr, uint8_t regAddr, uint8_t *buf, uint8_t count) {
	int32_t result = 0;

	result = i2c->MasterTransmit((uint32_t)slvAddr, &regAddr, 1, true);
	i2cBusyWait();
	if (result == ARM_DRIVER_OK) {
		result = i2c->MasterReceive((uint32_t)slvAddr, buf, count, false);
		i2cBusyWait();
	}
	return(result);
}

void i2cBusyWait() {
	ARM_I2C_STATUS status;

	status = i2c->GetStatus();
	while(status.busy)
		status = i2c->GetStatus();
}

Thank you for using the Community Forum.
3 Likes

Hello,

Thank’s for the answer, this resolve the problem :slight_smile:

2 Likes

thanks for the awesome information.