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

ERROR 4 [NRF_ERROR_NO_MEM] after few twi sensor readings

Project Zip: beacon_lis2dh.zip

Following is my setup:

  • Board : NRF52832 by Sparkfun(Link) - Added pull-up resistor for TWI
  • Sensor: LIS2DH12(Custom breakout)
  • IDE: Segger Studio
  • Power Supply: 3.3V 1A

Project Goal:

  • Beacon mode that switches between predefined UUIDs at regular interval or at an event
  • Interface with LIS2DH and pass the x, y, z values in MAJOR, MINOR for the specified advertising UUID

Problem:  The device can read lis2dh sensor (I am not sure if the readings are correct. I would like to request for help here). The Beacon advertisement is also working as the way as it should. After running for few seconds, advertisement stops and sensor reading also stops with ERROR 4. Given below is the debug log.

Note: LIS2DH library used is the default one that comes with SDK_17.0.2 found at ../components/drivers_ext/lis2dh12

Debug Terminal Log:

<info> app_timer: RTC: initialized.
<error> app: Major: 1, 2
<error> app: Minor: 3, 4
<info> app: Beacon example started.
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 2
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 22 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 3
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 59 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 4
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 96 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 5
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 133 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 6
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 170 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 7
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 207 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 8
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 244 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 9
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 281 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, A
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 318 0
<info> app: 255 0 0
<info> app: Advertisement timeout
<info> app: Dev state: 1
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, B
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 360 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, C
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 397 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, D
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 434 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, E
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 471 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, F
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 508 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 10
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 545 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 11
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 582 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 12
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 619 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 13
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 656 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 14
<info> app: update_major_minor(); Minor: 3, 4
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 693 0
<info> app: 255 0 0
<info> app: Advertisement timeout
<info> app: Dev state: 2
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 15
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 735 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 16
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 772 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 17
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 809 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 18
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 846 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 19
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 883 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 1A
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 920 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 1B
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<info> app: 0 0 0
<info> app: 0 0 0
<info> app: 17392 3 3
<info> app: 6 957 0
<info> app: 255 0 0
<info> app: update_maj_min_timer_handler
<info> app: update_major_minor(); Major: 1, 1C
<info> app: update_major_minor(); Minor: C, C
<info> app: Update Accl Timer
<error> app: ERROR 4 [NRF_ERROR_NO_MEM] at D:\SDK\DeviceDownload(2)\nRF5SDK1702d674dde\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_beacon_test\main.c:831
PC at: 0x000310BD
<error> app: End of error report

Main.c

/**
 * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 *
 * @defgroup ble_sdk_app_beacon_main main.c
 * @{
 * @ingroup ble_sdk_app_beacon
 * @brief Beacon Transmitter Sample Application main file.
 *
 * This file contains the source code for an Beacon transmitter sample application.
 */

#include <stdbool.h>
#include <stdint.h>
#include "ble_gap.h"
#include "nordic_common.h"
#include "bsp.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_nvic.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_drv_twi.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "lis2dh12.h"
#include "nrf_delay.h"


#define TWI_SCL 25
#define TWI_SDA 24

//#define LIS2DH_ADDR 0x18

#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND    0x02 // In order to add device name
#define DEVICE_NAME                      "NRF_Beacon"

#define update_maj_min

#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */

#define APP_BLE_OBSERVER_PRIO           3

#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */

#define APP_ADV_DURATION                MSEC_TO_UNITS(10000, UNIT_10_MS)                                       /**< The advertising duration (20 seconds) in units of 10 milliseconds. */

#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(200, UNIT_0_625_MS)  /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
                              /**< Unit in 10ms>*/
#define APP_BEACON_INFO_LENGTH          0x17                               /**< Total length of information advertised by the Beacon. */
#define APP_ADV_DATA_LENGTH             0x15                               /**< Length of manufacturer specific data in the advertisement. */
#define APP_DEVICE_TYPE                 0x02                               /**< 0x02 refers to Beacon. */
#define APP_MEASURED_RSSI               0xC3                               /**< The Beacon's measured RSSI at 1 meter distance in dBm. */
#define APP_COMPANY_IDENTIFIER          0x004c                             /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */

#define APP_MAJOR_VALUE                 0x01, 0x02                         /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE                 0x03, 0x04                         /**< Minor value used to identify Beacons. */

#define APP_BEACON_UUID                 0x01, 0x12, 0x23, 0x34, \
                                        0x45, 0x56, 0x67, 0x78, \
                                        0x89, 0x9a, 0xab, 0xbc, \
                                        0xcd, 0xde, 0xef, 0xf1            /**< Proprietary UUID for Beacon. */

#define APP_BEACON_UUID_1               0x02, 0x12, 0x23, 0x34, \
                                        0x45, 0x56, 0x67, 0x78, \
                                        0x89, 0x9a, 0xab, 0xbc, \
                                        0xcd, 0xde, 0xef, 0xf2            /**< Proprietary UUID for Beacon. */

#define APP_MAJOR_VALUE_1               0x05, 0x06                        /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE_1               0x0c, 0x0c                        /**< Minor value used to identify Beacons. */


#define APP_BEACON_UUID_2               0x03, 0x12, 0x23, 0x34, \
                                        0x45, 0x56, 0x67, 0x78, \
                                        0x89, 0x9a, 0xab, 0xbc, \
                                        0xcd, 0xde, 0xef, 0xf3             /**< Proprietary UUID for Beacon. */
#define APP_MAJOR_VALUE_2                 0x0a, 0x0b                       /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE_2                 0x0c, 0x0d                       /**< Minor value used to identify Beacons. */

#define DEAD_BEEF                       0xDEADBEEF                         /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

NRF_BLE_GATT_DEF(m_gatt);                                                  /**< GATT module instance. */
BLE_ADVERTISING_DEF(m_advertising);                                        /**< Advertising module instance. */
APP_TIMER_DEF(m_update_timer_id); 
APP_TIMER_DEF(m_update_maj_min_id);                                        /**< Advertising module instance. */
APP_TIMER_DEF(get_ble_event_id_timer_id);
APP_TIMER_DEF(m_accl_id);


#define UPDATE_TIMER_INTERVAL           APP_TIMER_TICKS(1000)

static uint16_t   m_conn_handle = BLE_CONN_HANDLE_INVALID;                 /**< Handle of the current connection. */

#if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
#define MAJ_VAL_OFFSET_IN_BEACON_INFO   18                                 /**< Position of the MSB of the Major Value in m_beacon_info array. */
#define UICR_ADDRESS                    0x10001080                         /**< Address of the UICR register used by this example. The major and minor versions to be encoded into the advertising data will be picked up from this location. */
#endif

static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */



static uint8_t              m_scanrsp_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
static uint8_t              m_enc_srdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; //modified
ble_advdata_t srdata;
ble_advdata_t advdata;

ble_advdata_manuf_data_t scanrsp_manuf_data;
uint8_array_t            scanrsp_manuf_data_array;
uint8_t                  scanrsp_manuf_data_data[10];

uint8_t _data = 0x02;
uint8_t dev_state = 1;
ble_advdata_manuf_data_t manuf_specific_data;
uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;


static void advertisement_update(void);
static void get_update_ble_evt_id(void);
static void advertising_start(void);
static void advertising_stop(void);

static void update_major_minor(void);
static void create_update_maj_min_timer(void);

//accl timers
void update_accl(void);
void create_accl_update_timer(void);


/* TWI instance ID. */
#define TWI_INSTANCE_ID     0
/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

/*TWI Function Declaration*/
void twi_master_init(void);
void twi_handler(nrf_drv_twi_evt_t const *p_event, void *p_context);

/*LIS2DH Functions declarations*/
lis2dh12_data_cb_t accl_data_on_read(void);
void accl_init();
void accl_print_data();
void print_identity();

void twi_handler(nrf_drv_twi_evt_t const *p_event, void *p_context){
  
  switch(p_event->type){
    case NRF_DRV_TWI_EVT_DONE:
    if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
    {
                                                //data_handler(m_sample);
    }
    NRF_LOG_INFO("\nm_xfer_done = true");
    m_xfer_done = true;
    break;

    default: break;
  }
}
#define MAX_PENDING_TRANSACTIONS    33

#define LIS2DH12_MIN_QUEUE_SIZE     32

NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);

LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);                    /*Define LIS2DH Instance*/
lis2dh12_data_t accl_data;

static uint8_t m_sample = 0;



/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = m_enc_srdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX

    }
};



static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
{
    APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                         // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                         // manufacturer specific data in this implementation.
    APP_BEACON_UUID,     // 128 bit UUID value.
    APP_MAJOR_VALUE,     // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MINOR_VALUE,     // Minor arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                         // this implementation.
};

static uint8_t m_beacon_info1[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
{
    APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                         // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                         // manufacturer specific data in this implementation.
    APP_BEACON_UUID_1,     // 128 bit UUID value.
    APP_MAJOR_VALUE_1,     // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MINOR_VALUE_1,     // Minor arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                         // this implementation.
};

static uint8_t m_beacon_info2[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
{
    APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                         // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                         // manufacturer specific data in this implementation.
    APP_BEACON_UUID_2,     // 128 bit UUID value.
    APP_MAJOR_VALUE_2,     // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MINOR_VALUE_2,     // Minor arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                         // this implementation.
};


/**@brief Callback function for asserts in the SoftDevice.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in]   line_num   Line number of the failing ASSERT call.
 * @param[in]   file_name  File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
static void advertising_init(void)
{
    uint32_t      err_code;    
    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;


#if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
    // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the
    // UICR instead of using the default values. The major and minor values obtained from the UICR
    // are encoded into advertising data in big endian order (MSB First).
    // To set the UICR used by this example to a desired value, write to the address 0x10001080
    // using the nrfjprog tool. The command to be used is as follows.
    // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value>
    // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the
    // the following command should be used.
    // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102
    uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
    uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);

    uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;

    m_beacon_info[index++] = MSB_16(major_value);
    m_beacon_info[index++] = LSB_16(major_value);

    m_beacon_info[index++] = MSB_16(minor_value);
    m_beacon_info[index++] = LSB_16(minor_value);
#endif

    manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
    manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;

    NRF_LOG_ERROR("Major: %x, %x", manuf_specific_data.data.p_data[18],manuf_specific_data.data.p_data[19]);
    NRF_LOG_ERROR("Minor: %x, %x", manuf_specific_data.data.p_data[20],manuf_specific_data.data.p_data[21]);
    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    //advdata.name_type             = BLE_ADVDATA_NO_NAME;
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

#ifdef scan_resp
    // Build and set scan response data.
    memset(&srdata, 0, sizeof(srdata));
    srdata.name_type             = BLE_ADVDATA_FULL_NAME;
    scanrsp_manuf_data_data[0] = 0x0A;
    scanrsp_manuf_data_data[1] = 0x0B;
    //scanrsp_manuf_data_data[2] = 0x0C;
    //scanrsp_manuf_data_data[3] = 0x0C;
    //scanrsp_manuf_data_data[4] = 0x0C;
    //scanrsp_manuf_data_data[5] = 0x0C;
    //scanrsp_manuf_data_data[6] = 0x0C;
    //scanrsp_manuf_data_data[7] = 0x0C;
       scanrsp_manuf_data_data[8] = 0x0C;
       scanrsp_manuf_data_data[9] = 0xBA;


    scanrsp_manuf_data_array.p_data = scanrsp_manuf_data_data;
    scanrsp_manuf_data_array.size = sizeof(scanrsp_manuf_data_data);

    scanrsp_manuf_data.company_identifier = 0xB00B;
    scanrsp_manuf_data.data = scanrsp_manuf_data_array;
    srdata.p_manuf_specific_data = &scanrsp_manuf_data;

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);
#endif
    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = APP_ADV_DURATION; //0;       // Never time out.

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    APP_ERROR_CHECK(err_code);

    ble_gap_conn_sec_mode_t sec_mode;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                     (const uint8_t *)DEVICE_NAME,
                                      strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);
}



/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;

    switch (p_ble_evt->header.evt_id)
    {
        //case BLE_GAP_EVT_CONNECTED:
        //    NRF_LOG_INFO("Connected");
        //    err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
        //    break;

        //case BLE_GAP_EVT_DISCONNECTED:
        //    NRF_LOG_INFO("Disconnected");
        //    // LED indication will be changed when advertising starts.
        //    m_conn_handle = BLE_CONN_HANDLE_INVALID;
        //    break;

        //case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        //{
        //    NRF_LOG_DEBUG("PHY update request.");
        //    ble_gap_phys_t const phys =
        //    {
        //        .rx_phys = BLE_GAP_PHY_AUTO,
        //        .tx_phys = BLE_GAP_PHY_AUTO,
        //    };
        //    err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
        //    APP_ERROR_CHECK(err_code);
        //} break;

        //case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
        //    // Pairing not supported
        //    err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
        //    APP_ERROR_CHECK(err_code);
        //    break;

        //case BLE_GATTS_EVT_SYS_ATTR_MISSING:
        //    // No system attributes have been stored.
        //    err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
        //    APP_ERROR_CHECK(err_code);
        //    break;

        //case BLE_GATTC_EVT_TIMEOUT:
        //    // Disconnect on GATT Client timeout event.
        //    err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
        //                                     BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
        //    APP_ERROR_CHECK(err_code);
        //    break;

        //case BLE_GATTS_EVT_TIMEOUT:
        //    // Disconnect on GATT Server timeout event.
        //    err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
        //                                     BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            //APP_ERROR_CHECK(err_code);
            //break;

        case BLE_GAP_EVT_ADV_SET_TERMINATED :
           NRF_LOG_INFO("Advertisement timeout");
           NRF_LOG_INFO("Dev state: %d", dev_state);
           ret_code_t err_code;
           //err_code=app_timer_stop(m_update_maj_min_id);
           //APP_ERROR_CHECK(err_code);

          

            if (dev_state == 1){
            manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
            advdata.p_manuf_specific_data = &manuf_specific_data;
            }
           

            if (dev_state == 2){
            manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info1;
            advdata.p_manuf_specific_data = &manuf_specific_data;
            
            }
            if (dev_state == 3){
            manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info2;
            advdata.p_manuf_specific_data = &manuf_specific_data;
            }
            advdata.flags  = flags;
           
          
           err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
           APP_ERROR_CHECK(err_code);

           err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
           APP_ERROR_CHECK(err_code);
           advertising_start();

            if(dev_state >= 3) dev_state=1;
            else dev_state++;
#ifdef scan_resp
           ble_advdata_manuf_data_t manuf_data;
           manuf_data.data.p_data = (uint8_t *) m_beacon_info1;
           manuf_data.data.size = APP_BEACON_INFO_LENGTH;

           //advdata.flags = flags;
           advdata.p_manuf_specific_data = &manuf_data;
           m_adv_data.scan_rsp_data.p_data[12] = 0xEE;
           m_adv_data.scan_rsp_data.p_data[13] = 0xAA;
           //err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
           //APP_ERROR_CHECK(err_code);
           err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
           APP_ERROR_CHECK(err_code);

           err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
           APP_ERROR_CHECK(err_code);
           advertising_start();
#endif
          
           break;

        default:
            NRF_LOG_INFO("BLE Default %d", p_ble_evt->header.evt_id);
            break;
    }
}


#ifdef scan_resp
/**@brief Function for updating scan response data.
 */
static void advertisement_update(void){
ret_code_t err_code;
//ble_advdata_manuf_data_t manuf_specific_data;
//manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
//// Build and set advertising data.
//memset(&advdata, 0, sizeof(advdata));

////advdata.name_type             = BLE_ADVDATA_NO_NAME;
//advdata.flags                 = flags;
//advdata.p_manuf_specific_data = &manuf_specific_data;

ble_advdata_manuf_data_t manuf_data;
manuf_data.data.p_data = (uint8_t *) m_beacon_info;
manuf_data.data.size = APP_BEACON_INFO_LENGTH;

advdata.flags = flags;
advdata.p_manuf_specific_data = &manuf_data;

m_adv_data.scan_rsp_data.p_data[12] = 0xFF;
m_adv_data.scan_rsp_data.p_data[13] = _data;
++_data;


//err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
//APP_ERROR_CHECK(err_code);
err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
 APP_ERROR_CHECK(err_code);


get_update_ble_evt_id();

//err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
//APP_ERROR_CHECK(err_code);

}

#endif

/**@brief Function for starting advertising.
 */
static void advertising_start(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for starting advertising.
 */
static void advertising_stop(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_stop(m_adv_handle);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_ERROR("\nAdvertising stopped!");
}

/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);
   // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);

    ble_gap_conn_sec_mode_t sec_mode;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                     (const uint8_t *)DEVICE_NAME,
                                      strlen(DEVICE_NAME));
}


/**@brief Function for initializing logging. */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/**@brief Function for initializing LEDs. */
static void leds_init(void)
{
    ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing timers. */
static void timers_init(void)
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing power management.
 */
static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}

/**@brief Function starting the internal LFCLK oscillator.
 *
 * @details This is needed by RTC1 which is used by the Application Timer
 *          (When SoftDevice is enabled the LFCLK is always running and this is not needed).
 */
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);
}

#ifdef scan_resp
static void update_timer_handler(void * p_context){

	NRF_LOG_INFO("timer handler\r\n");

	advertisement_update();
}


static void get_update_ble_evt_id(void){
ble_evt_t ble_event;
NRF_LOG_INFO("get_update_ble_evt_id()\r");
NRF_LOG_INFO("ble event id is %d\n", ble_event.header.evt_id);
}

static void create_timers()
{
    ret_code_t err_code;

    // Create timers
    err_code = app_timer_create(&m_update_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                update_timer_handler);
    APP_ERROR_CHECK(err_code);

        // Create timers
    //err_code = app_timer_create(&get_ble_event_id_timer_id,
    //                            APP_TIMER_MODE_REPEATED,
    //                            get_update_ble_evt_id);
    //APP_ERROR_CHECK(err_code);
}
#endif

#ifdef update_maj_min
/**@brief Function for updating major minor data.
 */
static void update_major_minor(void){
ret_code_t err_code;
//ble_advdata_manuf_data_t manuf_specific_data;
//manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
//// Build and set advertising data.
//memset(&advdata, 0, sizeof(advdata));

////advdata.name_type             = BLE_ADVDATA_NO_NAME;
//advdata.flags                 = flags;
//advdata.p_manuf_specific_data = &manuf_specific_data;
//ble_advdata_manuf_data_t manuf_data;
//manuf_data.company_identifier = APP_COMPANY_IDENTIFIER;
//manuf_data.data.size = APP_BEACON_INFO_LENGTH;
//ble_advdata_manuf_data_t manuf_data;
//manuf_data.company_identifier = APP_COMPANY_IDENTIFIER;
//manuf_data.data.p_data = (uint8_t *) m_beacon_info;
//manuf_data.data.size = APP_BEACON_INFO_LENGTH;

//advdata.p_manuf_specific_data = &manuf_data;

manuf_specific_data.data.p_data[18] = 0x01;
manuf_specific_data.data.p_data[19] = _data;
++_data;

    NRF_LOG_INFO("update_major_minor(); Major: %x, %x", manuf_specific_data.data.p_data[18],manuf_specific_data.data.p_data[19]);
    NRF_LOG_INFO("update_major_minor(); Minor: %x, %x", manuf_specific_data.data.p_data[20],manuf_specific_data.data.p_data[21]);

err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
 APP_ERROR_CHECK(err_code);
}


static void update_maj_min_timer_handler(void * p_context){

	NRF_LOG_INFO("update_maj_min_timer_handler\r");

	update_major_minor();       
}


static void create_update_maj_min_timer()
{
    ret_code_t err_code;

    // Create timers
    err_code = app_timer_create(&m_update_maj_min_id,
                                APP_TIMER_MODE_REPEATED,
                                update_maj_min_timer_handler);
    APP_ERROR_CHECK(err_code);
}
#endif


void update_accl()
{
accl_print_data();
}


void update_accl_handler(void * p_context)
{
  NRF_LOG_INFO("Update Accl Timer\r");
  update_accl();
}

void create_update_accl_timer(void)
{
    ret_code_t err_code;
    err_code = app_timer_create(&m_accl_id, APP_TIMER_MODE_REPEATED, update_accl_handler);
    APP_ERROR_CHECK(err_code);
  
}

/**@brief Function for handling the idle state (main loop).
 *
 * @details If there is no pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
     nrf_pwr_mgmt_run();
    }
}

void accl_init()
{
	ret_code_t err_code;

	nrf_drv_twi_config_t const config = {
		.scl                = TWI_SCL,
		.sda                = TWI_SDA,
		.frequency          = NRF_DRV_TWI_FREQ_100K,
		.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
		.clear_bus_init     = false
	};

	err_code = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_twi_sensor_init(&m_nrf_twi_sensor);
	APP_ERROR_CHECK(err_code);

	err_code = lis2dh12_init(&m_lis2dh12);
	APP_ERROR_CHECK(err_code);

	// data acquisition configuration: 10HZ sample rate, low power mode, x axis, y axis, z axis, values in range -2g <-> +2g, disable high resolution mode (in this case step size is 256)
	LIS2DH12_DATA_CFG(m_lis2dh12, LIS2DH12_ODR_10HZ, true, true, true, true, LIS2DH12_SCALE_2G, 0);
	err_code = lis2dh12_cfg_commit(&m_lis2dh12);
	APP_ERROR_CHECK(err_code);

	// FIFO configuration: enable FIFO, streaming mode, int1 pin used, 32 values watermark
	//LIS2DH12_FIFO_CFG(m_lis2dh12, 1, LIS2DH12_STREAM, 0, 10);
	//err_code = lis2dh12_cfg_commit(&m_lis2dh12);
	//APP_ERROR_CHECK(err_code);

	//// interrupt configurataion: disable everything except the FIFO watermark interrupt
	//LIS2DH12_INT1_PIN_CFG(m_lis2dh12, 0, 0, 0, 0, 1, 0, 1, 0);
	//err_code = lis2dh12_cfg_commit(&m_lis2dh12);
	//APP_ERROR_CHECK(err_code);
}

void accl_print_data()
{
	ret_code_t err_code;  
        //uint8_t m_data;
        //err_code = lis2dh12_fifo_src_read(&m_lis2dh12, 0x00, &m_data);
        //APP_ERROR_CHECK(err_code);
        //NRF_LOG_INFO("WTM: %d OVN: %d EMPTY: %d FSS: %2d ", (m_data & 0b10000000), (m_data & 0b01000000), (m_data & 0b00100000), (m_data & 0b0001111));

        lis2dh12_data_t samples[5];
	err_code = lis2dh12_data_read(&m_lis2dh12, 0x00, samples, 5);
	APP_ERROR_CHECK(err_code);

	for (uint8_t i = 0; i < 5; i++)
		NRF_LOG_INFO("%d %d %d", samples[i].x, samples[i].y, samples[i].z);
}


void print_identity(ret_code_t r, void *p_register_data)
{
    NRF_LOG_INFO("Identity: %d", *((uint8_t *)p_register_data));
}


lis2dh12_data_cb_t accl_data_on_read(void){
  
  NRF_LOG_INFO("Accl data reading finished");
}



/**
 * @brief Function for application main entry.
 */
int main(void)
{
    // Initialize.
    log_init();
    lfclk_request();
    timers_init();
    leds_init();
    accl_init();
    power_management_init();
    ble_stack_init();

    ret_code_t err_code;
    
    advertising_init();

    // do not try to access FIFO values if watermark was not reached yet
    //if (!data_available)
    //	continue;
   //err_code = lis2dh12_who_am_i_read(&m_lis2dh12, print_identity, &m_sample);
   //APP_ERROR_CHECK(err_code);

    
#ifdef scan_resp
    create_timers();
#endif

#ifdef update_maj_min

    create_update_maj_min_timer();
#endif

    create_update_accl_timer();

    // Start execution.
    NRF_LOG_INFO("Beacon example started.");
    advertising_start();
    
#ifdef scan_resp
    err_code = app_timer_start(m_update_timer_id, UPDATE_TIMER_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif

#ifdef update_maj_min
    err_code = app_timer_start(m_update_maj_min_id, UPDATE_TIMER_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif
    nrf_delay_ms(500);

    err_code = app_timer_start(m_accl_id, UPDATE_TIMER_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
    

    //err_code = lis2dh12_data_read(&m_lis2dh, accl_data_on_read, &accl_data, 5);
    //APP_ERROR_CHECK(err_code);

    //    err_code = app_timer_start(get_ble_event_id_timer_id, UPDATE_TIMER_INTERVAL, NULL);
    //APP_ERROR_CHECK(err_code);
    // Enter main loop.
    for (;; )
    {
        idle_state_handle();
    }
}


/**
 * @}
 */

  • tamojit said:
    The read function is called every 1 second. As I am using the default sensor driver that comes with the SDK, I am not quite sure if there is anyway the queue buffer can be cleared. Please refer me any documentation regarding it, I could not find any.

    Thank you for clarifying.
    Looking into the source code of the nrf_twi_sensor.c it seems to me that the memory allocation that fails (nrf_balloc_alloc) does so because there are no more available memory in the pool. Paired with what you said earlier - that a bigger queue makes the NRF_ERROR_NO_MEM taker longer to be generated - makes me think that transactions are being queued faster than they are being expedited. However, the slow rate of 1 transaction per second makes me doubt this somewhat.
    Memory will be freed up again when a transaction either is completed, interrupted or fails to start.

    Do you have access to a logical analyzer, so we may take a look at what is happening on the lines prior to this error occurring?

    tamojit said:
    if you once again see the debug log and follow the line patterns after "Update Accl Timer" you will notice that every fourth line has its value increased after every iteration. Moreover the value doesnot change when I move around the accelerometer.

    Please keep in mind that I have no idea what these different lines and numbers are supposed to represent.
    The value does not change when you move it - could it be that you need to enable the positioning measurements, or similar? Does the sensor require any 'setup' or configuration before it will start measuring and sending the measurements? This will be mentioned in the user guide if necessary.

    tamojit said:
    I followed it and I managed it to recover the state by using "NVIC_SystemReset()" at NRF_ERROR_NO_MEM. I am not sure if this correct way, but I did not like it. It solves for now, but in the long run, this methodology is not ethical to me.

    Oh, no, this is not what I meant. Resetting the system is the default error handler already - if you pass a non-NRF_SUCCESS error code to an APP_ERROR_CHECK then the system will reset.
    However, what I recommend that you do is to add a check directly following the _read call, to see if it returned NRF_ERROR_NO_MEM, and in the case that it did you could for example wait until a transfer successfully completes before trying to queue the transfer again.

    Best regards,
    Karl

Related