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

BLE Zigbee concurent door lock example with SysTick_Handler

Hi,

We are at the stage of migrating our exsisting code which was based on the SDK 15.2 to use the nRF5 SDK for Thread and Zigbee v4.1.0.

Im stuck at the stage of using the SysTick. It seems to me that when we want to use this, the code does not run as normal anymore.

I've added the following lines to the zigbee example \examples\multiprotocol\ble_zigbee\ble_zigbee_dynamic_door_lock_nus:

/*----------------------------------------------------------------------------
  SysTick IRQ: Executed periodically (10ms) 
 *----------------------------------------------------------------------------*/
void SysTick_Handler (void) 
{
	static int n = 0;
	n++;
}

/**@brief Function for application main entry.
 */
int main(void)
{
    zb_ret_t   zb_err_code;
	
		SysTick_Config(SystemCoreClock/100);
		NVIC_EnableIRQ(SysTick_IRQn);

    /* Initialize loging system and timers. */
    log_init();
    timer_init();

    /* Intitialise the FDS storage subsystem. */
    storage_init();

    /* Initialise the LEDs and PWM to steer the lock. */
    leds_pwm_init();

    /* Bluetooth initialization. */
    ble_stack_init();
    /* NUS Commander initialization. */
    nus_init(NULL);

    /* Add commands to NUS */
    add_nus_commands();

    /* Initialize Zigbee stack. */
    zigbee_init();

    /* Start execution. */
    NRF_LOG_INFO("BLE Zigbee dynamic door lock example started.");

    /** Start Zigbee Stack. */
    zb_err_code = zboss_start_no_autostart();
    ZB_ERROR_CHECK(zb_err_code);

    while(1)
    {
        zboss_main_loop_iteration();
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        if (m_garbage_flag)
        {
            m_garbage_flag = false;
            UNUSED_RETURN_VALUE(fds_gc());
        }
    }
}

When I added these lines (SysTick_Config and NVIC_EnableIRQ) the example stops working as normal after zigbee stack initilized (uart log) and gets stuck.

My questions are:

1. Why cant I use the SysTick?

2. What else is a good option to use instead? app timer?

Parents
  • So I tried the app timer, but I get the same result. I enabled timer 4 in de SDK config and made changes from the example \examples\peripheral\timer to make use of timer 4.

    /**
     * Copyright (c) 2018 - 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 zigbee_examples_multiprotocol_nus_door_lock main.c
     * @{
     * @ingroup  zigbee_examples
     * @brief    UART over BLE application with Zigbee HA Door Lock profile.
     *
     * This file contains the source code for a sample application that uses the Nordic UART service
     * and a door lock operating a Zigbee network.
     * This application uses the @ref srvlib_conn_params module.
     */
    #include "zboss_api.h"
    #include "zboss_api_addons.h"
    #include "zb_mem_config_min.h"
    #include "zb_error_handler.h"
    #include "zb_zcl_identify.h"
    #include "zigbee_helpers.h"
    
    #include "nus.h"
    
    #include "app_timer.h"
    #include "app_pwm.h"
    #include "boards.h"
    #include "bsp_btn_ble.h"
    #include "fds.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "nrf_drv_timer.h"
    const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(4);
    
    #define APP_BLE_OBSERVER_PRIO               1                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define IEEE_CHANNEL_MASK                   (1l << ZIGBEE_CHANNEL)                  /**< Scan only one, predefined channel to find the coordinator. */
    #define DOOR_LOCK_ENDPOINT                  8                                       /**< First source endpoint used to control Door Lock. */
    #define ERASE_PERSISTENT_CONFIG             ZB_FALSE                                /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. NOTE: If this option is set to ZB_TRUE then do full device erase for all network devices before running other samples. */
    #define ZIGBEE_NETWORK_STATE_LED            BSP_BOARD_LED_2                         /**< LED indicating that Door Lock successfully joind Zigbee network. */
    #define DOOR_LOCK_STATE_LED                 BSP_BOARD_LED_3                         /**< LED indicating that the state of the door (closed - ON, open - OFF). */
    #define DOOR_LOCK_CONFIG_FILE               0xBEEF                                  /**< ID of the file with the Door Lock configuration. */
    #define DOOR_LOCK_CONFIG_STATE_KEY          0x1337                                  /**< ID of the key with Door Lock state inside the configuration. */
    
    #define DOOR_LOCK_BASIC_APP_VERSION         01                                      /**< Version of the application software (1 byte). */
    #define DOOR_LOCK_BASIC_STACK_VERSION       10                                      /**< Version of the implementation of the Zigbee stack (1 byte). */
    #define DOOR_LOCK_BASIC_HW_VERSION          11                                      /**< Version of the hardware of the device (1 byte). */
    #define DOOR_LOCK_BASIC_MANUF_NAME          "Nordic"                                /**< Manufacturer name (32 bytes). */
    #define DOOR_LOCK_BASIC_MODEL_ID            "Door_Lock_v0.1"                        /**< Model number assigned by manufacturer (32-bytes long string). */
    #define DOOR_LOCK_BASIC_DATE_CODE           "20180113"                              /**< First 8 bytes specify the date of manufacturer of the device in ISO 8601 format (YYYYMMDD). Th rest (8 bytes) are manufacturer specific. */
    #define DOOR_LOCK_BASIC_POWER_SOURCE        ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE     /**< Type of power sources available for the device. For possible values see section 3.2.2.2.8 of ZCL specification. */
    #define DOOR_LOCK_BASIC_PH_ENV              ZB_ZCL_BASIC_ENV_UNSPECIFIED            /**< Describes the type of physical environment. For possible values see section 3.2.2.2.10 of ZCL specification. */
    #define DOOR_LOCK_BASIC_LOCATION_DESC       "Cave"                                  /**< Describes the physical location of the device (16 bytes). May be modified during commisioning process. */
    
    #define NUS_COMMAND_OPEN                    "sesame"                                /**< NUS command that will unlock the door. */
    #define NUS_COMMAND_CLOSE                   "hodor"                                 /**< NUS command that will lock the door. */
    
    #define LOCK_MECHANISM_PIN                  NRF_GPIO_PIN_MAP(0,29)                  /**< Pin 0.29 - the one which drives the PWM. */
    #define LOCK_MECHANISM_PWM_NAME             PWM1                                    /**< PWM instance used to drive the door lock. */
    #define LOCK_MECHANISM_PWM_TIMER            2                                       /**< Timer number used by PWM. */
    #define LOCK_MECHANISM_STATE_OPEN_DC        70                                      /**< Duty Cycle to maintain at the Lock Open state. */
    #define LOCK_MECHANISM_STATE_CLOSE_DC       55                                      /**< Duty Cycle to maintain at the Lock Close state. */
    
    #if !defined ZB_ED_ROLE
    #error Define ZB_ED_ROLE to compile Door Lock (End Device) source code.
    #endif
    
    APP_PWM_INSTANCE(LOCK_MECHANISM_PWM_NAME, LOCK_MECHANISM_PWM_TIMER);                /**< PWM Instance to steer the lock. */
    static volatile bool m_fds_initialized;                                             /**< Flag which signals the FDS subsystem being initialised. */
    static volatile bool m_garbage_flag;                                                /**< Flag which signals the need for garbage collector to clean up the flash. */
    
    /* Protocol-agnostic configuration of Door Lock. */
    typedef struct
    {
        uint32_t is_locked;
    } door_lock_configuration_t;
    
    /* Main application customizable context. Stores all settings and static values. */
    typedef struct door_lock_ctx_s
    {
        door_lock_configuration_t      configuration;  // Configuration has to be word-aligned, because of FDS, hence it's first in the structure.
        zb_zcl_basic_attrs_ext_t       basic_attr;
        zb_zcl_identify_attrs_t        identify_attr;
        zb_zcl_scenes_attrs_t          scenes_attr;
        zb_zcl_groups_attrs_t          groups_attr;
        zb_zcl_door_lock_attrs_t       door_lock_attr;
    } door_lock_ctx_t;
    
    static door_lock_ctx_t m_dev_ctx;
    
    /* Configuration record for the FDS subsystem. */
    static fds_record_t const m_configuration_record =
    {
        .file_id           = DOOR_LOCK_CONFIG_FILE,
        .key               = DOOR_LOCK_CONFIG_STATE_KEY,
        .data.p_data       = &m_dev_ctx.configuration,
        /* The length of a record is always expressed in 4-byte units (words). */
        .data.length_words = (sizeof(m_dev_ctx.configuration) + 3) / sizeof(uint32_t),
    };
    
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(basic_attr_list,
                                         &m_dev_ctx.basic_attr.zcl_version,
                                         &m_dev_ctx.basic_attr.app_version,
                                         &m_dev_ctx.basic_attr.stack_version,
                                         &m_dev_ctx.basic_attr.hw_version,
                                         m_dev_ctx.basic_attr.mf_name,
                                         m_dev_ctx.basic_attr.model_id,
                                         m_dev_ctx.basic_attr.date_code,
                                         &m_dev_ctx.basic_attr.power_source,
                                         m_dev_ctx.basic_attr.location_id,
                                         &m_dev_ctx.basic_attr.ph_env,
                                         m_dev_ctx.basic_attr.sw_ver);
    
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &m_dev_ctx.identify_attr.identify_time);
    
    ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, &m_dev_ctx.groups_attr.name_support);
    
    ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list,
                                      &m_dev_ctx.scenes_attr.scene_count,
                                      &m_dev_ctx.scenes_attr.current_scene,
                                      &m_dev_ctx.scenes_attr.current_group,
                                      &m_dev_ctx.scenes_attr.scene_valid,
                                      &m_dev_ctx.scenes_attr.name_support);
    
    ZB_ZCL_DECLARE_DOOR_LOCK_ATTRIB_LIST(door_lock_attr_list,
                                         &m_dev_ctx.door_lock_attr.lock_state,
                                         &m_dev_ctx.door_lock_attr.lock_type,
                                         &m_dev_ctx.door_lock_attr.actuator_enabled);
    
    ZB_HA_DECLARE_DOOR_LOCK_CLUSTER_LIST(door_lock_clusters,
                                         door_lock_attr_list,
                                         basic_attr_list,
                                         identify_attr_list,
                                         groups_attr_list,
                                         scenes_attr_list);
    
    ZB_HA_DECLARE_DOOR_LOCK_EP(door_lock_ep, DOOR_LOCK_ENDPOINT, door_lock_clusters);
    
    ZB_HA_DECLARE_DOOR_LOCK_CTX(door_lock_ctx, door_lock_ep);
    
    
    /**@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;
    
        UNUSED_PARAMETER(p_context);
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected");
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected");
                bsp_board_led_off(BSP_BOARD_LED_0);
                bsp_board_led_off(BSP_BOARD_LED_1);
                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_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;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /***************************************************************************************************
     * @section Initialization
     **************************************************************************************************/
    
    /**@brief Function for the SoftDevice initialization.
     *
     * @details This function 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);
    }
    
    
    /**@brief Function for initializing the nrf log module.
     */
    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 the application timer.
     */
    static void timer_init(void)
    {
        uint32_t error_code;
        error_code          = app_timer_init();
        APP_ERROR_CHECK(error_code);
    }
    
    
    /**@brief Functiom which essentially sets the lock state via PWM and stores the value in flash.
     *
     * @param[in] value ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED to lock,
     *                  ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED to unlock.
     */
    static zb_void_t set_lock_state(zb_uint8_t value)
    {
    
    
        if (value == ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED)
        {
            m_dev_ctx.configuration.is_locked = (uint32_t) true;
            bsp_board_led_on(DOOR_LOCK_STATE_LED);
            while (app_pwm_channel_duty_set(&LOCK_MECHANISM_PWM_NAME, 0, LOCK_MECHANISM_STATE_CLOSE_DC) == NRF_ERROR_BUSY)
            {
            }
            UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                                    ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                                    ZB_ZCL_CLUSTER_SERVER_ROLE,
                                                    ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                                    &value,
                                                    ZB_FALSE));
        }
        else if (value == ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED)
        {
            m_dev_ctx.configuration.is_locked = (uint32_t) false;
            bsp_board_led_off(DOOR_LOCK_STATE_LED);
            while (app_pwm_channel_duty_set(&LOCK_MECHANISM_PWM_NAME, 0, LOCK_MECHANISM_STATE_OPEN_DC) == NRF_ERROR_BUSY)
            {
            }
            UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                                    ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                                    ZB_ZCL_CLUSTER_SERVER_ROLE,
                                                    ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                                    &value,
                                                    ZB_FALSE));
        }
        else
        {
            NRF_LOG_WARNING("Wrong value of lock state - omitting");
            return;
        }
    
        ret_code_t        err_code;
        fds_record_desc_t desc = {0};
        fds_find_token_t  tok  = {0};
    
        err_code = fds_record_find(DOOR_LOCK_CONFIG_FILE, DOOR_LOCK_CONFIG_STATE_KEY, &desc, &tok);
        APP_ERROR_CHECK(err_code);
    
        err_code = fds_record_update(&desc, &m_configuration_record);
        APP_ERROR_CHECK(err_code);
        /* Set the garbage flag to dispatch the garbage collector. */
        m_garbage_flag = true;
    }
    
    /**@brief Function for initializing all clusters attributes.
     */
    static void door_lock_clusters_attr_init(void)
    {
        /* Basic cluster attributes data */
        m_dev_ctx.basic_attr.zcl_version   = ZB_ZCL_VERSION;
        m_dev_ctx.basic_attr.app_version   = DOOR_LOCK_BASIC_APP_VERSION;
        m_dev_ctx.basic_attr.stack_version = DOOR_LOCK_BASIC_STACK_VERSION;
        m_dev_ctx.basic_attr.hw_version    = DOOR_LOCK_BASIC_HW_VERSION;
    
        /* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte should
         * contain string length without trailing zero.
         *
         * For example "test" string wil be encoded as:
         *   [(0x4), 't', 'e', 's', 't']
         */
        ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.mf_name,
                              DOOR_LOCK_BASIC_MANUF_NAME,
                              ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_MANUF_NAME));
    
        ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                              DOOR_LOCK_BASIC_MODEL_ID,
                              ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_MODEL_ID));
    
        ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                              DOOR_LOCK_BASIC_DATE_CODE,
                              ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_DATE_CODE));
    
        m_dev_ctx.basic_attr.power_source = DOOR_LOCK_BASIC_POWER_SOURCE;
    
        ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                              DOOR_LOCK_BASIC_LOCATION_DESC,
                              ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_LOCATION_DESC));
    
    
        m_dev_ctx.basic_attr.ph_env = DOOR_LOCK_BASIC_PH_ENV;
    
        /* Identify cluster attributes data */
        m_dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    
        /* Door Lock cluster attributes data */
        m_dev_ctx.door_lock_attr.lock_type        = ZB_ZCL_ATTR_DOOR_LOCK_LOCK_TYPE_OTHER;
        m_dev_ctx.door_lock_attr.lock_state       = m_dev_ctx.configuration.is_locked ? ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED : ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED;
        m_dev_ctx.door_lock_attr.actuator_enabled = ZB_TRUE;
    
        if ((bool)m_dev_ctx.configuration.is_locked == false)
        {
            set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);
        }
        else
        {
            set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
        }
    }
    
    /**@brief Handler of the FDS events.
     *
     * @param[in] p_evt Pointer to the FDS context.
     */
    static void fds_evt_handler(fds_evt_t const * p_evt)
    {
        switch (p_evt->id)
        {
            case FDS_EVT_INIT:
                if (p_evt->result == NRF_SUCCESS)
                {
                    m_fds_initialized = true;
                }
                break;
    
            default:
                break;
        }
    }
    
    /**@brief Function to initialise FDS storage and read the initial lock state out of it.
     */
    static void storage_init(void)
    {
        ret_code_t err_code;
    
        /* Register the handler. */
        UNUSED_RETURN_VALUE(fds_register(fds_evt_handler));
    
        err_code = fds_init();
        APP_ERROR_CHECK(err_code);
    
        /* Wait until we're initialised. */
        while (!m_fds_initialized)
        {
        }
    
        /* Get the record data out. */
        fds_record_desc_t desc = {0};
        fds_find_token_t  tok  = {0};
    
        err_code = fds_record_find(DOOR_LOCK_CONFIG_FILE, DOOR_LOCK_CONFIG_STATE_KEY, &desc, &tok);
        if (err_code == NRF_SUCCESS)
        {
            NRF_LOG_INFO("Previous configuration found");
    
            /* A config file is in flash. Let's update the RAM value. */
            fds_flash_record_t config = {0};
    
            /* Open the record and read its contents. */
            err_code = fds_record_open(&desc, &config);
            APP_ERROR_CHECK(err_code);
    
            /* Copy the configuration from flash into the configuration in the RAM. */
            memcpy(&m_dev_ctx.configuration, config.p_data, sizeof(door_lock_configuration_t));
    
            NRF_LOG_INFO("Loaded configuration: door is %s", m_dev_ctx.configuration.is_locked ? "locked" : "unlocked");
    
            /* Close the record when done reading. */
            err_code = fds_record_close(&desc);
            APP_ERROR_CHECK(err_code);
        }
        else
        {
            NRF_LOG_INFO("Previous configuration not found, creating one");
    
            err_code = fds_record_write(&desc, &m_configuration_record);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    /**@brief Function for initializing LEDs and PWM.
     */
    static void leds_pwm_init(void)
    {
        ret_code_t       error_code;
        app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L, LOCK_MECHANISM_PIN);
    
        /* Initialize LEDs - use BSP to control them. */
        error_code = bsp_init(BSP_INIT_LEDS, NULL);
        APP_ERROR_CHECK(error_code);
        bsp_board_leds_off();
    
        /* Initialize PWM running on timer 1 in order to control Door Lock servo. */
        error_code = app_pwm_init(&LOCK_MECHANISM_PWM_NAME, &pwm_cfg, NULL);
        APP_ERROR_CHECK(error_code);
    
        app_pwm_enable(&LOCK_MECHANISM_PWM_NAME);
    
    }
    
    /**@brief Callback function for handling ZCL commands.
     *
     * @param[in]   bufid   Reference to Zigbee stack buffer used to pass received data.
     */
    static zb_void_t zcl_device_cb(zb_bufid_t bufid)
    {
        zb_zcl_device_callback_param_t * p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
    
        /* Set default response value. */
        p_device_cb_param->status = RET_OK;
    
        switch (p_device_cb_param->device_cb_id)
        {
            case ZB_ZCL_DOOR_LOCK_UNLOCK_DOOR_CB_ID:
                set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);
                break;
    
            case ZB_ZCL_DOOR_LOCK_LOCK_DOOR_CB_ID:
                set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
                break;
    
            default:
                p_device_cb_param->status = RET_ERROR;
                break;
        }
    }
    
    /**@brief Function for initializing the Zigbee Stack.
     */
    static void zigbee_init(void)
    {
        zb_ieee_addr_t ieee_addr;
    
        /* Set Zigbee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize Zigbee stack. */
        ZB_INIT("door_lock_nus");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        /* Set up Zigbee protocol main parameters. */
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    
        zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(300));
        zb_set_rx_on_when_idle(ZB_FALSE);
    
        /* Register callback for handling ZCL commands. */
        ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
        /* Register Door Lock device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&door_lock_ctx);
    
        /* Initialize clusters' attributes. */
        door_lock_clusters_attr_init();
    }
    
    /**@brief Lock the Lock via the BLE connection.
     *
     * @param[in] count Unused parameter, inherited from NUS command template.
     */
    static void cmd_lock(int count)
    {
        UNUSED_PARAMETER(count);
        set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
    }
    
    /**@brief Unlock the Lock via the BLE connection.
     *
     * @param[in] count Unused parameter, inherited from NUS command template.
     */
    static void cmd_unlock(int count)
    {
        UNUSED_PARAMETER(count);
        set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);
    }
    
    /**@brief Function which adds the commands to the NUS commander.
     */
    static void add_nus_commands(void)
    {
        UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_OPEN, cmd_unlock));
        UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_CLOSE, cmd_lock));
    }
    
    /**@brief Zigbee stack event handler.
     *
     * @param[in]   bufid   Reference to the Zigbee stack buffer used to pass signal.
     */
    void zboss_signal_handler(zb_bufid_t bufid)
    {
        /* Update network status LED */
        zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    
        /* Call default signal handler. */
        ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    
        if (bufid)
        {
            zb_buf_free(bufid);
        }
    }
    
    /**
     * @brief Handler for timer events.
     */
    void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
        static uint32_t i;
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE4:
                i++;
                break;
    
            default:
                //Do nothing.
                break;
        }
    }
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
        zb_ret_t   zb_err_code;
    		uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
        uint32_t time_ticks;
    
        /* Initialize loging system and timers. */
        log_init();
        timer_init();
    	
        //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        zb_err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_event_handler);
        APP_ERROR_CHECK(zb_err_code);
    
        time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);
    
        nrf_drv_timer_extended_compare(
             &TIMER_LED, NRF_TIMER_CC_CHANNEL4, time_ticks, NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK, true);
    
        //nrf_drv_timer_enable(&TIMER_LED);
    
        /* Intitialise the FDS storage subsystem. */
        storage_init();
    
        /* Initialise the LEDs and PWM to steer the lock. */
        leds_pwm_init();
    
        /* Bluetooth initialization. */
        ble_stack_init();
        /* NUS Commander initialization. */
        nus_init(NULL);
    
        /* Add commands to NUS */
        add_nus_commands();
    
        /* Initialize Zigbee stack. */
        zigbee_init();
    
        /* Start execution. */
        NRF_LOG_INFO("BLE Zigbee dynamic door lock example started.");
    
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start_no_autostart();
        ZB_ERROR_CHECK(zb_err_code);
    
        while(1)
        {
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
            if (m_garbage_flag)
            {
                m_garbage_flag = false;
                UNUSED_RETURN_VALUE(fds_gc());
            }
        }
    }
    
    
    /**
     * @}
     */
    

    When I debug, the timer fires every time, but the zigbee log info shows me the same problem (started stack, but nothing else).

    When I remove the app timer (nrf_drv_timer_enable) zigbee joins again

    .

  • Hi,

    I see that you did not set interrupt priority for SysTick IRQ with NVIC_SetPriority. The reset value is 0, so the highest priority. This might be the reason for why you are having problems with SysTick.

    I tested your application, but I was unable to reproduce the issue. Have you made any other changes to the application? Have you made any changes to sdk_config.h besides enabling TIMER4? 

    Best regards,

    Marte

  • I tried setting NVIC_SetPriority(SysTick_IRQn, 100);, same result unfortunatly.

    The example project with the app timer, sdk_config.h was changed to output the serial data to baud 115200, but not much else was changed.

    here it is:

    8561.sdk_config.h

    When I comment the line:

    nrf_drv_timer_enable(&TIMER_LED);

    it joins. When I dont, it wont...

Reply Children
Related