This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Issue with I2C burst write function

I need to use a burst write i2c function to write the dmp library for the MPU6050 gyroscope.

The current function that I've been using does not work for this case:

uint32_t nrf_drv_mpu_write_registers(uint8_t reg, uint8_t * p_data, uint32_t length)
{
    // This burst write function is not optimal and needs improvement.
    // The new SDK 11 TWI driver is not able to do two transmits without repeating the ADDRESS + Write bit byte
    uint32_t err_code;
    uint32_t timeout = MPU_TWI_TIMEOUT;

    // Merging MPU register address and p_data into one buffer.
    merge_register_and_data(twi_tx_buffer, reg, p_data, length);

    // Setting up transfer
    nrf_drv_twi_xfer_desc_t xfer_desc;
    xfer_desc.address = MPU_ADDRESS;
    xfer_desc.type = NRF_DRV_TWI_XFER_TX;
    xfer_desc.primary_length = length + 1;
    xfer_desc.p_primary_buf = twi_tx_buffer;

    // Transferring
    err_code = nrf_drv_twi_xfer(&m_twi_instance, &xfer_desc, 0);

    while((!twi_tx_done) && --timeout);
    if(!timeout) return NRF_ERROR_TIMEOUT;
    twi_tx_done = false;

    return err_code;
}

And, I've been researching on another solution:

 

/** Write multiple bytes to an 8-bit device register.
 * @param devAddr I2C slave device address
 * @param regAddr First register address to write to
 * @param length Number of bytes to write
 * @param data Buffer to copy new data from
 * @return Status of operation (true = success)
 */
bool i2cdev_writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) {
	
	/*
	if (NRF_SUCCESS!=nrf_drv_twi_tx(&m_twi,devAddr,&regAddr,1,true))
		return false;
	return NRF_SUCCESS==nrf_drv_twi_tx(&m_twi,devAddr,data,length,false);
	*/
	
	//TODO: This could be improved...
	uint8_t buffer[32];
	buffer[0] = regAddr;
	uint8_t i = 1;
	while(i < (length + 1))
		buffer[i++] = *data++;
	
	return NRF_SUCCESS==nrf_drv_twi_tx(&m_twi,devAddr,buffer,length+1,false);
}

From this code, it writes to consecutive register addresses. 

I'm curious if I can change the no_stop parameter to true to allow burst write to multiple bytes of data but single address.

  • Hi

    It should be possible to call nrf_drv_twi_tx mulitple times with the no_stop bit set true, to allow you to do a write followed by a repeated start and another write. You just have to make sure that the last transaction sets no_stop to false, to properly finish the transaction. 

    This hasn't been extensively tested though, as most sensors either just use a normal write or a write followed by a read. 

    Best regards
    Torbjørn

Related