in nRF54L15 getting I2C error code as -5, unable to communicate with I2C peripheral.

Hi Team,

Below function returns error code as -5 and unable to write and read data from I2C peripheral.

err = i2c_write_read(i2c_devaddrwrite_datawrite_sizeread_dataread_size);
#define  EIO 5    /* I/O error */
Can you please provide your inputs to resolve this I2C issue.
Regards,
Sravan Rikka
Parents
  • Thank you! 

    Have you tried reproducing the issue on a DK? Or stepped into the i2c_nrfx_twim_transfer() in v3.1.1\zephyr\drivers\i2c\i2c_nrfx_twim.c, which is ultimately called from i2c_write_read() to see why it returns -5 (-EIO)?

    This is the full function:

    static int i2c_nrfx_twim_transfer(const struct device *dev,
    				  struct i2c_msg *msgs,
    				  uint8_t num_msgs, uint16_t addr)
    {
    	struct i2c_nrfx_twim_data *dev_data = dev->data;
    	const struct i2c_nrfx_twim_common_config *dev_config = dev->config;
    	int ret = 0;
    	uint8_t *msg_buf = dev_config->msg_buf;
    	uint16_t msg_buf_used = 0;
    	uint16_t msg_buf_size = dev_config->msg_buf_size;
    	uint8_t *buf;
    	uint16_t buf_len;
    
    	(void)i2c_nrfx_twim_exclusive_access_acquire(dev, K_FOREVER);
    
    	/* Dummy take on completion_sync sem to be sure that it is empty */
    	k_sem_take(&dev_data->completion_sync, K_NO_WAIT);
    
    	for (size_t i = 0; i < num_msgs; i++) {
    		if (I2C_MSG_ADDR_10_BITS & msgs[i].flags) {
    			ret = -ENOTSUP;
    			break;
    		}
    
    		bool dma_accessible = nrf_dma_accessible_check(&dev_config->twim, msgs[i].buf);
    
    		/* This fragment needs to be merged with the next one if:
    		 * - it is not the last fragment
    		 * - it does not end a bus transaction
    		 * - the next fragment does not start a bus transaction
    		 * - the direction of the next fragment is the same as this one
    		 */
    		bool concat_next = ((i + 1) < num_msgs)
    				&& !(msgs[i].flags & I2C_MSG_STOP)
    				&& !(msgs[i + 1].flags & I2C_MSG_RESTART)
    				&& ((msgs[i].flags & I2C_MSG_READ)
    				    == (msgs[i + 1].flags & I2C_MSG_READ));
    
    		/* If we need to concatenate the next message, or we've
    		 * already committed to concatenate this message, or its buffer
    		 * is not accessible by DMA, add it to the internal driver
    		 * buffer after verifying there's room.
    		 */
    		if (concat_next || (msg_buf_used != 0) || !dma_accessible) {
    			if ((msg_buf_used + msgs[i].len) > msg_buf_size) {
    				LOG_ERR("Need to use the internal driver "
    					"buffer but its size is insufficient "
    					"(%u + %u > %u). "
    					"Adjust the zephyr,concat-buf-size or "
    					"zephyr,flash-buf-max-size property "
    					"(the one with greater value) in the "
    					"\"%s\" node.",
    					msg_buf_used, msgs[i].len,
    					msg_buf_size, dev->name);
    				ret = -ENOSPC;
    				break;
    			}
    			if (!(msgs[i].flags & I2C_MSG_READ)) {
    				memcpy(msg_buf + msg_buf_used,
    				       msgs[i].buf,
    				       msgs[i].len);
    			}
    			msg_buf_used += msgs[i].len;
    		}
    
    		if (concat_next) {
    			continue;
    		}
    
    		if (msg_buf_used == 0) {
    			buf = msgs[i].buf;
    			buf_len = msgs[i].len;
    		} else {
    			buf = msg_buf;
    			buf_len = msg_buf_used;
    		}
    		ret = i2c_nrfx_twim_msg_transfer(dev, msgs[i].flags, buf, buf_len, addr);
    		if (ret < 0) {
    			break;
    		}
    
    		ret = k_sem_take(&dev_data->completion_sync,
    				 I2C_TRANSFER_TIMEOUT_MSEC);
    		if (ret != 0) {
    			/* Whatever the frequency, completion_sync should have
    			 * been given by the event handler.
    			 *
    			 * If it hasn't, it's probably due to an hardware issue
    			 * on the I2C line, for example a short between SDA and
    			 * GND.
    			 * This is issue has also been when trying to use the
    			 * I2C bus during MCU internal flash erase.
    			 *
    			 * In many situation, a retry is sufficient.
    			 * However, some time the I2C device get stuck and need
    			 * help to recover.
    			 * Therefore we always call i2c_nrfx_twim_recover_bus()
    			 * to make sure everything has been done to restore the
    			 * bus from this error.
    			 */
    			(void)i2c_nrfx_twim_recover_bus(dev);
    			ret = -EIO;
    			break;
    		}
    
    		if (dev_data->res != NRFX_SUCCESS) {
    			ret = -EIO;
    			break;
    		}
    
    		/* If concatenated messages were I2C_MSG_READ type, then
    		 * content of concatenation buffer has to be copied back into
    		 * buffers provided by user. */
    		if ((msgs[i].flags & I2C_MSG_READ) && (buf == msg_buf)) {
    			int j = i;
    
    			while (msg_buf_used >= msgs[j].len) {
    				msg_buf_used -= msgs[j].len;
    				memcpy(msgs[j].buf,
    				       msg_buf + msg_buf_used,
    				       msgs[j].len);
    				j--;
    			}
    
    		}
    
    		msg_buf_used = 0;
    	}
    
    	i2c_nrfx_twim_exclusive_access_release(dev);
    
    	return ret;
    }

    and as you can see, there are several possible routes to return -EIO. Either k_sem_take(&dev_data->completion_sync, I2C_TRANSFER_TIMEOUT_MSEC); returned an error, or dev_data->res != NRFX_SUCCESS, or possibly i2c_nrfx_twim_msg_transfer() returned -EIO.

    Are you able to see which one it is? 

    Best regards,

    Edvin

  • Hi Edvin,

    Have you tried reproducing the issue on a DK?

    No, we don't have DK boards.

    We are using 'i2c_write_read()' function and getting -5 from this function. Attached our test code.

    Please provide your inputs to resolve this. We are stuck up in board bring up activity.

    We have 5 I2C slave on board. We are able to communicate successfully and getting data from the 3 slaves but getting -5 error from two slaves. We are using 10K pullup resistor.


    I2C communication code.docx

    Regards,

    Sravan Rikka

Reply
  • Hi Edvin,

    Have you tried reproducing the issue on a DK?

    No, we don't have DK boards.

    We are using 'i2c_write_read()' function and getting -5 from this function. Attached our test code.

    Please provide your inputs to resolve this. We are stuck up in board bring up activity.

    We have 5 I2C slave on board. We are able to communicate successfully and getting data from the 3 slaves but getting -5 error from two slaves. We are using 10K pullup resistor.


    I2C communication code.docx

    Regards,

    Sravan Rikka

Children
Related