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

twi/i2c 16bit address and value

I am trying to measure distance with a vl53l1x sensor through the twi_sensor example.
I uploaded the code to segger by referring to sparkfun, but twi_handler does not work. It seems to be a problem because the write function and the read function are used incorrectly, but I don't know what's wrong. why!

This is sparkfun_arduino library code.

VL53L1X_ERROR VL53L1X::VL53L1_WrByte(VL53L1_DEV Dev, uint16_t index, uint8_t data)
{
	int status;
	
	//VL53L1_I2CWrite(uint8_t dev, uint16_t index, uint8_t *data, uint16_t number_of_bytes);
	status = VL53L1_I2CWrite(Dev->I2cDevAddr, index, &data, 1);
	return status;
}


VL53L1X_ERROR VL53L1X::VL53L1_RdWord(VL53L1_DEV Dev, uint16_t index, uint16_t *data)
{
	int status;
	uint8_t buffer[2] = {0, 0};
	
	//VL53L1_I2CRead(uint8_t dev, uint16_t index, uint8_t *data, uint16_t number_of_bytes);
	status = VL53L1_I2CRead(Dev->I2cDevAddr, index, buffer, 2);
	if (!status)
	{
		*data = (buffer[0] << 8) + buffer[1];
	}
	return status;
}


VL53L1X_ERROR VL53L1X::VL53L1_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToWrite)
{
#ifdef DEBUG_MODE
	Serial.print("Beginning transmission to ");
	Serial.println(((DeviceAddr) >> 1) & 0x7F);
#endif
	dev_i2c->beginTransmission(((uint8_t)(((DeviceAddr) >> 1) & 0x7F)));
#ifdef DEBUG_MODE
	Serial.print("Writing port number ");
	Serial.println(RegisterAddr);
#endif
	uint8_t buffer[2];
	buffer[0] = RegisterAddr >> 8;
	buffer[1] = RegisterAddr & 0xFF;
	dev_i2c->write(buffer, 2);
	for (int i = 0; i < NumByteToWrite; i++)
		dev_i2c->write(pBuffer[i]);

	dev_i2c->endTransmission(true);
	return 0;
}


VL53L1X_ERROR VL53L1X::VL53L1_I2CRead(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t *pBuffer, uint16_t NumByteToRead)
{
	int status = 0;

	//Loop until the port is transmitted correctly
	uint8_t maxAttempts = 5;
	for (uint8_t x = 0; x < maxAttempts; x++)
	{
#ifdef DEBUG_MODE
		Serial.print("Beginning transmission to ");
		Serial.println(((DeviceAddr) >> 1) & 0x7F);
#endif
		dev_i2c->beginTransmission(((uint8_t)(((DeviceAddr) >> 1) & 0x7F)));
#ifdef DEBUG_MODE
		Serial.print("Writing port number ");
		Serial.println(RegisterAddr);
#endif
		uint8_t buffer[2];
		buffer[0] = RegisterAddr >> 8;
		buffer[1] = RegisterAddr & 0xFF;
		dev_i2c->write(buffer, 2);
		status = dev_i2c->endTransmission(false);

		if (status == 0)
			break;

//Fix for some STM32 boards
//Reinitialize th i2c bus with the default parameters
#ifdef ARDUINO_ARCH_STM32
		if (status)
		{
			dev_i2c->end();
			dev_i2c->begin();
		}
#endif
		//End of fix
	}

	dev_i2c->requestFrom(((uint8_t)(((DeviceAddr) >> 1) & 0x7F)), (byte)NumByteToRead);

	int i = 0;
	while (dev_i2c->available())
	{
		pBuffer[i] = dev_i2c->read();
		i++;
	}

	return 0;
}

This is my code.

static uint8_t m_sample[2];



__STATIC_INLINE void data_handler(uint8_t newValue)
{   
    NRF_LOG_INFO("New value: %d ", newValue);
}

void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    NRF_LOG_INFO("handler!");
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                data_handler(m_sample);
            }
            break;

        default:
            break;
    }
}

void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_vl53l1x_config = {
       .scl                = ARDUINO_SCL_PIN, //ORANGE 27
       .sda                = ARDUINO_SDA_PIN, //RED 26
       .frequency          = NRF_DRV_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_vl53l1x_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

VL53L1X_ERROR VL53L1_WrByte(uint16_t reg, uint8_t p_tx_data)
{ 
      ret_code_t err_code;
      uint8_t tx_data[3];

      tx_data[0] = ( (reg >> 8)& 0xFF );
      tx_data[1] = reg & 0xFF;
      tx_data[2] = p_tx_data;
    
      err_code = nrf_drv_twi_tx(&m_twi, VL53L1X_ADDR, tx_data, sizeof(tx_data), false);
      return err_code;
}

VL53L1X_ERROR VL53L1_RdWord(uint16_t reg, uint16_t *p_rx_data)
{   
      ret_code_t ret_code;

      uint8_t addr_data[2];
      addr_data[0] = (reg >> 8) & 0xFF;
      addr_data[1] = reg & 0xFF;
      
      ret_code = nrf_drv_twi_tx(&m_twi, VL53L1X_ADDR, addr_data, sizeof(addr_data), false);
      if(ret_code != NRF_SUCCESS)
      {
          NRF_LOG_INFO("TWI RdWord NRF_SUCCESS FAIL");
          return ret_code;
      }
      
      ret_code = nrf_drv_twi_rx(&m_twi, VL53L1X_ADDR, m_sample, sizeof(m_sample));
      *p_rx_data =  (uint16_t) ( (m_sample[0] << 8) | m_sample[1] );
      return *p_rx_data;

}


int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("\r\nTWI sensor example started.");
    NRF_LOG_FLUSH();
    twi_init();  

    while (true)
    {
        startRanging();
        nrf_delay_ms(1000);

        while(!checkForDataReady())
        {
         nrf_delay_ms(1000); 
        }

        clearInterrupt();
        stopRanging();
        NRF_LOG_INFO("%d==============", cnt);
        int distance = getDistance();
        NRF_LOG_INFO("Distance : %d ", distance);

        //for(uint32_t i = 0; i < 2; i++)
        //{
        //  printf("%d = 0x%02X \n",i, m_sample[i] );  
        //}

        NRF_LOG_FLUSH();        
    }
}

When I build and check through SerialPort, twi_handler does not come over and "TWI RdWord NRF_SUCCESS FAIL" comes out.

Why does the result come out like this?

Where is it wrong? Please let me know ㅠㅠ

  • Hi

    Can you print out the ret_code; that returns from the nrf_drv_twi_tx() function where you're seeing this "TWI RdWord NRF_SUCCESS FAIL", as that should help us see what kind of error the application returns instead of this generic FAIL message.

    You can also try connecting the device(s) to a logic analyzer to see if there is actually any "action" on the TX and RX pins you're trying to read and write from.

    Best regards,

    Simon

Related