BME280 not accessing data from TWIM

Hello,

im trying to use TWIM to get some data from BME280. The problem is that it always responds with 0x00, when it should be 0x60.
I kinda don't know whats the problem there:

#include <zephyr/kernel.h>
#include <nrfx_twim.h>
#include <nrfx_timer.h>
#include <zephyr/device.h>
#include <nrfx.h>
#include <zephyr/devicetree.h>
#include <nrfx_twis.h>
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_ctrl.h>
#include <helpers/nrfx_gppi.h>
#include <nrfx_ppi.h>

//BME 280 DEFINES START
#define BME280_I2C_ADDRESS              0x76
#define BME280_REG_ID                   0xD0
#define BME280_REG_TEMP_COMP_START      0x88
#define BME280_CHIP_ID                  0x60
#define BME280_REG_PRESS_MSB            0xF7
struct{
    uint8_t chip_id;
}bme280_data;

uint8_t read_buf_id[1];
uint8_t read_buf_temp[6];

uint8_t write_reg_buffer[1];
uint8_t read_meas_buf[9];


//BME280 DEFINES END

LOG_MODULE_REGISTER(LOGGING_FORTWIM);

// TIMERS DEFINES START
#define TIMER_INST_IDX 0
#define TIME_TO_WAIT_MS 3300UL

// TIMERS DEFINES END

// TWIM TWIS DEFINES START
#define TWIM_INST_IDX 0

#define MASTER_SCL_PIN 3

#define MASTER_SDA_PIN 4

static nrfx_twim_t m_twim_inst = NRFX_TWIM_INSTANCE(TWIM_INST_IDX);

//uint8_t channel;

nrfx_timer_t timer_inst = NRFX_TIMER_INSTANCE(TIMER_INST_IDX);

static void twim_handler(nrfx_twim_evt_t const * p_event, void * p_context)
{
    if (p_event->type == NRFX_TWIM_EVT_DONE)
    {
        char * p_msg = p_context;
        LOG_INF("%s", p_msg);
    }
    if(p_event->type == NRFX_TWIM_EVT_BUS_ERROR){
        LOG_INF("BUS ERROR");
    }
    if(p_event->type == NRFX_TWIM_EVT_ADDRESS_NACK){
        LOG_INF("ADDRESS NACK\n");
    }
    else
    {
        LOG_INF("--> Master event: %d.", p_event->type);
    }
}

static void timer_handler(nrf_timer_event_t event_type, void *p_context)
{
    LOG_INF("TIMER INTERRUPT HANDLER\n");
    // LOG_INF("xPEP DZIALA");
}

void register_read(uint8_t   slave_addr,
                   uint32_t  reg_num,
                   uint8_t * rx_buffer,
                   uint8_t   bytes_to_read)
{
    nrfx_twim_xfer_desc_t twim_xfer_desc = NRFX_TWIM_XFER_DESC_TXRX(slave_addr, // BME280 I2C
                                                                    write_reg_buffer, //what address to access???
                                                                    1, //Amount
                                                                    rx_buffer, // Rx buffer
                                                                    bytes_to_read);
    nrfx_twim_xfer(&m_twim_inst, &twim_xfer_desc, 0);
    

    while (nrfx_twim_is_busy(&m_twim_inst))
    {}
}



static void Timer_init(void)
{

    nrfx_err_t err;

    (void)err;

    uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(timer_inst.p_reg);

    nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);

    config.bit_width = NRF_TIMER_BIT_WIDTH_32;

    err = nrfx_timer_init(&timer_inst, &config, timer_handler);

    nrfx_timer_clear(&timer_inst);

    uint32_t desired_ticks = nrfx_timer_ms_to_ticks(&timer_inst, TIME_TO_WAIT_MS);

    nrfx_timer_extended_compare(&timer_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks,
                                NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
}
int main(void)
{
    LOG_INIT();

    nrfx_err_t status;
    (void)status;

    Timer_init();
    void * p_context = "--> Master event: done - transfer completed";

    write_reg_buffer[0]=BME280_REG_ID;
    nrfx_twim_config_t twim_config = NRFX_TWIM_DEFAULT_CONFIG(MASTER_SCL_PIN, MASTER_SDA_PIN);
    status = nrfx_twim_init(&m_twim_inst, &twim_config, twim_handler, p_context);
    nrfx_twim_enable(&m_twim_inst);
    //register_read(BME280_I2C_ADDRESS, write_reg_buffer, read_buf_id, 1);
    nrfx_twim_xfer_desc_t twim_xfer_desc = NRFX_TWIM_XFER_DESC_TXRX(BME280_I2C_ADDRESS, // BME280 I2C
                                                                    write_reg_buffer, 
                                                                    1, 
                                                                    read_buf_id, 
                                                                    1);
    status = nrfx_twim_xfer(&m_twim_inst, &twim_xfer_desc, 0);
    if (status != NRFX_SUCCESS) {
    LOG_ERR("Error during TWI transfer: %d", status);
    }
    bme280_data.chip_id=read_buf_id[0];                                                               
    LOG_INF("ctrl buff: 0x%02x", bme280_data.chip_id);
    // status = nrfx_gppi_channel_alloc(&channel);
    
    // nrfx_gppi_channel_endpoints_setup(
    //     channel,
	// 	nrfx_timer_event_address_get(&timer_inst, NRF_TIMER_EVENT_COMPARE0),
	// 	nrfx_twim_start_task_address_get(NRF_TWIM0, NRF_TWIM_TASK_STARTRX)
    // );

  
  

    IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TWIM_INST_GET(TWIM_INST_IDX)), IRQ_PRIO_LOWEST,
                       NRFX_TWIM_INST_HANDLER_GET(TWIM_INST_IDX), 0);

    
    IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER_INST_IDX)), IRQ_PRIO_LOWEST,
                       NRFX_TIMER_INST_HANDLER_GET(TIMER_INST_IDX), 0);

 

    

    while (1)
    {
        LOG_PROCESS();
    }
}


My BME280 is connected like this:

SCL: 3 / SDA: 4 / GND GND / Vcc Vdd / CSB&SDO GND

  • Hello,

    It looks like you are printing the content of the buffer (0x00) before the transfer is complete. Try adding a wait to ensure that the transfer is complete:

    ...
    
    volatile bool xfer_done = false;
    
    static void twim_handler(nrfx_twim_evt_t const * p_event, void * p_context)
    {
        if (p_event->type == NRFX_TWIM_EVT_DONE)
        {
            char * p_msg = p_context;
            LOG_INF("%s", p_msg);
            xfer_done = true;
        }
        ...
    }
    
    int main(void)
    {
        ...
        status = nrfx_twim_xfer(&m_twim_inst, &twim_xfer_desc, 0);
        if (status != NRFX_SUCCESS) {
            LOG_ERR("Error during TWI transfer: %d", status);
        }
        while (xfer_done == false)
        {
            // Wait.
        }
        bme280_data.chip_id=read_buf_id[0];                                                               
        LOG_INF("ctrl buff: 0x%02x", bme280_data.chip_id);
        ...
    }

    And see if that helps.

    Best regards,

    Edvin

Related