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

TWI Sensor sensor_set_mode NRF_ERROR_INVALID_ADDR

Hi, I'm using nRF52 DK (nRF52832), demo code <TWI sensor>. I'm using this slave sensor to communicate with Master nRF52 DK. My code gets stuck at sensor_set_mode() function. On PuTTY, it shows that the while loop never exits. The error is NRF_ERROR_INVALID_ADDR. Any help, pls? 

/* Creating a TWI master driver instance. */
#define TWI_INSTANCE_ID     0
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

// address = 0x21 or 0x22 or 0x23 depends on the resistor valur at ADDR port
#define SENSOR_ADDR          (0x22U >> 1) 

// In order to set sensor as continuous mode, use register 0x3608
#define continuous_mode_command1 0x36U
#define continuous_mode_command2 0x08U

/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

void sensor_set_mode(void)
{
    ret_code_t err_code;
    NRF_LOG_INFO("sensor_set_mode started\r\n");
    // Writing CONTINUOUS_MODE = 0x3608U into SDP3x configuration register. Set SDP3x sensor in continuous mode. 
    uint8_t reg0 = continuous_mode_command1;
    uint8_t reg1 = continuous_mode_command2;
    
    uint16_t reg = ((reg0 << 8) | reg1);
    NRF_LOG_INFO("reg16bit: %x\r\n",reg);


    /* Function for sending data to a TWI slave.       
        * @param[in] p_instance Pointer to the driver instance structure.
        * @param[in] address    Address of a specific slave device (only 7 LSB).
        * @param[in] p_data     Pointer to a transmit buffer.
        * @param[in] length     Number of bytes to send.
        * @param[in] no_stop    If set, the stop condition is not generated on the bus
        *                       after the transfer has completed successfully (allowing
        *                       for a repeated start in the next transfer).
        This function will return NRF_SUCCESS if the procedure was successful.
    */
    err_code = nrf_drv_twi_tx(&m_twi, SENSOR_ADDR, reg, sizeof(reg), false);
    NRF_LOG_INFO("error code6 = %s\r\n",nrf_strerror_find(err_code));
    
    NRF_LOG_INFO(" set i2c address\r\n");
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
    NRF_LOG_INFO("done\r\n");
    
}

Parents
  • Thanks, Jorgen. I did the modification as you mentioned. However, now the project stops printing anything. I tried to use the SEGGER debugger to debug. The debugger stops at sensor_set_mode(). Here is my whole code if you need. The slave sensor datasheet is here. Many thanks. 

    Note:  3 warning signs are located at

    line 79

    line 137

    line 193

    /**
     * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup tw_sensor_example main.c
     * @{
     * @ingroup nrf_twi_example
     * @brief TWI Sensor Example main file.
     *
     * This file contains the source code for a sample application using TWI.
     *
     */
    
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    
    
    // 
    
    /* Common addresses definition for temperature sensor. 
     * 1) U means data type is "unsigned". Another example of data type is L, which means "long"
     * 2)  >> is the right shift operator, which means to shift the bit to the right by xxx positions.
     *     e.g. if a = 5 (0000 0101), (a<<1)=10 because (0000 1010)=10
     * 3) The prefix 0x means hexadecimal value
     *    0x21U in hex = 2*(16^1) + 1*(16^0) = 33 in decimal
     *    By seeing the datasheet of SDP3x sensor: address=0x22 when ADDR connects to 1.2K resistor
     *    That's why we define address = 0x22U here
     */
     // When ADDR connects to GND, it uses the default I2C address: 0x21 (Got this info from datasheet)
    #define SENSOR_ADDR          (0x22U >> 1)   // why shift address by 1 bit ?????????????????????????????????????????????????/
    
    /* Chose mode for master and slave. Use 1 bit (LSB) to indicate that 
       - If master reads data from slave, use 1
       - If master sends data to slave, use 0
       In order to set sensor as continuous mode, use register 0x3608
    */
    #define continuous_mode_command1 0x36U
    #define continuous_mode_command2 0x08U
    
    
    uint16_t tempVal;
    float tempC;
    
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    
    
    /* Creating a TWI master driver instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    /* Buffer for samples read from sensor. 
       SDP3x digital sensor outputs a 16-bits data. Since m_sample is 8-bit, so we need to use m_smaple[2] for 16-bit. 
    */
    static uint8_t m_sample[2];
    
    
    
    /**
     * @brief Function for setting mode on sensor
     */
    void sensor_set_mode(void)
    {
        NRF_LOG_INFO("sensor_set_mode 000\r\n");
        ret_code_t err_code;
        NRF_LOG_INFO("sensor_set_mode started\r\n");
        // Writing CONTINUOUS_MODE = 0x3608U into SDP3x configuration register. Set SDP3x sensor in continuous mode. 
        uint8_t reg0 = continuous_mode_command1;
        uint8_t reg1 = continuous_mode_command2;
        NRF_LOG_INFO("regt0 = %d , %x\r\n",reg0,reg0);
        NRF_LOG_INFO("regt1 = %d , %x\r\n",reg1,reg1);
        // uint16_t reg = ((reg0 << 8) | reg1);
        uint8_t reg[2] = {reg0,reg1};
        NRF_LOG_INFO("reg16bit: %x\r\n",reg);
    
    
        /* Function for sending data to a TWI slave.       
            * @param[in] p_instance Pointer to the driver instance structure.
            * @param[in] address    Address of a specific slave device (only 7 LSB).
            * @param[in] p_data     Pointer to a transmit buffer.
            * @param[in] length     Number of bytes to send.
            * @param[in] no_stop    If set, the stop condition is not generated on the bus
            *                       after the transfer has completed successfully (allowing
            *                       for a repeated start in the next transfer).
            This function will return NRF_SUCCESS if the procedure was successful.
        */
        err_code = nrf_drv_twi_tx(&m_twi, SENSOR_ADDR, &reg, sizeof(reg), false);
        NRF_LOG_INFO("sizeof reg = %d\r\n",sizeof(reg));
        NRF_LOG_INFO("error code = %s\r\n",nrf_strerror_find(err_code));
        NRF_LOG_INFO(" set i2c address\r\n");
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
        NRF_LOG_INFO("done1\r\n");
    
    }
    
    
    
    
    
    
    /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Pressure value read from sensor.
     */
    float pressure;
    float pressure_scale = 60.0;
    __STATIC_INLINE void data_handler(uint8_t pressure_raw_data)
    {
         pressure = pressure_raw_data / pressure_scale;
         NRF_LOG_INFO("raw_data = %d, pressure = " NRF_LOG_FLOAT_MARKER "\r\n",pressure_raw_data,NRF_LOG_FLOAT(pressure));  
    }
    
    
    
    
    
    
    
    
    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
         NRF_LOG_INFO("Test0\r\n");
        
         // type: TWI master event types
         switch (p_event->type)
        {
            NRF_LOG_INFO("Test222\r\n");
    
            case NRF_DRV_TWI_EVT_DONE:            // Transfer completed event.
                // NRF_DRV_TWI_XFER_RX: is TWI master driver transfer types (Rx transfer)
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
                {
                    NRF_LOG_INFO("Case 1: NRF_DRV_TWI_EVT_DONE\r\n");
                    /*
                    pressure = pressure_raw_data / pressure_scale;
                    NRF_LOG_INFO("raw_data = %d, pressure = " NRF_LOG_FLOAT_MARKER "\r\n",pressure_raw_data,NRF_LOG_FLOAT(pressure));
                    */
                    data_handler(m_sample);
                }
                m_xfer_done = true;
                break;
    
    
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:    // Error event: NACK received after sending the address.
                NRF_LOG_INFO("Error event: NACK received after sending the address.");
                break;
    
    
            case NRF_DRV_TWI_EVT_DATA_NACK:       // Error event: NACK received after sending a data byte.
                NRF_LOG_INFO(" Error event: NACK received after sending a data byte.");
                break;
    
    
            default:
                NRF_LOG_INFO("1 Default");
                break;
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
        
    
        // Structure for the TWI master driver instance configuration.
        const nrf_drv_twi_config_t twi_lm75b_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,     // Options: 100K, 250K, 400K
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
        NRF_LOG_INFO("111\r\n");
    
    
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("222\r\n");
    
    
    
        nrf_drv_twi_enable(&m_twi);
        NRF_LOG_INFO("333\r\n");
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
    static void read_sensor_data()
    {
        m_xfer_done = false;
        NRF_LOG_INFO("read_sensor_data\r\n");
    
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. 
    
         * Function for reading data from a TWI slave.
         *
         * The transmission will be stopped when an error occurs. If a transfer is ongoing,
         * the function returns the error code @ref NRF_ERROR_BUSY.
         *
         * @param[in] p_instance Pointer to the driver instance structure.
         * @param[in] address    Address of a specific slave device (only 7 LSB).
         * @param[in] p_data     Pointer to a receive buffer.
         * @param[in] length     Number of bytes to be received.
         *
         * @retval NRF_SUCCESS                    If the procedure was successful.
         */
        ret_code_t err_code1 = nrf_drv_twi_rx(&m_twi, SENSOR_ADDR, &m_sample[0], sizeof(m_sample));
        ret_code_t err_code2 = nrf_drv_twi_rx(&m_twi, SENSOR_ADDR, &m_sample[1], sizeof(m_sample));
        APP_ERROR_CHECK(err_code1);
        APP_ERROR_CHECK(err_code2);
        uint16_t complete_data = ((uint16_t)m_sample[0] << 8) | m_sample[1];
        NRF_LOG_INFO("complete data = %d  \r\n",complete_data);
    }
    
    
    
    
    
    
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        NRF_LOG_INFO("aaa\r\n");
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_INFO("bbb\r\n");
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("\r\nTWI sensor example started.");
        
        NRF_LOG_INFO("444\r\n");
        twi_init();
        NRF_LOG_INFO("4445555555555\r\n");
         
        sensor_set_mode();
        NRF_LOG_INFO("4445555555555666666666\r\n");
        NRF_LOG_FLUSH();
        // NRF_LOG_INFO("Size = %d\r\n",sizeof(m_sample));
        while (true)
        {
            NRF_LOG_INFO("555\r\n");
            nrf_delay_ms(500);
            NRF_LOG_FLUSH();
            do
            {
                NRF_LOG_INFO("666\r\n");
                NRF_LOG_FLUSH();
                nrf_delay_ms(2000);
                //  Wait For Event
                __WFE();
            }while (m_xfer_done == false);
            NRF_LOG_INFO("777\r\n");
            read_sensor_data();
            NRF_LOG_INFO("888\r\n");
            NRF_LOG_FLUSH();
        }
    }
    
    /** @} */
    
    
     

Reply
  • Thanks, Jorgen. I did the modification as you mentioned. However, now the project stops printing anything. I tried to use the SEGGER debugger to debug. The debugger stops at sensor_set_mode(). Here is my whole code if you need. The slave sensor datasheet is here. Many thanks. 

    Note:  3 warning signs are located at

    line 79

    line 137

    line 193

    /**
     * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup tw_sensor_example main.c
     * @{
     * @ingroup nrf_twi_example
     * @brief TWI Sensor Example main file.
     *
     * This file contains the source code for a sample application using TWI.
     *
     */
    
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    
    
    // 
    
    /* Common addresses definition for temperature sensor. 
     * 1) U means data type is "unsigned". Another example of data type is L, which means "long"
     * 2)  >> is the right shift operator, which means to shift the bit to the right by xxx positions.
     *     e.g. if a = 5 (0000 0101), (a<<1)=10 because (0000 1010)=10
     * 3) The prefix 0x means hexadecimal value
     *    0x21U in hex = 2*(16^1) + 1*(16^0) = 33 in decimal
     *    By seeing the datasheet of SDP3x sensor: address=0x22 when ADDR connects to 1.2K resistor
     *    That's why we define address = 0x22U here
     */
     // When ADDR connects to GND, it uses the default I2C address: 0x21 (Got this info from datasheet)
    #define SENSOR_ADDR          (0x22U >> 1)   // why shift address by 1 bit ?????????????????????????????????????????????????/
    
    /* Chose mode for master and slave. Use 1 bit (LSB) to indicate that 
       - If master reads data from slave, use 1
       - If master sends data to slave, use 0
       In order to set sensor as continuous mode, use register 0x3608
    */
    #define continuous_mode_command1 0x36U
    #define continuous_mode_command2 0x08U
    
    
    uint16_t tempVal;
    float tempC;
    
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    
    
    /* Creating a TWI master driver instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    /* Buffer for samples read from sensor. 
       SDP3x digital sensor outputs a 16-bits data. Since m_sample is 8-bit, so we need to use m_smaple[2] for 16-bit. 
    */
    static uint8_t m_sample[2];
    
    
    
    /**
     * @brief Function for setting mode on sensor
     */
    void sensor_set_mode(void)
    {
        NRF_LOG_INFO("sensor_set_mode 000\r\n");
        ret_code_t err_code;
        NRF_LOG_INFO("sensor_set_mode started\r\n");
        // Writing CONTINUOUS_MODE = 0x3608U into SDP3x configuration register. Set SDP3x sensor in continuous mode. 
        uint8_t reg0 = continuous_mode_command1;
        uint8_t reg1 = continuous_mode_command2;
        NRF_LOG_INFO("regt0 = %d , %x\r\n",reg0,reg0);
        NRF_LOG_INFO("regt1 = %d , %x\r\n",reg1,reg1);
        // uint16_t reg = ((reg0 << 8) | reg1);
        uint8_t reg[2] = {reg0,reg1};
        NRF_LOG_INFO("reg16bit: %x\r\n",reg);
    
    
        /* Function for sending data to a TWI slave.       
            * @param[in] p_instance Pointer to the driver instance structure.
            * @param[in] address    Address of a specific slave device (only 7 LSB).
            * @param[in] p_data     Pointer to a transmit buffer.
            * @param[in] length     Number of bytes to send.
            * @param[in] no_stop    If set, the stop condition is not generated on the bus
            *                       after the transfer has completed successfully (allowing
            *                       for a repeated start in the next transfer).
            This function will return NRF_SUCCESS if the procedure was successful.
        */
        err_code = nrf_drv_twi_tx(&m_twi, SENSOR_ADDR, &reg, sizeof(reg), false);
        NRF_LOG_INFO("sizeof reg = %d\r\n",sizeof(reg));
        NRF_LOG_INFO("error code = %s\r\n",nrf_strerror_find(err_code));
        NRF_LOG_INFO(" set i2c address\r\n");
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
        NRF_LOG_INFO("done1\r\n");
    
    }
    
    
    
    
    
    
    /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Pressure value read from sensor.
     */
    float pressure;
    float pressure_scale = 60.0;
    __STATIC_INLINE void data_handler(uint8_t pressure_raw_data)
    {
         pressure = pressure_raw_data / pressure_scale;
         NRF_LOG_INFO("raw_data = %d, pressure = " NRF_LOG_FLOAT_MARKER "\r\n",pressure_raw_data,NRF_LOG_FLOAT(pressure));  
    }
    
    
    
    
    
    
    
    
    /**
     * @brief TWI events handler.
     */
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
         NRF_LOG_INFO("Test0\r\n");
        
         // type: TWI master event types
         switch (p_event->type)
        {
            NRF_LOG_INFO("Test222\r\n");
    
            case NRF_DRV_TWI_EVT_DONE:            // Transfer completed event.
                // NRF_DRV_TWI_XFER_RX: is TWI master driver transfer types (Rx transfer)
                if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
                {
                    NRF_LOG_INFO("Case 1: NRF_DRV_TWI_EVT_DONE\r\n");
                    /*
                    pressure = pressure_raw_data / pressure_scale;
                    NRF_LOG_INFO("raw_data = %d, pressure = " NRF_LOG_FLOAT_MARKER "\r\n",pressure_raw_data,NRF_LOG_FLOAT(pressure));
                    */
                    data_handler(m_sample);
                }
                m_xfer_done = true;
                break;
    
    
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:    // Error event: NACK received after sending the address.
                NRF_LOG_INFO("Error event: NACK received after sending the address.");
                break;
    
    
            case NRF_DRV_TWI_EVT_DATA_NACK:       // Error event: NACK received after sending a data byte.
                NRF_LOG_INFO(" Error event: NACK received after sending a data byte.");
                break;
    
    
            default:
                NRF_LOG_INFO("1 Default");
                break;
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
        
    
        // Structure for the TWI master driver instance configuration.
        const nrf_drv_twi_config_t twi_lm75b_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,     // Options: 100K, 250K, 400K
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
        NRF_LOG_INFO("111\r\n");
    
    
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("222\r\n");
    
    
    
        nrf_drv_twi_enable(&m_twi);
        NRF_LOG_INFO("333\r\n");
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
    static void read_sensor_data()
    {
        m_xfer_done = false;
        NRF_LOG_INFO("read_sensor_data\r\n");
    
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. 
    
         * Function for reading data from a TWI slave.
         *
         * The transmission will be stopped when an error occurs. If a transfer is ongoing,
         * the function returns the error code @ref NRF_ERROR_BUSY.
         *
         * @param[in] p_instance Pointer to the driver instance structure.
         * @param[in] address    Address of a specific slave device (only 7 LSB).
         * @param[in] p_data     Pointer to a receive buffer.
         * @param[in] length     Number of bytes to be received.
         *
         * @retval NRF_SUCCESS                    If the procedure was successful.
         */
        ret_code_t err_code1 = nrf_drv_twi_rx(&m_twi, SENSOR_ADDR, &m_sample[0], sizeof(m_sample));
        ret_code_t err_code2 = nrf_drv_twi_rx(&m_twi, SENSOR_ADDR, &m_sample[1], sizeof(m_sample));
        APP_ERROR_CHECK(err_code1);
        APP_ERROR_CHECK(err_code2);
        uint16_t complete_data = ((uint16_t)m_sample[0] << 8) | m_sample[1];
        NRF_LOG_INFO("complete data = %d  \r\n",complete_data);
    }
    
    
    
    
    
    
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        NRF_LOG_INFO("aaa\r\n");
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_INFO("bbb\r\n");
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("\r\nTWI sensor example started.");
        
        NRF_LOG_INFO("444\r\n");
        twi_init();
        NRF_LOG_INFO("4445555555555\r\n");
         
        sensor_set_mode();
        NRF_LOG_INFO("4445555555555666666666\r\n");
        NRF_LOG_FLUSH();
        // NRF_LOG_INFO("Size = %d\r\n",sizeof(m_sample));
        while (true)
        {
            NRF_LOG_INFO("555\r\n");
            nrf_delay_ms(500);
            NRF_LOG_FLUSH();
            do
            {
                NRF_LOG_INFO("666\r\n");
                NRF_LOG_FLUSH();
                nrf_delay_ms(2000);
                //  Wait For Event
                __WFE();
            }while (m_xfer_done == false);
            NRF_LOG_INFO("777\r\n");
            read_sensor_data();
            NRF_LOG_INFO("888\r\n");
            NRF_LOG_FLUSH();
        }
    }
    
    /** @} */
    
    
     

Children
  • Looks like you implemented a combination of my two suggested solutions, leading back to the original problem again. You need to remove the '&' before reg when it is declared as an array, it is only needed when passing a single variable. An array is by default a pointer.

    I'm not sure what causes the warning on line 79, you need to post the warning text if I should help you with that. The reason for shifting the address is that the sensors normally uses a 7-bit addressing format, with LSB being a R/W bit. The nrf_drv_twi API expects only the 7-bit address, not the R/W bit. If the address is correct before or after shifting should be visible from the sensor datasheet, but you can also run the "TWI scanner example" to get the address of any TWI devices found on the bus.

    The warning on line 193 is because the data_handler() function expects a single uint8_t variable as input, while you pass m_sample, which is a 2-byte (uint8_t) variable array, i.e. you are passing a pointer.

  • Thanks, Jogen. 

    According to your guide, now only 1 warning sign is left (line 193).

    For line 193, I'm using this code

    data_handler(&m_sample);

    Moreover, on PuTTY, it doesn't print anything at all. Not even the very first line. I suspect that it's caused by line 193 error? Do you know how to fix the line 193 error, please? 

  • Passing &m_sample to data_handler does not really make sense, then you are passing the reference to a pointer (remember that m_sample is an array, i.e. already a pointer). You can change the function declaration to take an array as argument:

    void data_handler(uint8_t pressure_raw_data[2])

    And the pass the array directly:

    data_handler(m_sample);

    Or you can make m_sample into a uint16 variable before passing it:

    uint16_t pressure = ((m_sample[0] << 8) | m_sample[1]);
    data_handler(pressure);
    
    void data_handler(uint16_t pressure_raw_data)
    {
        ...
    }

    Anyway, I'm not sure that this is the reason for the log not printing, at least I cannot see any reasons that the code you have should crash.

    You can try to disable deferred logging in your sdk_config.h file, to see if something is preventing the application from running until the first NRF_LOG_FLUSH() macro:

    #define NRF_LOG_DEFERRED 0

Related