I2C Sensor that uses I2C address of 0xB5 which is an 8 Bit address, unable to communicate with Sensor

Hello, I have a sensor from ST-Electronics that uses the I2C protocol to communicate with the NRF52840. The sensor has an 8-bit address, specifically 0xB5, which is outside the range of 7-bit addressing mode used by the NRF driver. I have been working on this for three days with no success. I have tried using bit shift operations but it did not work. Is there any way to communicate with the sensor using its 8-bit addressing mode?

Application initialilly read the "WHO_I_AM" address

//This HAL .c file for nrf52 pointer function
/** I2C Device Address 8 bit format **/
//#define STHS34PF80_I2C_ADD  0xB5U
int STHS34PF80_I2C_ADD  = (0xB5 >> 1);

/* Device initialization */

volatile bool tx_m_xfer_done = false;
volatile bool rx_m_xfer_done = false;

void st_transaction_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
        if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
        {
          tx_m_xfer_done = true; 
        }
        if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
        {
          rx_m_xfer_done = true;
        }
        break;

        default:
        break;
    }
}

void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = ST_MOTION_SCK_LINE,
       .sda                = ST_MOTION_SDK_LINE,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = 0
    };

    err_code = nrf_drv_twi_init(&SENSOR_BUS, &twi_config, st_transaction_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&SENSOR_BUS);
}

void platform_delay(uint32_t ms)
{
  nrf_delay_ms(ms);
}

int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp,uint16_t len)
{
  ret_code_t res;
  res = nrf_drv_twi_tx(handle,STHS34PF80_I2C_ADD, &reg, 1,false); 
  /*Error Implementation remaining and should be Implemented*/
  res = nrf_drv_twi_rx(handle,STHS34PF80_I2C_ADD, bufp, len);
}

int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,uint16_t len)
{
  ret_code_t res;
  
  res = nrf_drv_twi_tx(handle,STHS34PF80_I2C_ADD,&reg,1,false);
  APP_ERROR_CHECK(res);
  while (tx_m_xfer_done == false);

  res = nrf_drv_twi_rx(handle,STHS34PF80_I2C_ADD, bufp, len);
  APP_ERROR_CHECK(res);
  while (rx_m_xfer_done == false);

  tx_m_xfer_done = false;
  rx_m_xfer_done = false;
}


When no right shift operation is used.

Parents
  • Just shift the address right by 1 (= divide by two).

    Some documnents give you the address with the r/w bit included, some don't want it that way.

    EDIT: Use an oscilloscope to check the waveforms. It is easy to misconfigure a pin and use push-pull instead of the open drain mode that I²C requires. Not difficult to spot with a scope when looking at the rise time.

Reply
  • Just shift the address right by 1 (= divide by two).

    Some documnents give you the address with the r/w bit included, some don't want it that way.

    EDIT: Use an oscilloscope to check the waveforms. It is easy to misconfigure a pin and use push-pull instead of the open drain mode that I²C requires. Not difficult to spot with a scope when looking at the rise time.

Children
Related