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

Why cannot I receive second byte of MAX30205 with nrf_drv_twi_xfer()?

Hello,

I am using nrf52832 with PCA10040 and SDK15.1 along with a temperature sensor MAX30205. So far I can write, but I am realizing that I cannot read the second byte of the temperature given by the sensor using the function nrf_drv_twi_xfer() of the driver...

My function looks like this

int8_t twi1_ext_read_transfer(uint8_t i2cAddressMAX30205, uint8_t reg_addr,char *rxData, uint16_t bytesNumberRx,bool repeatedStart) {

  ret_code_t err_code;


    nrf_drv_twi_xfer_desc_t twi_MAX30205_ReadTransferData;

    twi_MAX30205_ReadTransferData.address          = i2cAddressMAX30205;
    twi_MAX30205_ReadTransferData.p_primary_buf    = &reg_addr;
    twi_MAX30205_ReadTransferData.primary_length   = sizeof(reg_addr);
    twi_MAX30205_ReadTransferData.p_secondary_buf  = rxData;
    twi_MAX30205_ReadTransferData.secondary_length = bytesNumberRx;
    if(repeatedStart){
        twi_MAX30205_ReadTransferData.type             = NRF_DRV_TWI_XFER_TXRX;
    } else {
        twi_MAX30205_ReadTransferData.type             = NRF_DRV_TWI_XFER_RX;
    }

    uint32_t flags = NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER;

    err_code = nrf_drv_twi_xfer(&twi_MAX30205, &twi_MAX30205_ReadTransferData, flags);

    APP_ERROR_CHECK(err_code);

    #if defined(DEBUG_INTERFACE_MAX30205) && defined(EXG_MODULE_TMIC_DK)
        NRF_LOG_RAW_INFO("TW1:From device address 0x%04x reading register 0x%04x value 0x%04x \r\n",i2cAddressMAX30205,reg_addr,*rxData);
    #endif

    return ((int8_t)err_code);    
}

If I use that, when calling driver function I see how last byte `data[1]` seems not to have right value

int max30205_read_reg16(int16_t *value, char reg)//, I2C &i2c_bus) 
{
    int32_t ret;
    char data[2] = {0, 0};
    max30205_raw_data tmp;

    tmp.msb =0;
    tmp.lsb=0;
     
    if (reg == MAX30205_REG_TEMPERATURE || 
        reg == MAX30205_REG_THYST_LOW_TRIP || reg == MAX30205_REG_TOS_HIGH_TRIP) {

            ret = twi1_ext_read_transfer(max30205_address, reg, data, 2, true);

            if (ret == 0) {
                tmp.msb = data[0];
                tmp.lsb = data[1];
                *value = tmp.swrd;
                return MAX30205_NO_ERROR;
            } else {
                printf(
                    "%s: failed to read data: ret: %d\r\n", __func__, ret);
            }

    } else {
        printf("%s: register address is not correct: register: %d\r\n",
                __func__, reg);
    }                
    return MAX30205_ERROR;
}

Can someone give me a hint?

Thanks in advance

  • Hello,

    Have you tried to analyze the TWI wires to see if the data actually coming on the data line matches your second byte or not?

    BR,

    Edvin

  • YEs I have tried and I see how it doesn't, the data line doesn't match the second byte, what is this due to?

  • I have also a releated question, in the TWI  documentation  example is stated that

    A single transfer consists of a transmission of 1 byte and a reception of 3 bytes. The TX data is repeated for all transfers, but the RX data from all transfers is collected in the buffer. Therefore, NRF_DRV_TWI_FLAG_RX_POSTINC is set so that the buffer address for the received data is incremented. The end of sequence is controlled externally, and the processing of data is postponed until the end of the sequence (the user event handler is disabled).

    Where and how is done that end of sequence using nrf_drv_twi_exfer()??

  • For anyone that have the same issue,

    I solved my problem by changing my read function to use the blocking mode, to do so I had to disable my TWI interrup handler  in this way

    err_code = nrf_drv_twi_init(&twi_MAX30205, &twi_config_MAX30302,NULL,NULL), Which isn't clear on the documentation but mentioned on the forum

    Full TWI initialization function

    uint32_t twi1_ext_start() {
    
      uint32_t err_code;
    
      // Configuring twi1 for the MAX30205, by default the frequency is 100KHz
      twi_config_MAX30302.sda       = SEM_EXT_SDA_I2C;
      twi_config_MAX30302.scl       = SEM_EXT_SCL_I2C;
      twi_config_MAX30302.frequency = TWI_FREQUENCY_FREQUENCY_K250;
      twi_config_MAX30302.interrupt_priority = APP_IRQ_PRIORITY_HIGH;
      twi_config_MAX30302.clear_bus_init     = false;
      
    
      //Initialising the sensor
      err_code = nrf_drv_twi_init(&twi_MAX30205, &twi_config_MAX30302,NULL,NULL);
    
      //Enabling the I2C driver
      nrf_drv_twi_enable(&twi_MAX30205);
      
      APP_ERROR_CHECK(err_code);
    
      return err_code;
    }

    Reading function from TWI interface

    int8_t twi1_ext_read_transfer(uint8_t i2cAddressMAX30205, uint8_t reg_addr,char *rxData, uint16_t bytesNumberRx,bool repeatedStart){
    
        ret_code_t err_code ;
    
        uint8_t tx_data[] = {0};
    
        tx_data[1] = reg_addr;
    
        err_code = nrf_drv_twi_tx(&twi_MAX30205, i2cAddressMAX30205, tx_data, sizeof(tx_data), false);
        APP_ERROR_CHECK(err_code);
        
        err_code = nrf_drv_twi_rx(&twi_MAX30205, i2cAddressMAX30205, rxData, bytesNumberRx);
        APP_ERROR_CHECK(err_code);
    
        return ((int8_t)err_code);
    
    }

Related