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

  • call sensor_status_publish() from the set interrupt priority level

    What do you mean by calling from set interrupt priority level? Does it have to be an interrupt to call the function from?

    Maybe you can share some code snippet on how to handle this api call from main. Thanks.

Reply Children
No Data
Related