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

How can I reuse this library into TWI library in nrF52?

Hello all,

I am trying to make use of some Adafruit libraries for some sensors in my nrF52pca10040, the libraries are these twoAdafruit_BME280.cpp, Adafruit_BME280.h and Adafruit_TSL2591.h,Adafruit_TSL2591.cpp

They both make use of either SPI or I2C interfaces, I am interested on I2C, so I was trying to port both to the nrF52, I have started with the BME280 one. Using SEGGER I am compiling them but I am getting an error when reaching the method Wire.begin(); on Adafruit_BME280::begin(uint8_t a), which is expected since this function is from Arduino.

I have looked into the example twi_sensor and I see that there the twi_init is configured as

const nrf_drv_twi_config_t twi_lm75b_config = {
   .scl                = ARDUINO_SCL_PIN,
   .sda                = ARDUINO_SDA_PIN,
   .frequency          = NRF_TWI_FREQ_100K,
   .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
   .clear_bus_init     = false
};

Can I use the same configuration for my case? What should I change to be able to make use of that library?

On the other hand, those libs work a lot with the definitions HIGH,LOW,INPUT or OUTPUT, where can I find those definitons for the nrf52 board? As well as functions as configuring the PIN(pinmode(pin,OUPUT)) and writing onto it (digitalWrite(pin,HIGH)) ?

Thank you very much in advance,

Kind regards

Edit: following the advice of Jorgen, I have created my own version of the begin, read and write, however, even though there is no compilation errors, debuging the lib it gets stack when reaching the condition if (read8(BME280_REGISTER_CHIPID) != 0x60) in the begin() method.

bool Adafruit_BME280::begin(uint8_t a) {
  _i2caddr = a;

  if (_cs == -1) {
    // i2c
    //Wire.begin();

    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_BME280_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

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

    nrf_drv_twi_enable(&m_twi);

  } else {
//    digitalWrite(_cs, HIGH);
//    pinMode(_cs, OUTPUT);
//
//    if (_sck == -1) {
//      // hardware SPI
//      SPI.begin();
//    } else {
//      // software SPI
//      pinMode(_sck, OUTPUT);
//      pinMode(_mosi, OUTPUT);
//      pinMode(_miso, INPUT);
//    }
  }

  if (read8(BME280_REGISTER_CHIPID) != 0x60)
    return false;

  readCoefficients();

  //Set before CONTROL_meas (DS 5.4.3)
  write8(BME280_REGISTER_CONTROLHUMID, 0x05); //16x oversampling 

  write8(BME280_REGISTER_CONTROL, 0xB7); // 16x ovesampling, normal mode
  return true;
}

void Adafruit_BME280::write8(byte reg, byte value)
{
  if (_cs == -1) {

    ret_code_t err_code;
    err_code = nrf_drv_twi_tx(&m_twi, _i2caddr, (const byte*)reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_twi_tx(&m_twi, _i2caddr, (byte*)value, sizeof(value), false);
    APP_ERROR_CHECK(err_code);


//    Wire.beginTransmission((uint8_t)_i2caddr);
//    Wire.write((uint8_t)reg);
//    Wire.write((uint8_t)value);
//    Wire.endTransmission();
}}
uint8_t Adafruit_BME280::read8(byte reg)
{
  uint8_t value = 0;
  uint8_t valueAux = 0;

  if (_cs == -1) {
  
    ret_code_t err_code = nrf_drv_twi_rx(&m_twi, _i2caddr, &valueAux, sizeof(byte));
    APP_ERROR_CHECK(err_code);
    if (m_rxfer_done) {
      value = valueAux;//getting the value of the pointer
      m_rxfer_done = false;
    }


//    Wire.beginTransmission((uint8_t)_i2caddr);
//    Wire.write((uint8_t)reg);
//    Wire.endTransmission();
//    Wire.requestFrom((uint8_t)_i2caddr, (byte)1);
//    value = Wire.read();

  } 
  return value;
}

void Adafruit_BME280::twi_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_RX) {
      m_rxfer_done = true;
    } else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX) {
      m_txfer_done = true;
    }

    break;
  default:
    break;
  }
}

EDIT2image description Debug

Parents
  • Hi,

    You will have to rewrite all the init, write and read functions to use the corresponding TWI driver functions. For instance, in place of Wire.begin(), you should use an init function similar to twi_init() in the twi_sensor example, and use nrf_drv_twi_rx() and nrf_drv_twi_tx() in place of the read and write functions.

    For details about configuring and setting GPIOs, you should have a look at the GPIO abstraction documentation. Pins are configured as input or output using nrf_gpio_cfg_input() and nrf_gpio_cfg_output() functions. There are functions available for setting, clearing, toggling and writing to GPIOs.

    Best regards,

    Jørgen

  • Thanks Jorgen, I had the transmit as well but I didn't show before. Thanks for the tip I will incorporate as well, could you tell me why is better using an array than two variables, performance? In case of reading 24 bits, I can reuse the above function like this

    uint32_t Adafruit_BME280::read24(byte reg)
    {
      uint32_t value = 0;
      uint8_t valueAux[3] ;
      ret_code_t err_code;
    
      if (_cs == -1) {
    
        byte xfer[1] = {reg};
        err_code = nrf_drv_twi_tx(&m_twi, _i2caddr, (const byte*)xfer, sizeof(xfer), false);
        APP_ERROR_CHECK(err_code);
        while (m_txfer_done == false);
    
        err_code = nrf_drv_twi_rx(&m_twi, _i2caddr, valueAux, 3*sizeof(byte));//2*sizeof(byte) = 2bytes = 16bits
        APP_ERROR_CHECK(err_code);
        while (m_txfer_done == false);
          value = valueAux[0] << 8;
          value = valueAux[1] << 8;
          value = value | valueAux[0] | valueAux[1];
          m_rxfer_done = false;
    
    //    Wire.beginTransmission((uint8_t)_i2caddr);
    //    Wire.write((uint8_t)reg);
    //    Wire.endTransmission();
    //    Wire.requestFrom((uint8_t)_i2caddr, (byte)3);
    //    
    //    value = Wire.read();
    //    value <<= 8;
    //    value |= Wire.read();
    //    value <<= 8;
    //    value |= Wire.read();
          return value;
        }
    
Reply
  • Thanks Jorgen, I had the transmit as well but I didn't show before. Thanks for the tip I will incorporate as well, could you tell me why is better using an array than two variables, performance? In case of reading 24 bits, I can reuse the above function like this

    uint32_t Adafruit_BME280::read24(byte reg)
    {
      uint32_t value = 0;
      uint8_t valueAux[3] ;
      ret_code_t err_code;
    
      if (_cs == -1) {
    
        byte xfer[1] = {reg};
        err_code = nrf_drv_twi_tx(&m_twi, _i2caddr, (const byte*)xfer, sizeof(xfer), false);
        APP_ERROR_CHECK(err_code);
        while (m_txfer_done == false);
    
        err_code = nrf_drv_twi_rx(&m_twi, _i2caddr, valueAux, 3*sizeof(byte));//2*sizeof(byte) = 2bytes = 16bits
        APP_ERROR_CHECK(err_code);
        while (m_txfer_done == false);
          value = valueAux[0] << 8;
          value = valueAux[1] << 8;
          value = value | valueAux[0] | valueAux[1];
          m_rxfer_done = false;
    
    //    Wire.beginTransmission((uint8_t)_i2caddr);
    //    Wire.write((uint8_t)reg);
    //    Wire.endTransmission();
    //    Wire.requestFrom((uint8_t)_i2caddr, (byte)3);
    //    
    //    value = Wire.read();
    //    value <<= 8;
    //    value |= Wire.read();
    //    value <<= 8;
    //    value |= Wire.read();
          return value;
        }
    
Children
No Data
Related