I2C Block Write Doesn't Work

Hi,

I am currently working on SoC sensor, which is there is a process for uploading firmware from the controller to a sensor through I2C. So I am creating a function for read_block and write_block. Read block do save data from I2C to a array buffer, and write block write a buffer through I2C.

Below is my code for block read and block write.

/**************************************************************************//**
 * @brief Write a Block
 *****************************************************************************/
uint8_t i2c_block_write(uint8_t device, uint8_t address, uint8_t length, uint8_t const *data)
{
	
		uint8_t ret;
  uint8_t i2c_write_data[length+1];

  i2c_write_data[0] = address ;
  for (int i = 0; i < length+1; i++) {
    i2c_write_data[i + 1] = data[i];
  }

  ret = nrf_drv_twi_tx(&m_twi, device, i2c_write_data, sizeof(i2c_write_data),false);
	while(nrf_drv_twi_is_busy(&m_twi));
  
  return ret;
}

/**************************************************************************//**
 * @brief Read a Block
 *****************************************************************************/
uint8_t i2c_block_read(uint8_t device, uint8_t address, uint16_t length, uint8_t *data)
{
	uint8_t ret;
	uint8_t register_address[1];

  register_address[0] = address;
	nrf_drv_twi_tx(&m_twi, device, register_address, sizeof(register_address),true);
	while (m_xfer_done == false);
	while(nrf_drv_twi_is_busy(&m_twi));
  ret = nrf_drv_twi_rx(&m_twi, device, data, length);
	while (m_xfer_done == false);
  while(nrf_drv_twi_is_busy(&m_twi));

  return ret;
}

When I implement it on main code, I can do Read Block I2C, but I can't do write block, it is stuck on pull-ed condition (in my condition, it is pulled up). But when I debug on it, it does the process, but after checking the signal response, there is no signal even from controller to sensor. Below is picture for logic analyzer and in notepad is a debugging process that I wrote on firmware.

Anybody know why my block write is not working? Thank you.

Parents
  • Hi there,

    I have some questions that I would like you to answer:

    1. Which nrf5SDK version are you using and are you using the Softdevice as well?
    2. Do you check the return value of i2c_block_write()? What does it return?
    3. It seems that the log output and your comment but when I debug on it, it does the process, but after checking the signal response, there is no signal even from controller to sensor, indicates that the write is executed but you can't verify it on the logic analyzer. Is this correct? 
    4.  Are you using a DK or custom board? Do you have any external pull ups configured?
    5. Have you been able to list the slave address by testing the TWI Scanner example?

    regards

    Jared 

  • Hi Jared, thanks for replying to me.

    1. It is nRF5_SDK_17.1.0_ddde560. Not yet, I was planning to do that in the future. But not until it works.

    2. Sorry not yet. Will check it later. Thanks.

    3. Yes, it is.

    4. No, I am using a custom board. Yes, it pull-ups with a 4.7k resistor.

    5. Yes I have.

  • Hi,

    1. Can you check the return value? i2c_block_write()?
    2. Can you share the schematics for your custom board?
    3. Can you share the part where you initialize the twi module?

    regards

    Jared 

  • Hi, sorry for my late response.

    1. It is responding 16 (as uint8_t). 

    2. Below is the picture for sensor to level shifter.

    Sorry I can't share more than that because I can't share more than that. But at least you know that SDA and SCL go to nrf pins as well.

    3. It is on here below.

    void twi_init (uint8_t sda_pin, uint8_t scl_pin)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = scl_pin,
           .sda                = sda_pin,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }

    Hopefully you have any idea about this. Thanks.

  • azwawe said:
    It is responding 16 (as uint8_t). 

    That's a NRF_ERROR_INVALID_ADDR. The documentation states:

    NRF_ERROR_INVALID_ADDR       If the EasyDMA is used and memory address in not in RAM.
    I think you have to double check the address that you pass to the write function. Also, see this case.
    Jared 
  • Hi, thanks Jared for your information.

    Anyway, I try to reinstall my Keil and create a new project with same configuration, suddenly the code works. I don't know why Joy

    I think we can close this thread. tbh, I don't know what's going on but at least it works now. Thanks for your help, really appreciate it.

Reply Children
Related