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

nRF only mode on nRF52840DK

Hello,

I have following problem.

I use the nRF52840 DK and want to run it in nRF only mode, so I have the minimum power consumption. If I set the DK to low power mode with "nrf_pwr_mgmt_run()" I still have a current consumption of about 1.4mA. To get into the nRF only mode I set SW10 to ON, SW9 to VDD and SW6 to nRF only. Furthermore I operate the DK via the P21 with an external voltage. Nevertheless I can't reduce the current consumption into the uA range. Did I forget to configure something on the DK? Can you tell me what I have to do to further reduce the current.

Thanks already.

  • Hi,

    How do you measure the current? Do you measure current on P22/P23, or do you measure the current going into the board through P21? Current on P22/P23 pins are for the nRF power domain only, it does not include the current from interface MCU, LEDs, etc.

    What application are you running on the DK, and which SDK version are you using? Calling nrf_pwr_mgmt_run() will not necessarily give you low current consumption, this depends on which modules are enabled/running in the background. 1.4 mA (given that this is consumed by the nRF itself), sounds like the EasyDMA current. This is often enabled by UARTE in RX mode or SAADC peripheral enabled.

    Best regards,
    Jørgen

  • I measure the current that goes through the P21 to the board. I use the nRF5 SDK 16.0.0 with the SDK for Mesh 4.2.0. I have extended the example of the BLE Mesh sensor model. The sensor server uses timers, the SAADC, TWI and several GPIO's. But if I comment all this out (including the initialization and the start of the BLE mesh) and just run "nrf_pwr_mgmt_run()" in the main, I still have a power consumption of about 1.4mA. The only thing that is still on is the RTC (defined in my code as sleep timer). Attached you can find the main program which gives me a current consumption of 1.4mA. I have read that NRF_LOG_ENABLED can consume power, because this causes the UART to be on. In "sdk.config" the macro is and was never enabled. Nevertheless the main uses functions from "log.h". How can this be? Is it possible that this is the cause of the remaining 1.4mA?
    Do I have to configure something on the DK with the solder bridges to get further down with the consumption?

    Thanks already.

    Kind regards.

    /* Copyright (c) 2010 - 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.
     */
    
    #include <stdint.h>
    #include <string.h>
    
    /* HAL */
    #include "boards.h"
    #include "simple_hal.h"
    #include "app_timer.h"
    
    /* Core */
    #include "nrf_mesh_config_core.h"
    #include "nrf_mesh_gatt.h"
    #include "nrf_mesh_configure.h"
    #include "nrf_mesh.h"
    #include "mesh_stack.h"
    #include "device_state_manager.h"
    #include "access_config.h"
    #include "proxy.h"
    #include "nrf_power.h"
    #include "mesh_config_entry.h"
    #include "mesh_config.h"
    
    /* Provisioning and configuration */
    #include "mesh_provisionee.h"
    #include "mesh_app_utils.h"
    
    /* Logging and RTT */
    #include "log.h"
    #include "rtt_input.h"
    
    /* Example specific includes */
    #include "app_config.h"
    #include "example_common.h"
    #include "nrf_mesh_config_examples.h"
    #include "ble_softdevice_support.h"
    
    #include "sensor_utils.h"
    #include "app_sensor.h"
    #include "app_sensor_utils.h"
    
    // Custom drivers
    #include "sensormodule_driver.h"
    #include "ads1232_driver.h"
    #include "sleepTimer_driver.h"
    #include "button_driver.h"
    #include "nrf_pwr_mgmt.h"
    #include "twi_driver.h"
    #include "nrf_sdh.h"
    #include "nrf_drv_swi.h"
    #include "nrfx_swi.h"
    
    #define UNSPECIFIED 0
    
    #define APP_SENSOR_ELEMENT_INDEX     (0)
    #define MODULE_ID (0x02)
    #define TEST_PIN    NRF_GPIO_PIN_MAP(1,2)
    
    static bool m_device_provisioned;
    
    // Custom code
    /*---------------------------------------------------------------------------------*/
    static barrel_sensor_data_t barrel_data;
    static uint8_t temp_sensor = 0;
    static bool button_flag = false;
    static nrf_swi_t my_swi;
    
    static void init_barrelData(void) {
      barrel_data.sensor_module_id = MODULE_ID;
      barrel_data.timestamp.time_year = 2020;
      barrel_data.timestamp.time_month = 1;
      barrel_data.timestamp.time_mday = 1;
      barrel_data.timestamp.time_hour = 0;
      barrel_data.timestamp.time_min = 0;
      barrel_data.timestamp.time_sec = 0;
    
      barrel_data.weight = 8388607;
      barrel_data.weight = 1111111;
      barrel_data.temp = 125;
      barrel_data.humidity = 65;
      barrel_data.batt_soc = 88;
    }
    
    int16_t	    test_data1_int = 0;
    uint16_t    test_data2_uint = 0;
    uint32_t    offset_weight = 0;
    
    static bool sleepTimer_elapsed = false;
        
    static void sleepTimer_handler(nrf_drv_rtc_int_type_t int_type)
    {
        if (int_type == NRF_DRV_RTC_INT_COMPARE0)
        {
    	sleepTimer_stop();
    	sleepTimer_elapsed = true;
            nrf_gpio_pin_toggle(LED_2);
        }
    }
    
    
    
    void button_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    
        switch(pin)
        {
    	case BUTTON_STATUS:
    	    if(nrf_gpio_pin_read(BUTTON_STATUS) == 1)
                {
    		//nrf_drv_gpiote_out_toggle(PIN_OUT);
                    //nrf_drv_gpiote_in_event_disable(BUTTON_STATUS);
                }
                break;
    
    	case BUTTON_CALIBRATION:
    	    if(nrf_gpio_pin_read(BUTTON_CALIBRATION) == 1)
                {
    		//nrf_drv_gpiote_out_toggle(PIN_OUT);
                }
                break;
    
    	case BUTTON_MEASURE:
    	    if(nrf_gpio_pin_read(BUTTON_MEASURE) == 1)
                {
    		//nrf_drv_gpiote_out_toggle(PIN_OUT);
                }
                break;
    
            default:
    	    break;
        }
        //nrf_delay_ms(1000);
        //nrf_drv_gpiote_clr_task_trigger(pin);
        //nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT);
    
    }
    /*---------------------------------------------------------------------------------*/
    
    /* Callback function forward declarations */
    
    static void app_sensor_get_cb(const app_sensor_server_t * p_server,
                                  uint16_t property_id,
                                  uint8_t * p_sensor_data,
                                  uint16_t * p_out_bytes);
    
    static void app_sensor_settings_get_cb(const app_sensor_server_t * p_server,
                                           uint16_t property_id,
                                           sensor_settings_status_msg_pkt_t * p_out,
                                           uint16_t * p_out_bytes);
    
    static void app_sensor_setting_set_cb(const app_sensor_server_t * p_server,
                                          uint16_t property_id,
                                          uint16_t setting_property_id,
                                          const sensor_setting_set_msg_pkt_t * p_in,
                                          uint16_t in_len,
                                          sensor_setting_status_msg_pkt_t * p_out,
                                          uint16_t * p_out_bytes);
    
    static void app_sensor_setting_get_cb(const app_sensor_server_t * p_server,
                                          uint16_t property_id,
                                          uint16_t setting_property_id,
                                          sensor_setting_status_msg_pkt_t * p_out,
                                          uint16_t * p_out_bytes);
    
    static void app_sensor_column_get_cb(const app_sensor_server_t * p_server,
                                         const sensor_column_get_msg_pkt_t * p_in,
                                         uint16_t in_len,
                                         sensor_column_status_msg_pkt_t * p_out,
                                         uint16_t * p_out_len);
    
    static void app_sensor_series_get_cb(const app_sensor_server_t * p_server,
                                         const sensor_series_get_msg_pkt_t * p_in,
                                         uint16_t in_len,
                                         sensor_series_status_msg_pkt_t * p_out,
                                         uint16_t * p_out_len);
    
    
    static void app_sensor_server_transaction_status_cb(access_model_handle_t model_handle,
                                                        void * p_args,
                                                        access_reliable_status_t status);
    
    
    /* Descriptor for this particular sensor (static) */
    #define NUM_DESCRIPTORS 1
    
    /* Server structure definitions */
    
    static const sensor_descriptor_t m_pir_descriptor[NUM_DESCRIPTORS] =
    {
        {
            .property_id = SENSOR_MOTION_SENSED_PROPERTY_ID,
            .positive_tolerance = UNSPECIFIED,
            .negative_tolerance = UNSPECIFIED,
            .sampling_function = UNSPECIFIED,
            .measurement_period = UNSPECIFIED,
            .update_interval = UNSPECIFIED
        }
    };
    
    /* The first item in the array gives the number of listed/supported property ids.
     */
    //static uint16_t property_array[] = {1, SENSOR_MOTION_SENSED_PROPERTY_ID};
    //static uint16_t property_array[] = {3, BARREL_MODULE_DATA_PROPERTY_ID, WEIGHT_SENSOR_PROPERTY_ID, TEMP_SENSOR_PROPERTY_ID};
    //static uint16_t property_array[] = {2, TEMP_SENSOR_PROPERTY_ID, SENSOR_MOTION_SENSED_PROPERTY_ID};
    static uint16_t property_array[] = {2, BARREL_MODULE_DATA_PROPERTY_ID, TEMP_SENSOR_PROPERTY_ID};
    
    /* Define a cadence timer for each of the properties that the server supports.
     */
    APP_TIMER_DEF(m_sensor_server_0_cadence_timer_0);
    
    static app_timer_id_t cadence_timer_ids[1] =
    {
        &m_sensor_server_0_cadence_timer_0_data
    };
    
    static uint8_t m_message_buffer[APP_CONFIG_MAX_MESSAGE_BYTES];
    
    APP_SENSOR_SERVER_DEF(m_sensor_server_0,
                          APP_CONFIG_FORCE_SEGMENTATION,
                          APP_CONFIG_MIC_SIZE,
                          app_sensor_get_cb,
                          app_sensor_settings_get_cb,
                          app_sensor_setting_set_cb,
                          app_sensor_setting_get_cb,
                          app_sensor_column_get_cb,
                          app_sensor_series_get_cb,
                          app_sensor_server_transaction_status_cb,
                          property_array,
                          cadence_timer_ids,
                          m_pir_descriptor,
                          NUM_DESCRIPTORS,
                          m_message_buffer,
                          sizeof(m_message_buffer))
    
    
    
    static uint8_t m_pir_motion_sensed_in_period;
    
    static void app_sensor_get_cb(const app_sensor_server_t * p_server,
                                  uint16_t property_id,
                                  uint8_t * p_out,
                                  uint16_t * p_out_bytes)
    {
        uint16_t required_out_bytes;
    
        /* The required buffer size can vary with property ID.
         */
        switch (property_id) {
        case SENSOR_NO_PROPERTY_ID:
            /* Return data from all sensors.
             * This demo supports 1 sensor that provides 1 byte measurements.
             */
            required_out_bytes = 1;
            break;
    
        case BARREL_MODULE_DATA_PROPERTY_ID:
            pack_to_message(&barrel_data, p_out, p_out_bytes);
            required_out_bytes = *p_out_bytes;
            break;
    
        case TEMP_SENSOR_PROPERTY_ID:
            required_out_bytes = 1;
            temp_sensor = 25;
            p_out[0] = temp_sensor;
            *p_out_bytes = 1;
            break;
    
        default:
            /* Error - this demo only supports 1 property ID. */
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR,
                  "unsupported property id = 0x%04x (%d)\n",
                  property_id,
                  property_id);
    
            required_out_bytes = *p_out_bytes + 1;
            break;
        }
    
        if (*p_out_bytes < required_out_bytes)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR,
                  "inadequate buffer (0x%04x (%d), %d, %d) = (property id, required, actual)\n",
                  property_id,
                  property_id,
                  required_out_bytes,
                  *p_out_bytes);
    
            *p_out_bytes = 0;
            return;
        }
    }
    
    
    static void app_sensor_settings_get_cb(const app_sensor_server_t * p_server,
                                           uint16_t property_id,
                                           sensor_settings_status_msg_pkt_t * p_out,
                                           uint16_t * p_out_bytes)
    {
        /* return all the settings for the sensor identified by the property id */
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
              "no settings (0x%04x (%d)) = (property id)\n",
              property_id,
              property_id);
    
        /* For this DK demo, there are no sensor settings. Return the status with the property id.
         */
        *p_out_bytes = sizeof(property_id);
        p_out->property_id = property_id;
    }
    
    static void app_sensor_setting_set_cb(const app_sensor_server_t * p_server,
                                          uint16_t property_id,
                                          uint16_t setting_property_id,
                                          const sensor_setting_set_msg_pkt_t * p_in,
                                          uint16_t in_len,
                                          sensor_setting_status_msg_pkt_t * p_out,
                                          uint16_t * p_out_bytes)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
              "no implementation (0x%04x (%d), 0x%04x (%d)) = (property id, setting property id)\n",
            property_id,
            property_id,
            setting_property_id,
            setting_property_id);
    
        /* For this DK demo, there are no sensor settings. Return the status with the property id and
         * setting property id.
         */
        *p_out_bytes = sizeof(property_id) + sizeof(setting_property_id);
        p_out->property_id = property_id;
        p_out->setting_property_id = setting_property_id;
    }
    
    static void app_sensor_setting_get_cb(const app_sensor_server_t * p_server,
                                          uint16_t property_id,
                                          uint16_t setting_property_id,
                                          sensor_setting_status_msg_pkt_t * p_out,
                                          uint16_t * p_out_bytes)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
              "no implementation (0x%04x (%d), 0x%04x (%d)) = (property id, setting property id)\n",
            property_id,
            property_id,
            setting_property_id,
            setting_property_id);
    
        /* For this DK demo, there are no sensor settings. Return the status with the property id
         * and setting property id.
         */
        *p_out_bytes = sizeof(property_id) + sizeof(setting_property_id);
        p_out->property_id = property_id;
        p_out->setting_property_id = setting_property_id;
    }
    
    static void app_sensor_column_get_cb(const app_sensor_server_t * p_server,
                                         const sensor_column_get_msg_pkt_t * p_in,
                                         uint16_t in_len,
                                         sensor_column_status_msg_pkt_t * p_out,
                                         uint16_t * p_out_bytes)
    {
        /* If there is no property ID, return data from all sensors.
         */
        if (SENSOR_NO_PROPERTY_ID == p_in->property_id)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "no implementation: no property id\n");
        }
        else
        {
            /* There is a property ID, return sensor data from the requested sensor.
             */
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
                  "no implementation for property id 0x%04x\n", p_in->property_id);
        }
    
        /* For this DK demo, there is no column data available. Respond with the requested property id.
        */
        *p_out_bytes = sizeof(p_in->property_id);
        p_out->property_id = p_in->property_id;}
    
    static void app_sensor_series_get_cb(const app_sensor_server_t * p_server,
                                         const sensor_series_get_msg_pkt_t * p_in,
                                         uint16_t in_len,
                                         sensor_series_status_msg_pkt_t * p_out,
                                         uint16_t * p_out_bytes)
    {
        /* If there is no property ID, return data from all sensors.
         */
        if (SENSOR_NO_PROPERTY_ID == p_in->property_id)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "no implementation:, no property id\n");
        }
        else
        {
            /* There is a property ID, return sensor data from the requested sensor */
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
                  "no implementation for property id 0x%04x\n", p_in->property_id);
        }
    
        /*  @tagMeshMdlSp: "4.3.1.2.8 Sending a Sensor Series Status message: If the requested Property ID
         *  is not recognized by the Sensor Server or if there is no Sensor Series Column state for
         *  requested Property ID, then the Raw Value X field, the Sensor Column Width field, and the Raw
         *  Value Y field shall be omitted."
         *
         *  For this DK demo, there are no series data available.
         */
        *p_out_bytes = sizeof(p_in->property_id);
        p_out->property_id = p_in->property_id;
    }
    
    /* Acknowledged transaction status callback, if acknowledged transfer fails, application can
     * determine suitable course of action (e.g. re-initiate previous transaction) by using this
     * callback.
     */
    static void app_sensor_server_transaction_status_cb(access_model_handle_t model_handle,
                                                        void * p_args,
                                                        access_reliable_status_t status)
    {
        switch (status)
        {
            case ACCESS_RELIABLE_TRANSFER_SUCCESS:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer success.\n");
                break;
    
            case ACCESS_RELIABLE_TRANSFER_TIMEOUT:
                hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer timeout.\n");
                break;
    
            case ACCESS_RELIABLE_TRANSFER_CANCELLED:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Acknowledged transfer cancelled.\n");
                break;
    
            default:
                ERROR_CHECK(NRF_ERROR_INTERNAL);
                break;
        }
    }
    
    
    static void node_reset(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
        /* This function may return if there are ongoing flash operations. */
        mesh_stack_device_reset();
    }
    
    static void config_server_evt_cb(const config_server_evt_t * p_evt)
    {
        if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
        {
            node_reset();
        }
    }
    
    static void provisioning_device_identification_start_cb(uint8_t attention_duration_sec)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Device identification started\n");
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(BSP_LED_2_MASK  | BSP_LED_3_MASK,
                         LED_BLINK_ATTENTION_INTERVAL_MS,
                         LED_BLINK_ATTENTION_COUNT(attention_duration_sec));
    }
    
    static void provisioning_device_identification_stop_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Device identification stopped\n");
        hal_led_blink_stop();
    }
    
    /*
     * For PTS testing, set the PTS IXIT TSPX_sensor_property_ids to the string "0042,0000,00FF".
     *
     * Setting any button in [0, 6] places the server into a mode that mocks the sensor.
     * Re-initialization removes the mock sensor.
     *
     * Set button 5 when BV-08-C prompts for an out-of-range value.
     * Set button 6 when BV-08-C prompts for an in-range value.
     * Set button 7 when BV-09-C prompts for an initial value.
     * BV-09-C tests delta publication triggering. This takes two forms: absolute change and percent
     * change. Buttons in [3, 6] support changing in absolute form. It will require several changes
     * to provide suitable delta for unitless trigger in percentages.
     * Set button 1 for a small decrement.
     * Set button 2 for a large decrement.
     * Set button 3 for a small increment.
     * Set button 4 for a large increment.
     *
     * The sensor interrupt period is long enough to avoid violations of the minimum publication
     * interval. This is not true for the mock sensor: one can set keys fast enough to cause test
     * failures due to violations of the minimum publication interval. If you see this failure, take
     * more time between setting buttons.
     */
    
    static const char m_usage_string[] =
        "\n"
        "\t\t---------------------------------------------------\n"
        "\t\t Button/RTT 1) Decrease mocked sensor value by 1.\n"
        "\t\t Button/RTT 2) Decrease mocked sensor value by 10.\n"
        "\t\t Button/RTT 3) Increase mocked sensor value by 1.\n"
        "\t\t Button/RTT 4) Increase mocked sensor value by 10.\n"
        "\t\t        RTT 5) Clear all the states to reset the node.\n"
        "\t\t---------------------------------------------------\n";
    
    static void button_event_handler(uint32_t button_number)
    {
        button_number++; /* Increase to match number printed on DK */
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
    
        switch (button_number)
        {
            case 1:
            {   
    	    //nrf_sdh_resume();
    	    nrf_mesh_enable();
                (void)sensor_status_publish(&m_sensor_server_0, BARREL_MODULE_DATA_PROPERTY_ID);
                nrf_gpio_pin_toggle(LED_2);
                break;
            }
    
            case 2:
            {
    	    (void)sensor_status_publish(&m_sensor_server_0, TEMP_SENSOR_PROPERTY_ID);
                nrf_gpio_pin_toggle(LED_3);
                break;
            }
    
            case 3:
            {
    	    nrf_mesh_disable();
                //nrf_sdh_suspend();
                break;
            }
    
            case 4:
            {
                //nrf_mesh_enable();
                //nrf_sdh_resume();
                button_flag = true;
                break;
            }
    
            case 5:
            {
                /* Clear all the states to reset the node. */
                if (mesh_stack_is_device_provisioned())
                {
    #if MESH_FEATURE_GATT_PROXY_ENABLED
                    (void) proxy_stop();
    #endif
                    mesh_stack_config_clear();
                    node_reset();
                }
                else
                {
                    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "The device is unprovisioned. Resetting has no effect.\n");
                }
                break;
            }
    
            default:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, m_usage_string);
                break;
        } 
    }
    
    static void rtt_input_handler(int key)
    {
        uint32_t button_number = UINT32_MAX;
    
        if (key >= '1' && key <= '5')
        {
            button_number = key - '1';
            button_event_handler(button_number);
        }
        if (button_number == UINT32_MAX)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, m_usage_string);
        }
         
    }
    
    static void unicast_address_print(void)
    {
        dsm_local_unicast_address_t node_address;
        dsm_local_unicast_addresses_get(&node_address);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);
    }
    
    static void provisioning_complete_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");
    
    #if MESH_FEATURE_GATT_ENABLED
        /* Restores the application parameters after switching from the Provisioning
         * service to the Proxy  */
        gap_params_init();
        conn_params_init();
    #endif
    
        unicast_address_print();
        hal_led_blink_stop();
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
    
    }
    
    static void provisioning_abort_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Provisioning aborted\n");
        hal_led_blink_stop();
    }
    
    static void models_init_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
    
        uint32_t ret = app_sensor_init(&m_sensor_server_0, APP_SENSOR_ELEMENT_INDEX);
    
        APP_ERROR_CHECK(ret);
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
              "App Sensor Setup Server Model Handle - no errs: %d\n",
              m_sensor_server_0.server.model_handle);
    }
    
    static void mesh_init(void)
    {
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = NULL,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
    
        uint32_t status = mesh_stack_init(&init_params, &m_device_provisioned);
        switch (status)
        {
            case NRF_ERROR_INVALID_DATA:
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Data in the persistent memory was corrupted. Device starts as unprovisioned.\n");
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Reset device before starting of the provisioning process.\n");
                break;
            case NRF_SUCCESS:
                break;
            default:
                APP_ERROR_CHECK(status);
        }
    }
    
    /*lint -e438 */
    /*lint -e529 */
    /* Turn off lint warnings for unused m_timer, this is used to avoid compiler
     * warning for unused static m_sensor_server_0_cadence_timer_0 */
    
    static void mesh_initialize(void)
    {
        /* Use m_sensor_server_0_cadence_timer_0.
         */
        const app_timer_id_t m_timer __attribute__((unused)) = m_sensor_server_0_cadence_timer_0;
    
        __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Sensor Server Demo -----\n");
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    
    #if BUTTON_BOARD
        ERROR_CHECK(hal_buttons_init(button_event_handler));
    #endif
    
        ble_stack_init();
    
    #if MESH_FEATURE_GATT_ENABLED
        gap_params_init();
        conn_params_init();
    #endif
    
        mesh_init();
    }
    
    static void mesh_start(void)
    {
        rtt_input_enable(rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
    
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data    = static_auth_data,
                .prov_complete_cb = provisioning_complete_cb,
                .prov_device_identification_start_cb = provisioning_device_identification_start_cb,
                .prov_device_identification_stop_cb = provisioning_device_identification_stop_cb,
                .prov_abort_cb = provisioning_abort_cb,
                .p_device_uri = EX_URI_SENSOR_SERVER
            };
    
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
        else
        {
            unicast_address_print();
        }
        
        mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());
    
        ERROR_CHECK(mesh_stack_start());
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, m_usage_string);
    
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
    }
    
    /*
    static void lfclk_request(void)
    {
        ret_code_t err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
        nrf_drv_clock_lfclk_request(NULL);
    }
    */
    void init_misc (void){
        
        
        //lfclk_request();
        //ERROR_CHECK(app_timer_init());
        hal_leds_init();
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
    
    //    ERROR_CHECK(hal_buttons_init(button_event_handler));
    
    }
    
    void leds_init() {
        nrf_gpio_cfg_output(LED_1);
        nrf_gpio_cfg_output(LED_2);
        nrf_gpio_cfg_output(LED_3);
        nrf_gpio_cfg_output(LED_4);
        nrf_gpio_pin_write(LED_1, 1);
        nrf_gpio_pin_write(LED_2, 1);
        nrf_gpio_pin_write(LED_3, 1);
        nrf_gpio_pin_write(LED_4, 1);
    }
    /*
    void buttons_init() {
        nrf_gpio_cfg_input(BUTTON_1, NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(BUTTON_2, NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(BUTTON_3, NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(BUTTON_4, NRF_GPIO_PIN_PULLUP);
    }
    */
    
    void start_measurement(barrel_sensor_data_t *data)
    {
        data->weight = get_weight(LOADCELL_CORRIDOR);
        ads1232_stop();
        disable_anlaogCircuit();
        get_tempAndHum(&(data->temp), &(data->humidity));
        disable_digitalCircuit();
        data->batt_soc = get_battSoc();
    }
    
    void clear_outputs(void)
    {
        nrf_gpio_cfg_default(EN_V_DIG);
        nrf_gpio_cfg_default(EN_V_AN);
        nrf_gpio_cfg_default(EN_LS_ADC);
        nrf_gpio_cfg_default(EN_LS_I2C);
    }
    
    void config_outputs(void)
    {
        nrf_gpio_cfg_output(EN_V_DIG);
        nrf_gpio_cfg_output(EN_V_AN);
        nrf_gpio_cfg_output(EN_LS_I2C);
        nrf_gpio_cfg_output(EN_LS_ADC);
    }
    
    static void send_barrelData(void)
    {
        //(void)sensor_status_publish(&m_sensor_server_0, BARREL_MODULE_DATA_PROPERTY_ID);
        nrf_drv_swi_trigger(my_swi, 3);
    }
    
    void disable_mesh(void)
    {
    ret_code_t sdh_status;
    
        nrf_mesh_disable();
        do {
    	nrf_sdh_suspend();
         } while(nrf_sdh_is_suspended() == false);
    
         /*
            nrf_delay_ms(1000);
            sdh_status = nrf_sdh_disable_request();
            if (sdh_status == NRF_SUCCESS)
            {
    	    nrf_gpio_pin_write(TEST_PIN, 1);
            }
            nrf_delay_ms(1000);
    */
    	//sd_softdevice_disable();
    }
    
    static void enable_mesh(void)
    {
        nrf_sdh_resume();
        //sd_softdevice_enable();
        //nrf_sdh_enable_request();
    /*
        if (nrf_sdh_enable_request() == NRF_SUCCESS)
            {
    	    nrf_gpio_pin_write(TEST_PIN, 1);
            }
        nrf_delay_ms(1000);
    */
        nrf_mesh_enable();
    }
    
    
    void swi_event_handler(nrf_swi_t swi, nrf_swi_flags_t flags)
    {
        /* If "my_swi" was triggered and flag #3 is present... */
        if ((swi == my_swi) && (flags & (1 << 3)))
        {
    	(void)sensor_status_publish(&m_sensor_server_0, BARREL_MODULE_DATA_PROPERTY_ID);
            nrf_gpio_pin_toggle(LED_4);
        }
        return;
    }
    
    
    void init_swi(void)
    {
        ret_code_t err_code;
        err_code = nrf_drv_swi_init();
        APP_ERROR_CHECK(err_code);
        /* Allocate and setup one SWI. */
        err_code = nrf_drv_swi_alloc(&my_swi, swi_event_handler, APP_IRQ_PRIORITY_LOW);
        APP_ERROR_CHECK(err_code);
    }
    
    int main(void)
    {
        nrf_power_dcdcen_set(1);
    /*
        nrf_gpio_cfg_output(TEST_PIN);
        nrf_gpio_pin_write(TEST_PIN, 0);
    
        mesh_initialize();
        mesh_start();
    
        while(mesh_stack_is_device_provisioned() == false){
    	nrf_pwr_mgmt_run();
        }
    
        while(button_flag == false) {
    	nrf_pwr_mgmt_run();
        }
    */
        //init_swi();
        //init_barrelData();
        //disable_mesh();
        //init_misc();
        //peripherals_init();
        sleepTimer_init(sleepTimer_handler);
        //buttons_init(button_handler);
        //buttons_init();
        //nrf_mesh_disable();
        //nrf_gpio_cfg_output(EN_LS_ADC); 
        sleepTimer_setTimer(10);
        while(true) {
    	//nrf_gpio_pin_toggle(EN_LS_ADC);
    	//peripherals_start();
    	//start_measurement(&barrel_data);
    	//peripherals_uninit();
    	//nrf_gpio_pin_toggle(LED_1);
    	//nrf_mesh_enable();
            //enable_mesh();
    	//send_barrelData();
            //nrf_delay_ms(1000);        
            //disable_mesh();
            //nrf_mesh_disable();
    	sleepTimer_elapsed = false;
            sleepTimer_start();
            while(sleepTimer_elapsed == false)
            {
    	    nrf_pwr_mgmt_run();
           }
     
        }
    
    }
    
    /*lint +e438 */
    /*lint +e529 */
    

  • Hi,

    Sorry for the slow response on this matter. I'm not able to build the application, as it seems to include some custom drivers.

    If you have not yet resolved this issue, can you please post the full project, including the custom driver implementations?

    Best regards,
    Jørgen

Related