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

Read Function with TWI/TWIM legacy and NRFX

Hi I am using nRF52 DK, nRF52832 and a sensor. The TWI communication is described as :

and : 

I tried to use the Legacy of TWI drivers in order to implement a read function able to read the registers. As well i tried to use nrfx module with separate NRFX_TWIM_XFER_DESC_TX/RX. Both have some problems. Before to try to resolve my issues i am wondering if i am on the right path using these functions.

I would like to use the legacy beacuse i am working to an older version of SDK (14.2.0) and i don't want to integrate it with the nrfx module if possible.

Are these liberies able to implement a correct communication in my case or there are other functions more suitable to define my read function?

Thanks,

polimarte

  • Hello,

    The same transfer macros should be available in the legacy driver, please take a look at the driver documentation here: TWI master.

    Also, below I have included an example I made to interface with the Sensirion sht3x. It demonstrate how the transfer macros can be used to set up a complete transaction. Hopefully it may be useful as a reference.

    /**
     * Copyright (c) 2015 - 2019, 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. */
    #define SHT3x_ADDRESS                   (0x45U)
    #define SHT3x_MEAS_CMD_H                {0x2c, 0x06}                       /**<Start high repeatability measurement with clock stretching*/
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief Function for handling data from temperature sensor.
     *
     * @param[in] temp          Temperature in Celsius degrees read from sensor.
     */
    __STATIC_INLINE void data_handler(nrf_drv_twi_evt_t const * p_event)
    {
        uint16_t      raw_value;
        float         temperature;
        uint16_t      humidity;
        
        /* Raw data conversion. We are ignoring the checksum value here */ 
        raw_value = uint16_big_decode(&p_event->xfer_desc.p_secondary_buf[0]); /* Swap byte order to little endian */
        
        temperature = 175 * (uint16_t)raw_value / 65535.0f -45.0f;
    
        raw_value = uint16_big_decode(&p_event->xfer_desc.p_secondary_buf[3]);
        humidity = 100.0f * raw_value / 65535.0f;
        
        NRF_LOG_INFO("Temperature: "NRF_LOG_FLOAT_MARKER" Celsius degrees.", NRF_LOG_FLOAT(temperature));
        NRF_LOG_INFO("Humidity: %d%%", humidity);
    }
    
    /**
     * @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 (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX)
                {
                    data_handler(p_event);
                }
                break;
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_WARNING("Received NRF_DRV_TWI_EVT_ADDRESS_NACK event");
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_WARNING("Received NRF_DRV_TWI_EVT_DATA_NACK event");
                break;
            default:
                break;
        }
    }
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_sht3x_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_sht3x_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
    static void read_sensor_data()
    {  
        uint32_t err_code;
        static uint8_t twim_rx_buf[6];
        static uint8_t twim_tx_buf[] = SHT3x_MEAS_CMD_H;
    
        nrf_drv_twi_xfer_desc_t xfer_desc = NRF_DRV_TWI_XFER_DESC_TXRX(
            SHT3x_ADDRESS, twim_tx_buf, sizeof(twim_tx_buf), twim_rx_buf, sizeof(twim_rx_buf));
    
        err_code = nrf_drv_twi_xfer(&m_twi, &xfer_desc, NRF_DRV_TWI_FLAG_TX_NO_STOP);
        if (err_code == NRF_ERROR_BUSY)
        {
            NRF_LOG_INFO("TWIM driver is busy");
        }
        else
        {
            APP_ERROR_CHECK(err_code);
        }
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("\r\nTWI SHT3x example started.");
        NRF_LOG_FLUSH();
        twi_init();
    
        while (true)
        {
            nrf_delay_ms(500);
            read_sensor_data();
            NRF_LOG_FLUSH();
        }
    }
    
    /** @} */

    Best regards,

    Vidar

Related