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

Sending data via mesh with function "sensor_status_publish()" in main

Hello,

I have the following problem. I am using the SDK for Mesh 4.2.0 with the nRF5 SDK 16.0.0 on the nRF52840 DK, I am using the sensor model and I have extended it
with more features (SAADC, TWI, timers etc). Now I want to send data from the sensor server over the mesh network to the sensor client on a periodic basis. To do this I use the function "sensor_status_publish". After the nRF52 DK has done some measurements I call the function "sensor_status_publish()" to send the data to the sensor client and then the nRF52 DK goes into sleep mode. After a defined time, the nRF52 DK wakes up and this process will be repeated. But this does not work and I get the following error when calling the function "sensor_status_publish()": "<t:      92436>, app_error_weak.c,  105, Mesh assert at 0x0002F8D2 (:0)".
If I delete the function from the main and call it through the button_event_handler (call the function through a button_event), then the data transfer works.
How can I fix this error? Why can't I use the function "sensor_status_publish()" in the main?
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"

#define UNSPECIFIED 0

#define APP_SENSOR_ELEMENT_INDEX     (0)
#define MODULE_ID (0x01)

static bool m_device_provisioned;

// Custom code
/*---------------------------------------------------------------------------------*/
static barrel_sensor_data_t barrel_data;
static uint8_t temp_sensor = 0;

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:
        {
            (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:
        {
            //test_data = adc_read(1);
	    nrf_gpio_pin_toggle(LED_3);
            break;
        }

        case 4:
        {
            
            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);
}

void goSleep(void)
{
    __set_FPSCR( __get_FPSCR() & ~(0x0000009F)); 
    (void) __get_FPSCR();
    NVIC_ClearPendingIRQ(FPU_IRQn);
    (void)sd_app_evt_wait();  
}

static void send_barrelData(void)
{
    (void)sensor_status_publish(&m_sensor_server_0, BARREL_MODULE_DATA_PROPERTY_ID);
}

int main(void)
{
    // init
    nrf_power_dcdcen_set(1);

    mesh_initialize();
    mesh_start();
/*
    while(mesh_stack_is_device_provisioned == false){
	(void)sd_app_evt_wait();
    }
*/

    init_barrelData();
    peripherals_init();
    //init_misc();
    //mesh_stack_power_down();

    sleepTimer_init(sleepTimer_handler);
    //buttons_init(button_handler);

    //buttons_init();



    
    sleepTimer_setTimer(10);
    while(true) {
	//sd_softdevice_disable();
	//config_outputs();
	peripherals_start();
	start_measurement(&barrel_data);
        //clear_outputs();
	nrf_gpio_pin_toggle(LED_1);
        nrf_delay_ms(1000);
	send_barrelData();
	sleepTimer_elapsed = false;
        sleepTimer_start();
        while(sleepTimer_elapsed == false)

        {
	    goSleep();
        }
    }

}

/*lint +e438 */
/*lint +e529 */





/*	sleepTimer_elapsed = false;
	nrf_gpio_pin_toggle(LED_1);
	sleepTimer_start();	
	while(sleepTimer_elapsed == false) {
	    __WFE();
	}

	if (nrf_gpio_pin_read(BUTTON_1) == 0) {
	    test_data1 = adc_read(0);
	    //test_data2 = get_weight(LOADCELL_CORRIDOR)-offset_weight;
	    
	    nrf_gpio_pin_toggle(LED_2);
	    err_code = app_timer_start(sleep_timer_id, APP_TIMER_TICKS(200), NULL);
	    APP_ERROR_CHECK(err_code);
	    }

	if (nrf_gpio_pin_read(BUTTON_2) == 0){
	    offset_weight = get_weight(LOADCELL_CORRIDOR);
	    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
		  "offset weight: %d gramms\n", offset_weight);
	    nrf_gpio_pin_toggle(LED_3);
	    }

	if (nrf_gpio_pin_read(BUTTON_3) == 0) {
	    // Stop the repeated timer (stop blinking LED).
	    err_code = app_timer_stop(sleep_timer_id);
	    APP_ERROR_CHECK(err_code);
	    break;
	}
*/


	 



        /*
	    __SEV();
	    __WFE();
	    __WFE();
	 */
mesh

Parents
  • Hi,

    In order to get more information about where exactly the fault happens, you can use the addr2line command line too, like this:

    addr2line -e filename.elf 0x2F8D2

    I suspect that you get the fault because you call Bluetooth mesh API functions from main context, while the configuration for nrf_mesh_init() has the irq_priority field set to NRF_MESH_IRQ_PRIORITY_LOWEST. You need to choose one priority level from which to call nRF5 SDK for Mesh API funcitons, ref. Setting interrupt priority levels. In other words, either call sensor_status_publish() from the set interrupt priority level, or move to calling all Mesh API functions from main context (for instance through using the app scheduler.)

    Regards,
    Terje

Reply
  • Hi,

    In order to get more information about where exactly the fault happens, you can use the addr2line command line too, like this:

    addr2line -e filename.elf 0x2F8D2

    I suspect that you get the fault because you call Bluetooth mesh API functions from main context, while the configuration for nrf_mesh_init() has the irq_priority field set to NRF_MESH_IRQ_PRIORITY_LOWEST. You need to choose one priority level from which to call nRF5 SDK for Mesh API funcitons, ref. Setting interrupt priority levels. In other words, either call sensor_status_publish() from the set interrupt priority level, or move to calling all Mesh API functions from main context (for instance through using the app scheduler.)

    Regards,
    Terje

Children
Related