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

BMD300 I2C/TWI not working

Hi,

I am trying to communicate with MLX90615 (here) sensor using BMD300. nRF52 DK is used to program the device. I am testing with a sample code which detects any I2C compatible device which is connected to SDA and SCL. There is no activity happening on SCL and SDA pins! SCL pin is LOW and SDA pin remains HIGH. The main code is given below.

 #include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_uart.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"

/*UART buffer size. */
#define UART_TX_BUF_SIZE 256
#define UART_RX_BUF_SIZE 1

#warning "!**** ARE YOU ABSOLUTELY SURE YOU HAVE CHOSEN THE CORRECT SCL AND SDA PINS? ****!"
#define DEVICE_SCL_PIN 6
#define DEVICE_SDA_PIN 7

nrf_drv_twi_t twi_instance = NRF_DRV_TWI_INSTANCE(0);

uint8_t device_address = 0; // Address used to temporarily store the current address being checked
bool device_found = false; 


/**
 * @brief UART events handler.
 */
static void uart_events_handler(app_uart_evt_t * p_event)
{
    switch (p_event->evt_type)
    {
        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}


/**
 * @brief UART initialization.
 */
static void uart_config(void)
{
    uint32_t                     err_code;
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud38400
    };

    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_events_handler,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);

    APP_ERROR_CHECK(err_code);
}

/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{   
    switch(p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            // If EVT_DONE (event done) is received a device is found and responding on that particular address
     //       printf("\r\n!****************************!\r\nDevice found at 7-bit address: %#x!\r\n!****************************!\r\n\r\n", device_address);
            device_found = true;
            break;
        case NRF_DRV_TWI_EVT_ADDRESS_NACK:
      //      printf("No address ACK on address: %#x!\r\n", device_address);
            break;
        case NRF_DRV_TWI_EVT_DATA_NACK:
      //      printf("No data ACK on address: %#x!\r\n", device_address);
            break;
        default:
            break;        
    }   
}

/**
 * @brief UART initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;
    
    const nrf_drv_twi_config_t twi_config = {
       .scl                = DEVICE_SCL_PIN,
       .sda                = DEVICE_SDA_PIN,
       .frequency          = TWI_FREQUENCY_FREQUENCY_K100,
       .interrupt_priority = TWI0_CONFIG_IRQ_PRIORITY
    };
    
    err_code = nrf_drv_twi_init(&twi_instance, &twi_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    
    nrf_drv_twi_enable(&twi_instance);
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    nrf_gpio_cfg_output(9);
    nrf_gpio_pin_set(9);
  //  uart_config();
  //  printf("\033[2J\033[;H\r\n* Example to find TWI devices connected to \r\n* the TWI bus and their addresses\r\n\r\n");
    twi_init();
    
    uint8_t dummy_data = 0x07;
    // Itterate through all possible 7-bit TWI addresses
    for(uint8_t i = 0; i <= 0x7F; i++)
    {
      //  device_address = i;
        // Send dummy data. If a device is present on this particular address a TWI EVT_DONE event is 
        // received in the twi event handler and a message is printed to UART
        nrf_drv_twi_tx(&twi_instance, 0x5B, &dummy_data, 1, true);
        // Delay 10 ms to allow TWI transfer to complete and UART to print messages before starting new transfer
        nrf_delay_ms(10);
    }
    if(device_found)
    {
        // Blinke LED_1 rapidly if device is found
      
        
            nrf_gpio_pin_toggle(9);
            nrf_delay_ms(100);
        
    }
    else
    {
        
    }
}

What are the basic settings for TWI ? Is the initialisation correct? What are the recommended troubleshooting methods? Does the SCL pin out anything even if MLX90615 not detected?

regards, Vishnu

Parents
  • Vishnu,

    I'm working on getting the nRF52 development board to read the mlx90615 sensor. I'm using P0.26 and P0.27. When I read the sensor RAM I get data for both Ta and To that indicates unrealitic temperature near1000C. The following is snippets from my code. Perhaps we can collaborate to overcome our issues.

        /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Temperature in Celsius degrees read from sensor.
     */
    
    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
        
            case NRF_DRV_TWI_EVT_DONE:  //< Transfer completed event.
                 mlx_xfer_done = true;
                 break;
    
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:  //< Error event: NACK received after sending the address.
                 // handle addressing error code here
                 SEGGER_RTT_printf(0, "NACK received after sending the address \r\n");
                 break;
            
            case NRF_DRV_TWI_EVT_DATA_NACK:   //< Error event: NACK received after sending a data byte.
                 // handle addressing error code here
                 SEGGER_RTT_printf(0, "NACK received after sending a data byte \r\n");
                 break;
        }
    }
    
    
    /**
     * @brief TWI (SMBus) initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
      
        //Configure the I2C/SMBus to interface with the any slave device on the bus
        const nrf_drv_twi_config_t twi_mlx90615_config = {
           .scl                = SCL,
           .sda                = SDA,
           .frequency          = NRF_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,  
         };
    
        //Initiate the TWI driver instance in Blocking mode (needs an event handler)     
        err_code = nrf_drv_twi_init(&mlx90615, &twi_mlx90615_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);     
    
        //Enable the TWI driver instance
        nrf_drv_twi_enable(&mlx90615);
    }
    
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
        float read_mlx90615_temp_data(const uint8_t commanded_reg )
    {
        ret_code_t err_code;
        uint8_t reg = commanded_reg;
        uint8_t templsb,tempmsb, pec;
        uint16_t tempraw;  
        float temperature;
    
        templsb=0;                                            //Clear variables 
        tempmsb=0;                                            //Clear variables 
        tempraw=0;                                            //Clear variables 
        pec = 0;                                              //Clear variables
        
        mlx_xfer_done = false;
      
        /* Writing to MLX90615 to select which register to read */
        err_code = nrf_drv_twi_tx(&mlx90615, MLX90615_ADDR, &reg, sizeof(reg), true);
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
    
      
        mlx_xfer_done = false;
    
        /* Read LSB byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &templsb, sizeof(templsb));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
        
        mlx_xfer_done = false;
    
        /* Read MSB byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &tempmsb, sizeof(tempmsb));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
    
        mlx_xfer_done = false;
    
        /* Read Packet Error Code byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &pec, sizeof(pec));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);    
        
    
        tempraw = ((uint16_t)tempmsb << 8) | templsb;      // Make 16bit TempRAW from 2 8bit reads 
    
        temperature = ((tempraw * 0.02) - 273.15);
    
        return temperature;
    }
    
Reply
  • Vishnu,

    I'm working on getting the nRF52 development board to read the mlx90615 sensor. I'm using P0.26 and P0.27. When I read the sensor RAM I get data for both Ta and To that indicates unrealitic temperature near1000C. The following is snippets from my code. Perhaps we can collaborate to overcome our issues.

        /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Temperature in Celsius degrees read from sensor.
     */
    
    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        switch (p_event->type)
        {
        
            case NRF_DRV_TWI_EVT_DONE:  //< Transfer completed event.
                 mlx_xfer_done = true;
                 break;
    
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:  //< Error event: NACK received after sending the address.
                 // handle addressing error code here
                 SEGGER_RTT_printf(0, "NACK received after sending the address \r\n");
                 break;
            
            case NRF_DRV_TWI_EVT_DATA_NACK:   //< Error event: NACK received after sending a data byte.
                 // handle addressing error code here
                 SEGGER_RTT_printf(0, "NACK received after sending a data byte \r\n");
                 break;
        }
    }
    
    
    /**
     * @brief TWI (SMBus) initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
      
        //Configure the I2C/SMBus to interface with the any slave device on the bus
        const nrf_drv_twi_config_t twi_mlx90615_config = {
           .scl                = SCL,
           .sda                = SDA,
           .frequency          = NRF_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,  
         };
    
        //Initiate the TWI driver instance in Blocking mode (needs an event handler)     
        err_code = nrf_drv_twi_init(&mlx90615, &twi_mlx90615_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);     
    
        //Enable the TWI driver instance
        nrf_drv_twi_enable(&mlx90615);
    }
    
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
        float read_mlx90615_temp_data(const uint8_t commanded_reg )
    {
        ret_code_t err_code;
        uint8_t reg = commanded_reg;
        uint8_t templsb,tempmsb, pec;
        uint16_t tempraw;  
        float temperature;
    
        templsb=0;                                            //Clear variables 
        tempmsb=0;                                            //Clear variables 
        tempraw=0;                                            //Clear variables 
        pec = 0;                                              //Clear variables
        
        mlx_xfer_done = false;
      
        /* Writing to MLX90615 to select which register to read */
        err_code = nrf_drv_twi_tx(&mlx90615, MLX90615_ADDR, &reg, sizeof(reg), true);
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
    
      
        mlx_xfer_done = false;
    
        /* Read LSB byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &templsb, sizeof(templsb));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
        
        mlx_xfer_done = false;
    
        /* Read MSB byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &tempmsb, sizeof(tempmsb));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);
    
        mlx_xfer_done = false;
    
        /* Read Packet Error Code byte from the specified register from above */
        err_code = nrf_drv_twi_rx(&mlx90615, MLX90615_ADDR, &pec, sizeof(pec));
        APP_ERROR_CHECK(err_code);
        while (mlx_xfer_done == false);    
        
    
        tempraw = ((uint16_t)tempmsb << 8) | templsb;      // Make 16bit TempRAW from 2 8bit reads 
    
        temperature = ((tempraw * 0.02) - 273.15);
    
        return temperature;
    }
    
Children
No Data
Related