/**
 * Copyright (c) 2018 - 2019, 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_light_bulb main.c
 * @{
 * @ingroup zigbee_examples
 * @brief Dimmable light sample (HA profile)
 */

#include "sdk_config.h"
#include "zboss_api.h"
#include "zb_mem_config_med.h"
#include "zb_ha_dimmable_light.h"
#include "zb_error_handler.h"
#include "zb_nrf52840_internal.h"
#include "zigbee_helpers.h"

#include "bsp.h"
#include "boards.h"
#include "app_pwm.h"
#include "app_timer.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "nrf_drv_gpiote.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_saadc.h"
#include "nrf_delay.h"

#define MAX_CHILDREN                      10                                    /**< The maximum amount of connected devices. Setting this value to 0 disables association to this device.  */
//              /**< Scan only one, predefined channel to find the coordinator. */
#define IEEE_CHANNEL_MASK                  (ZB_TRANSCEIVER_ALL_CHANNELS_MASK)
#define HA_DIMMABLE_LIGHT_ENDPOINT        10                                    /**< Device endpoint, used to receive light controlling commands. */
#define ERASE_PERSISTENT_CONFIG           ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */


/* Basic cluster attributes initial values. */
#define BULB_INIT_BASIC_APP_VERSION       01                                    /**< Version of the application software (1 byte). */
#define BULB_INIT_BASIC_STACK_VERSION     10                                    /**< Version of the implementation of the ZigBee stack (1 byte). */
#define BULB_INIT_BASIC_HW_VERSION        11                                    /**< Version of the hardware of the device (1 byte). */
#define BULB_INIT_BASIC_MANUF_NAME        "Nordic"                              /**< Manufacturer name (32 bytes). */
#define BULB_INIT_BASIC_MODEL_ID          "Dimable_Light_v0.1"                  /**< Model number assigned by manufacturer (32-bytes long string). */
#define BULB_INIT_BASIC_DATE_CODE         "20180416"                            /**< First 8 bytes specify the date of manufacturer of the device in ISO 8601 format (YYYYMMDD). The rest (8 bytes) are manufacturer specific. */
#define BULB_INIT_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 BULB_INIT_BASIC_LOCATION_DESC     "Office desk"                         /**< Describes the physical location of the device (16 bytes). May be modified during commisioning process. */
#define BULB_INIT_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 IDENTIFY_MODE_ENTER_BUTTON        BSP_BOARD_BUTTON_0                    /**< Enter the Bulb into the Identify mode. */
#ifdef  BOARD_PCA10059                                                          /**< If it is Dongle */
#define ZIGBEE_NETWORK_STATE_LED          BSP_BOARD_LED_0                       /**< LED indicating that light switch successfully joind ZigBee network. */
#else
#define ZIGBEE_NETWORK_STATE_LED          BSP_BOARD_LED_3                       /**< LED indicating that light switch successfully joind ZigBee network. */
#endif


/* Declare endpoint for Dimmable Light device with scenes. */
#define ZB_HA_DECLARE_LIGHT_EP(ep_name, ep_id, cluster_list)                         \
  ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC(ep_name, ep_id,                       \
    ZB_HA_DIMMABLE_LIGHT_IN_CLUSTER_NUM, ZB_HA_DIMMABLE_LIGHT_OUT_CLUSTER_NUM);      \
  ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_info## device_ctx_name,               \
                                     ZB_HA_DIMMABLE_LIGHT_REPORT_ATTR_COUNT);        \
  ZBOSS_DEVICE_DECLARE_LEVEL_CONTROL_CTX(cvc_alarm_info## device_ctx_name,           \
                                         ZB_HA_DIMMABLE_LIGHT_CVC_ATTR_COUNT);       \
  ZB_AF_DECLARE_ENDPOINT_DESC(ep_name, ep_id, ZB_AF_HA_PROFILE_ID,                   \
                              0,     \
                              NULL,                 \
                              ZB_ZCL_ARRAY_SIZE(cluster_list, zb_zcl_cluster_desc_t),\
                              cluster_list,                                          \
                              (zb_af_simple_desc_1_1_t*)&simple_desc_##ep_name,      \
                              ZB_HA_DIMMABLE_LIGHT_REPORT_ATTR_COUNT,                \
                              reporting_info## device_ctx_name,                      \
                              ZB_HA_DIMMABLE_LIGHT_CVC_ATTR_COUNT,                   \
                              cvc_alarm_info## device_ctx_name)

#if !defined ZB_ROUTER_ROLE
#error Define ZB_ROUTER_ROLE to compile light bulb (Router) source code.
#endif

/********************Custom MACRO Pin Mapping*******************************/
#define ZERO_CROSS_DETECTION       NRF_GPIO_PIN_MAP(0,6)      //ZCD pin 
#define DIMMER_TRIGGER             NRF_GPIO_PIN_MAP(0,8)      //Trigger pin
#define EXTSW1_CONTROL             BSP_BUTTON_1         //ExtSW1 pin

//#define EXTSW2_CONTROL             NRF_GPIO_PIN_MAP(0,26)     //EXtSW2 pin

#define KEY_UP                     NRF_GPIO_PIN_MAP(1,10)     //Up pin
#define KEY_DOWN                   NRF_GPIO_PIN_MAP(1,13)     //Down pin

//#define KEY_LEARN                  NRF_GPIO_PIN_MAP(0,24)     //Learn pin
//#define OPTIONAL1_KEY              NRF_GPIO_PIN_MAP(1,15)     //Optional1 pin
//#define OPTIONAL2_KEY              NRF_GPIO_PIN_MAP(0,2)      //Optional2 pin
 
#define HALFCYCLE_10MSTIME          10000       //10msec for half cycle time 
#define MAX_DUTYCYCLE               9000       //max duty cycle 9msec

#define MIN_ADC_VAL                 78         //minimum adc value with repsective capacitor minimum voltage 

void timer2_Configuration (void);       //timer 2 configured as duty cycle timer 
void timer2_DimmingControlling_tme(uint32_t ui32Timer2Dutycycle); 

void timer1_Configuration (void);       //timer 1 configured as fixed timer for negative cycle 
void timer1_fixedtimeOperation (uint32_t ui32fixedtime);


/* Basic cluster attributes. */
typedef struct
{
    zb_uint8_t zcl_version;
    zb_uint8_t app_version;
    zb_uint8_t stack_version;
    zb_uint8_t hw_version;
    zb_char_t  mf_name[32];
    zb_char_t  model_id[32];
    zb_char_t  date_code[16];
    zb_uint8_t power_source;
    zb_char_t  location_id[17];
    zb_uint8_t ph_env;
    zb_char_t  sw_ver[17];
} bulb_device_basic_attr_t;

/* Identify cluster attributes. */
typedef struct
{
    zb_uint16_t identify_time;
} bulb_device_identify_attr_t;

/* ON/Off cluster attributes. */
typedef struct
{
    zb_bool_t   on_off;
    zb_bool_t   global_scene_ctrl;
    zb_uint16_t on_time;
    zb_uint16_t off_wait_time;
} bulb_device_on_off_attr_t;

/* Level Control cluster attributes. */
typedef struct
{
    zb_uint8_t  current_level;
    zb_uint16_t remaining_time;
} bulb_device_level_control_attr_t;

/* Scenes cluster attributes. */
typedef struct
{
    zb_uint8_t  scene_count;
    zb_uint8_t  current_scene;
    zb_uint8_t  scene_valid;
    zb_uint8_t  name_support;
    zb_uint16_t current_group;
} bulb_device_scenes_attr_t;

/* Groups cluster attributes. */
typedef struct
{
    zb_uint8_t name_support;
} bulb_device_groups_attr_t;

/* Main application customizable context. Stores all settings and static values. */
typedef struct
{
    bulb_device_basic_attr_t         basic_attr;
    bulb_device_identify_attr_t      identify_attr;
    bulb_device_scenes_attr_t        scenes_attr;
    bulb_device_groups_attr_t        groups_attr;
    bulb_device_on_off_attr_t        on_off_attr;
    bulb_device_level_control_attr_t level_control_attr;
} bulb_device_ctx_t;

/* constant declaration -----------------------------------------------*/
const nrf_drv_timer_t TIMER_1 = NRF_DRV_TIMER_INSTANCE(2);  // Created instance as timer 1
const nrf_drv_timer_t TIMER_2 = NRF_DRV_TIMER_INSTANCE(4);  // Created instance as timer 2

/*************GLOBAL VATIABLES***************************************/
uint32_t time2_ticks;
uint32_t ui32DimmerONTime = 0;
uint32_t CurrentDutyCycle = 0;
uint32_t ui32fixedtime = 0;
uint32_t ui32Brightness = 0; 
uint32_t ui32PrevDutyCycle = 0;

bool boolIgnorelongpress = false;

//push button config variables
uint16_t ui8PushbuttonStatusCount = 0;
uint8_t ui8Pushbuttonstatus = 0;

bool boolpushbuttonStatus = false;
bool boolpushbuttonContinue = false;
bool boolBrightnesslevelcontrol = false;
bool boolNextZCDProcess = false;

//button_2 global variables
uint16_t ui16PushButton2Count = 0;
uint8_t ui8PushButton2status = 0;
bool boolPushButton2Status = false;
bool boolPushButton2Continue = false;
bool boolPushButton2BrightnessControl = false;

//button_3 global variables
uint16_t ui16PushButton3Count = 0;
uint8_t ui8PushButton3status = 0;
bool boolPushButton3Status = false;
bool boolPushButton3Continue = false;
bool boolPushButton3BrightnessControl = false;

//SAADC/ADC variables
uint16_t ui16CurrentADCValue = 255; 
uint32_t ui32DutyCycle100 = MAX_DUTYCYCLE;

////Flag to monitor ADC value comparision with w. r. t. 0.7V while initial sequence implmentation
//bool boolADCComparisonComplete = true;
////Monitors ADC Reading while initial sequence implmentation
//bool boolADCReadingComplete = false;
////Flag indicating initial sequence operation or normal operation
bool boolInitialSequenceMeasurement = false;

bool boolSetInit30 = false;
float Val = 0, Val2=0;
uint32_t Result =0;


static nrf_saadc_value_t adc_buf[1];

/*************************END****************************************/


static bulb_device_ctx_t m_dev_ctx;

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_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);

/* On/Off cluster attributes additions data */
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST_EXT(on_off_attr_list,
                                      &m_dev_ctx.on_off_attr.on_off,
                                      &m_dev_ctx.on_off_attr.global_scene_ctrl,
                                      &m_dev_ctx.on_off_attr.on_time,
                                      &m_dev_ctx.on_off_attr.off_wait_time);

ZB_ZCL_DECLARE_LEVEL_CONTROL_ATTRIB_LIST(level_control_attr_list,
                                         &m_dev_ctx.level_control_attr.current_level,
                                         &m_dev_ctx.level_control_attr.remaining_time);

ZB_HA_DECLARE_DIMMABLE_LIGHT_CLUSTER_LIST(dimmable_light_clusters,
                                          basic_attr_list,
                                          identify_attr_list,
                                          groups_attr_list,
                                          scenes_attr_list,
                                          on_off_attr_list,
                                          level_control_attr_list);

ZB_HA_DECLARE_LIGHT_EP(dimmable_light_ep,
                       HA_DIMMABLE_LIGHT_ENDPOINT,
                       dimmable_light_clusters);

ZB_HA_DECLARE_DIMMABLE_LIGHT_CTX(dimmable_light_ctx,
                                 dimmable_light_ep);



/**@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();
}

/*********Brightness set command from Alexa or App*******************************************/
/**@brief Sets brightness of LED
 *
 * @param[in] brightness_level Brightness level, allowed values 0 ... 255, 0 - turn off, 255 - full brightness
 */
static void light_bulb_onboard_set_brightness(zb_uint8_t brightness_level)
{
    
    /* ZigBee level control cluster uses values from 0 up to 255. */
     //Convert brigthness level values as per 0 to 100 range 
     ui32DimmerONTime = ((brightness_level * 100)/ 255);
     //set brightness level to 100% Max 
    // CurrentDutyCycle = (((ui32DimmerONTime * 0.75) + 25) * 100); 

     CurrentDutyCycle = (ui32DimmerONTime * ui32DutyCycle100)/100;   
}


/**@brief Sets brightness of bulb luminous executive element
 *
 * @param[in] brightness_level Brightness level, allowed values 0 ... 255, 0 - turn off, 255 - full brightness
 */
static void light_bulb_set_brightness(zb_uint8_t brightness_level)
{
    light_bulb_onboard_set_brightness(brightness_level);
}

/**@brief Function for setting the light bulb brightness.
  *
  * @param[in]   new_level   Light bulb brightness value.
 */
static void level_control_set_value(zb_uint16_t new_level)
{
    NRF_LOG_INFO("Set level value: %i", new_level);

    ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT,                                       
                         ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL,            
                         ZB_ZCL_CLUSTER_SERVER_ROLE,                 
                         ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, 
                         (zb_uint8_t *)&new_level,                                       
                         ZB_FALSE);                                  

    /* According to the table 7.3 of Home Automation Profile Specification v 1.2 rev 29, chapter 7.1.3. */
    if (new_level == 0)
    {
        zb_uint8_t value = ZB_FALSE;
        ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_ON_OFF,    
                             ZB_ZCL_CLUSTER_SERVER_ROLE,  
                             ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
                             &value,                        
                             ZB_FALSE);                   
    }
    else
    {
        zb_uint8_t value = ZB_TRUE;
        ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_ON_OFF,    
                             ZB_ZCL_CLUSTER_SERVER_ROLE,  
                             ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
                             &value,                        
                             ZB_FALSE);
    }

    light_bulb_set_brightness(new_level);
}


/**@brief Function for turning ON/OFF the light bulb.
 *
 * @param[in]   on   Boolean light bulb state.
 */
static void on_off_set_value(zb_bool_t on)
{
    NRF_LOG_INFO("Set ON/OFF value: %i", on);

    ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT, 
                         ZB_ZCL_CLUSTER_ID_ON_OFF,    
                         ZB_ZCL_CLUSTER_SERVER_ROLE,  
                         ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
                         (zb_uint8_t *)&on,                        
                         ZB_FALSE);

    if (on)
    {
        level_control_set_value(m_dev_ctx.level_control_attr.current_level);  
        boolIgnorelongpress = false;    
    }
    else
    {
        light_bulb_set_brightness(0U);  
        CurrentDutyCycle = 0;
        boolIgnorelongpress = true; 
    }
}



/**@brief Function for initializing LEDs and a single PWM channel.
 */
static void leds_buttons_init(void)
{
    /* Initialize all LEDs*/
    /* Configure board. */
    bsp_board_init(BSP_INIT_LEDS);

    
}

/**@brief Function for initializing all clusters attributes.
 */
static void bulb_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   = BULB_INIT_BASIC_APP_VERSION;
    m_dev_ctx.basic_attr.stack_version = BULB_INIT_BASIC_STACK_VERSION;
    m_dev_ctx.basic_attr.hw_version    = BULB_INIT_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,
                          BULB_INIT_BASIC_MANUF_NAME,
                          ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_MANUF_NAME));

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                          BULB_INIT_BASIC_MODEL_ID,
                          ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_MODEL_ID));

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                          BULB_INIT_BASIC_DATE_CODE,
                          ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_DATE_CODE));

    m_dev_ctx.basic_attr.power_source = BULB_INIT_BASIC_POWER_SOURCE;

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                          BULB_INIT_BASIC_LOCATION_DESC,
                          ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_LOCATION_DESC));


    m_dev_ctx.basic_attr.ph_env = BULB_INIT_BASIC_PH_ENV;

    /* Identify cluster attributes data */
    m_dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;

    /* On/Off cluster attributes data */
    m_dev_ctx.on_off_attr.on_off = (zb_bool_t)ZB_ZCL_ON_OFF_IS_ON;

    m_dev_ctx.level_control_attr.current_level  = ZB_ZCL_LEVEL_CONTROL_LEVEL_MAX_VALUE;
    m_dev_ctx.level_control_attr.remaining_time = ZB_ZCL_LEVEL_CONTROL_REMAINING_TIME_DEFAULT_VALUE;

    ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT, 
                         ZB_ZCL_CLUSTER_ID_ON_OFF,    
                         ZB_ZCL_CLUSTER_SERVER_ROLE,  
                         ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
                         (zb_uint8_t *)&m_dev_ctx.on_off_attr.on_off,                        
                         ZB_FALSE);                   

    ZB_ZCL_SET_ATTRIBUTE(HA_DIMMABLE_LIGHT_ENDPOINT,                                       
                         ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL,            
                         ZB_ZCL_CLUSTER_SERVER_ROLE,                 
                         ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, 
                         (zb_uint8_t *)&m_dev_ctx.level_control_attr.current_level,                                       
                         ZB_FALSE);                                  
}

/**@brief Function which tries to sleep down the MCU 
 *
 * Function which sleeps the MCU on the non-sleepy End Devices to optimize the power saving.
 * The weak definition inside the OSIF layer provides some minimal working template
 */
zb_void_t zb_osif_go_idle(zb_void_t)
{
    //TODO: implement your own logic if needed
    zb_osif_wait_for_event();
}

/**@brief Callback function for handling ZCL commands.
 *
 * @param[in]   param   Reference to ZigBee stack buffer used to pass received data.
 */
static zb_void_t zcl_device_cb(zb_uint8_t param)
{
    zb_uint8_t                       cluster_id;
    zb_uint8_t                       attr_id;
    zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
    zb_zcl_device_callback_param_t * p_device_cb_param =
                     ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);

    NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);

    /* Set default response value. */
    p_device_cb_param->status = RET_OK;

    switch (p_device_cb_param->device_cb_id)
    {
        case ZB_ZCL_LEVEL_CONTROL_SET_VALUE_CB_ID:
            NRF_LOG_INFO("Level control setting to %d", p_device_cb_param->cb_param.level_control_set_value_param.new_value);
            level_control_set_value(p_device_cb_param->cb_param.level_control_set_value_param.new_value);
            break;

        case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
            cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
            attr_id    = p_device_cb_param->cb_param.set_attr_value_param.attr_id;

            if (cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF)
            {
                uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;

                NRF_LOG_INFO("on/off attribute setting to %hd", value);
                if (attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID)
                {
                    on_off_set_value((zb_bool_t) value);
                }
            }
            else if (cluster_id == ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL)
            {
                uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;

                NRF_LOG_INFO("level control attribute setting to %hd", value);
                if (attr_id == ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID)
                {
                    level_control_set_value(value);
                }
            }
            else
            {
                /* Other clusters can be processed here */
                NRF_LOG_INFO("Unhandled cluster attribute id: %d", cluster_id);
            }
            break;

        default:
            p_device_cb_param->status = RET_ERROR;
            break;
    }

    NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
}

/**@brief ZigBee stack event handler.
 *
 * @param[in]   param   Reference to ZigBee stack buffer used to pass arguments (signal).
 */
void zboss_signal_handler(zb_uint8_t param)
{
    zb_zdo_app_signal_hdr_t  * p_sg_p = NULL;
    zb_zdo_app_signal_type_t   sig    = zb_get_app_signal(param, &p_sg_p);
    zb_ret_t                   status = ZB_GET_APP_SIGNAL_STATUS(param);
    zb_bool_t                  comm_status;

    switch (sig)
    {
        case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
        case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            if (status == RET_OK)
            {
                NRF_LOG_INFO("Joined network successfully");
                bsp_board_led_on(ZIGBEE_NETWORK_STATE_LED);
            }
            else
            {
                NRF_LOG_ERROR("Failed to join network. Status: %d", status);
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
                ZB_COMM_STATUS_CHECK(comm_status);
            }
            break;

        case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
            if (status != RET_OK)
            {
                NRF_LOG_WARNING("Production config is not present or invalid");
            }
            break;

        case ZB_ZDO_SIGNAL_LEAVE:
            if (status == RET_OK)
            {
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);

                zb_zdo_signal_leave_params_t * p_leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_leave_params_t);
                NRF_LOG_INFO("Network left. Leave type: %d", p_leave_params->leave_type);
            }
            else
            {
                NRF_LOG_ERROR("Unable to leave network. Status: %d", status);
            }
            break;

        default:
            /* Unhandled signal. For more information see: zb_zdo_app_signal_type_e and zb_ret_e */
            NRF_LOG_INFO("Unhandled signal %d. Status: %d", sig, status);
            break;
    }

    if (param)
    {
        ZB_FREE_BUF_BY_REF(param);
    }
}

/* This Initial sequence to carried out to measure the intensity level for light controlling 
*  with respect to voltage level at input capacitor.
*
*/



static void InitialSequence(void)
{
  ret_code_t err_code;
  boolInitialSequenceMeasurement = true;
  
  ui32Brightness = 0;
  //read ADC value of capacitor
  err_code = nrf_drv_saadc_sample();
  APP_ERROR_CHECK(err_code);

  while((ui16CurrentADCValue >= MIN_ADC_VAL) && (ui32Brightness <= ui32DutyCycle100))
  {
      ui32PrevDutyCycle = ui32Brightness;
      ui32Brightness += 100;

      nrf_drv_gpiote_in_event_enable(ZERO_CROSS_DETECTION,true); //enable ZCD

      err_code = nrf_drv_saadc_sample();//trigger ADC
      APP_ERROR_CHECK(err_code);

      nrf_delay_ms(50); //adding delay able to read adc values 

  }
  ui32DutyCycle100 = ui32PrevDutyCycle;

  on_off_set_value(0U);
  ui32DimmerONTime = 0;
  boolSetInit30 = true;
  boolInitialSequenceMeasurement = false;  
}
/***************************SAADC Configuration Start*********************************************/

/**@brief Function for handling the ADC interrupt.
 *
 * @details  This function will fetch the conversion result from the ADC, convert the value into
 *           percentage and send it to peer.
 */
void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        
        uint32_t          err_code;

        ui16CurrentADCValue = p_event->data.done.p_buffer[0];  

        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
        APP_ERROR_CHECK(err_code);
      
    }
}

/**@brief Function for configuring ADC to do capacitor voltage conversion.
 */
static void adc_configure(void)
{
    ret_code_t err_code;
    nrf_drv_saadc_config_t saadc_config;
    saadc_config.resolution = NRF_SAADC_RESOLUTION_8BIT;   //8 bit resolution
    saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOW;
    
    err_code = nrf_drv_saadc_init(&saadc_config, saadc_event_handler);
    APP_ERROR_CHECK(err_code);
    
   //singale shot and channel config 
   //If input range is 0 to 2.26V then set reference as VDD/4 and gain as 1/3
   nrf_saadc_channel_config_t channel_config;
   channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
   channel_config.gain = NRF_SAADC_GAIN1_4;
   channel_config.acq_time = NRF_SAADC_ACQTIME_10US;
   channel_config.mode = NRF_SAADC_MODE_SINGLE_ENDED;
   channel_config.pin_n = NRF_SAADC_INPUT_DISABLED; 
   channel_config.pin_p = NRF_SAADC_INPUT_AIN2;
   channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
   channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;

    err_code = nrf_drv_saadc_channel_init(2, &channel_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(&adc_buf[0], 1);
    APP_ERROR_CHECK(err_code);
}

/***************************SAADC Configuration End*********************************************/

/***************************ZCD pin handler functions Start*********************************************/
void zcd_in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) //ZCD Interrupt Handler Routine
{
     if(CurrentDutyCycle == 0)  //if the duty cycle is zero then enable ZCD do not disable it 
     {
        nrf_drv_gpiote_in_event_enable(ZERO_CROSS_DETECTION, true);
     }
     else
     {
       //disable ZCD event 
       nrf_drv_gpiote_in_event_disable(ZERO_CROSS_DETECTION);
     }

    if(!boolInitialSequenceMeasurement)
    {
       //Positive cycle operation
       //Computation of Ramp up and Ramp down during brightness change
        if(CurrentDutyCycle != ui32Brightness)
        {
          if(ui32Brightness < CurrentDutyCycle)         //ui32Brightness is the current brightness value that is compared with user set value
          {
              ui32Brightness += 50;	 	//increment brightness
              if(ui32Brightness >= ui32DutyCycle100)        //the maximum duty cycle is 10msec
              {
                ui32Brightness = ui32DutyCycle100;	
              }
          }
          if(ui32Brightness > CurrentDutyCycle)
          {
              ui32Brightness -= 50;	 	 //decrement brightness
              if(ui32Brightness <= 0)
              {
                 ui32Brightness = 0;
              }

          }
        } 
    }
             
       //start timer1 for 10msec timer to estimate negative cycle start
       timer1_fixedtimeOperation(HALFCYCLE_10MSTIME);      //timer 1 start for 10msec

       if(ui32Brightness != 0) //User has turned off the light
       {         
          if(ui32Brightness >= MAX_DUTYCYCLE) //duty cycle is more than 9ms
           {
             timer2_DimmingControlling_tme(MAX_DUTYCYCLE);  //timer 2 started for brightness control 
             nrf_gpio_pin_write(DIMMER_TRIGGER,1);     //when duty cycle is greater than 0 set trigger pin HIGH 
           }
           else
           {
             timer2_DimmingControlling_tme(ui32Brightness);  //timer 2 started for brightness control
             nrf_gpio_pin_write(DIMMER_TRIGGER,1);     //when duty cycle is greater than 0 set trigger pin HIGH
           }
       }
       else
       {
          nrf_gpio_pin_write(DIMMER_TRIGGER,0);    //when duty cycle is 0 set trigger pin LOW 
          
           if(boolSetInit30)
           {
              Val = (ui32DutyCycle100*100)/MAX_DUTYCYCLE;
              Val2 = ((Val*255)/100);
              Result = (uint32_t)((Val2*30)/100);
              boolSetInit30 = false;
              m_dev_ctx.level_control_attr.current_level = Result;
              level_control_set_value(m_dev_ctx.level_control_attr.current_level);
           }
       }
         
}
/***************************ZCD pin handler functions End*********************************************/

/***************************Button1 pin handler functions Start*********************************************/
void button_in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    //controlling logic using button press interrupt
     boolpushbuttonStatus = true; // if the push button press detect then set flag true
     boolBrightnesslevelcontrol = !boolBrightnesslevelcontrol;   //toggle brightness control flag to increment/decrement level accordingly.
     ui8PushbuttonStatusCount = 0;
}
/***************************Button1 pin handler functions End*********************************************/

/***************************Button2 pin handler functions Start*********************************************/
void button2_in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    //button_2 pressed turn ON the LED and Increment the brightness
      boolPushButton2Status = true; //if the push button_2 press detect then set flag
      boolPushButton2BrightnessControl = true;
}
/***************************Button2 pin handler functions End*********************************************/

/***************************Button3 pin handler functions Start*********************************************/
void button3_in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    //button_3 pressed turn OFF the LED and Decrement the brightness
      boolPushButton3Status = true; //if the push button_2 press detect then set flag
      boolPushButton3BrightnessControl = true;
}     
/***************************Button3 pin handler functions End*********************************************/

/********** timer 1 Configuration Start *************************************************/
/**
* @brief Handler for timer events.
* 
* timer1_event_handler function to turn OFF the bulb and disable the timer 
*   
*/
void timer1_event_handler(nrf_timer_event_t event_type, void* p_context)
{   
      nrf_drv_timer_disable(&TIMER_1);        //disable timer 1
      
      //Negative cycle operation       
       if(ui32Brightness != 0) //User has turned off the light
       {
           if(ui32Brightness >= MAX_DUTYCYCLE) //duty cycle is more than 9ms
           {
             timer2_DimmingControlling_tme(MAX_DUTYCYCLE);  //timer 2 started for brightness control 
             nrf_gpio_pin_write(DIMMER_TRIGGER,1);     //when duty cycle is greater than 0 set trigger pin HIGH 
           }
           else
           {
             timer2_DimmingControlling_tme(ui32Brightness);  //timer 2 started for brightness control
             nrf_gpio_pin_write(DIMMER_TRIGGER,1);     //when duty cycle is greater than 0 set trigger pin HIGH
           }
       }
       else
       {
          nrf_gpio_pin_write(DIMMER_TRIGGER,0);    //when duty cycle is 0 set trigger pin LOW
       }
       
       boolNextZCDProcess = true; //set this flag for next zcd detection 

        //pushutton status check, below statements are executed when button_1 pressed
        if(boolpushbuttonStatus)   //check push button ststus flag is set or not 
        {
           ui8Pushbuttonstatus = nrf_gpio_pin_read(EXTSW1_CONTROL);  // if the button flag is set then read the push button pin status 
           if(ui8Pushbuttonstatus == 1) //if the push button pin is high then enter to check button press count 
           {
              ui8PushbuttonStatusCount+=2;    // increment the button press count 
              if(ui8PushbuttonStatusCount > 100)  // if the button the press count is 100(1sec) then it is long press action 
              {
                  /*function to brightness control
                  * on long press, increment and decrement the light intensity with the level of 10% 
                  */
                  if(boolBrightnesslevelcontrol)   // if the brightness level flag flase then start incrementing till maximun brightness 100%
                  {
                      if(m_dev_ctx.level_control_attr.current_level < 230)  
                      {
                          m_dev_ctx.level_control_attr.current_level = m_dev_ctx.level_control_attr.current_level + 13;                                                 
                      }
                      else 
                      {
                          m_dev_ctx.level_control_attr.current_level = 230;
                      }
                      level_control_set_value(m_dev_ctx.level_control_attr.current_level);
                  }
                  else
                  {
                      if(m_dev_ctx.level_control_attr.current_level >= 13)  
                      {
                          m_dev_ctx.level_control_attr.current_level = m_dev_ctx.level_control_attr.current_level - 13;                                                 
                      }
                      else 
                      {
                          m_dev_ctx.level_control_attr.current_level = 3;
                      }
                      level_control_set_value(m_dev_ctx.level_control_attr.current_level); 
                  }
                  ui8PushbuttonStatusCount = 0;
                  boolpushbuttonContinue = true;   
              }
           }
           else if(ui8Pushbuttonstatus == 0)  // if the push button oinb status is not set the enter loop to toggle the light status 
           {
              boolpushbuttonStatus = false;
              if((ui8PushbuttonStatusCount >=15) && (ui8PushbuttonStatusCount <= 100) && (boolpushbuttonContinue == false))  // if the button press is single (between 400msec to 1sec) then toggle the light 
              {
                  boolBrightnesslevelcontrol = !boolBrightnesslevelcontrol;
                  //function to toggle the LED current state
                  if(CurrentDutyCycle == 0)
                  {         
                      level_control_set_value(m_dev_ctx.level_control_attr.current_level);
                      boolIgnorelongpress = false;
                  }
                  else
                  {
                     //Off the LED
                     on_off_set_value(0U);
                     CurrentDutyCycle = 0; 
                     boolIgnorelongpress = true;                     
                  }
              }
              boolpushbuttonContinue = false; //set long press button flag false
              ui8PushbuttonStatusCount = 0;   //button press count zero 
           }
    
        }
        
        /***************Below statements are executed when button_2 pressed*****************************************/
        if(boolPushButton2Status)
        {
            ui8PushButton2status = nrf_gpio_pin_read(KEY_UP);
            if(ui8PushButton2status == 0)
            {   
               ui16PushButton2Count +=2; 
               if(!boolIgnorelongpress)  //ignore long press from up/down key when OFF 
               {
                  if(ui16PushButton2Count > 100)  //Increment brightness when button_2 long press
                  {
                      if(boolPushButton2BrightnessControl)
                      {
                        if(m_dev_ctx.level_control_attr.current_level < 230)  
                        {
                            m_dev_ctx.level_control_attr.current_level = m_dev_ctx.level_control_attr.current_level + 13;                                                 
                        }
                        else 
                        {
                            m_dev_ctx.level_control_attr.current_level = 230;
                        }
                        level_control_set_value(m_dev_ctx.level_control_attr.current_level);
    
                      }
                    ui16PushButton2Count = 0;
                    boolPushButton2Continue = true;
                  } 
               }
            }
            else if(ui8PushButton2status == 1)
            {
                boolPushButton2Status = false;
                boolPushButton2BrightnessControl = false;
                if((ui16PushButton2Count >=15) && (ui16PushButton2Count <= 100) && (boolPushButton2Continue == false))
                {
                     level_control_set_value(m_dev_ctx.level_control_attr.current_level); //Turn On when button_2 short press
                     boolIgnorelongpress = false;
                }
                ui16PushButton2Count = 0;
                boolPushButton2Continue = false;
            }
        }
        /***************Above statements are executed when button_2 pressed*****************************************/

        /***************Below statements are executed when button_3 pressed*****************************************/
        if(boolPushButton3Status)
        {
            ui8PushButton3status = nrf_gpio_pin_read(KEY_DOWN);
            if(ui8PushButton3status == 0)
            {
                ui16PushButton3Count +=2;
                if(!boolIgnorelongpress)    //ignore long press from up/down key when OFF 
                {                    
                    if(ui16PushButton3Count > 100)  //Decrement brightness when button_3 long press
                    {
                        if(boolPushButton3BrightnessControl)
                        {
                          if(m_dev_ctx.level_control_attr.current_level >= 13)  
                          {
                              m_dev_ctx.level_control_attr.current_level = m_dev_ctx.level_control_attr.current_level - 13;                                                 
                          }
                          else 
                          {
                              m_dev_ctx.level_control_attr.current_level = 3;
                          }
                          level_control_set_value(m_dev_ctx.level_control_attr.current_level); 

                        }
                      ui16PushButton3Count = 0;
                      boolPushButton3Continue = true;
                    }
                }
            }
            else if(ui8PushButton3status == 1)
            {
                boolPushButton3Status = false;
                boolPushButton3BrightnessControl = false;
                if((ui16PushButton3Count >=15) && (ui16PushButton3Count <= 100) && (boolPushButton3Continue == false))
                {
                    //Turn Off when button_3 short press
                    CurrentDutyCycle = 0; 
                    on_off_set_value(0U);
                    boolIgnorelongpress = true;
                }
                ui16PushButton3Count = 0;
                boolPushButton3Continue = false;
            }
        }
        /***************Above statements are executed when button_3 pressed*****************************************/
       
}

/**
* @brief function for timer1 configurarion
* 
* configure timer 1 with the frequency parameter set 1MHz
* Intialise the timer event handler and enable 10msec timer for Negative cycle  
*   
*/
void timer1_Configuration (void)
{  
    uint32_t err_code = NRF_SUCCESS;
    //Configure TIMER_1 as 10msec timer
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.frequency = 4; //set frequency 1MHz  
    err_code = nrf_drv_timer_init(&TIMER_1, &timer_cfg, timer1_event_handler);
    if (err_code != NRF_SUCCESS)
    {
        // handle error condition
    }
}

//fixed timer 1
void timer1_fixedtimeOperation (uint32_t ui32fixedtime)
{
  uint32_t time1_ticks;

  time1_ticks = nrf_drv_timer_us_to_ticks(&TIMER_1, ui32fixedtime); 
  nrf_drv_timer_extended_compare(
        &TIMER_1, NRF_TIMER_CC_CHANNEL0, time1_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);    //timer 1 configured as continous timer  
  nrf_drv_timer_clear(&TIMER_1);
  nrf_drv_timer_enable(&TIMER_1);
}
/**********Negative Cycle timer Configuration End *************************************************/


/**********************Duty Cycle timer Configuration Start ********************************************/
/**
* @brief Handler for timer events.
* 
* timer2_event_handler function to turn OFF the bulb and disable the timer 
*   
*/
void timer2_event_handler(nrf_timer_event_t event_type, void* p_context) //Timer 2 interrupt handler
{
     nrf_drv_timer_disable(&TIMER_2);    //disable timer 2
     nrf_gpio_pin_write(DIMMER_TRIGGER,0);  //set trigger pin LOW 
     if(boolNextZCDProcess)     //if negative cycle complete enable the ZCD event again for next interrupt
     {
      // enable ZCD event 
       nrf_drv_gpiote_in_event_enable(ZERO_CROSS_DETECTION,true);
       boolNextZCDProcess = false;
     }
     
}

/**
* @brief function for timer2 configurarion
* 
* configure timer 2 with the frequency parameter set 1MHz
* Intialise the timer event handler and enable 10msec to control the dimming effect 
*   
*/
void timer2_Configuration (void)
{  
    uint32_t err_code = NRF_SUCCESS;
    //Configure TIMER_2 as 0 to 10msec duty cycle timer
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.frequency = 4; //set frequency 1MHz  
    err_code = nrf_drv_timer_init(&TIMER_2, &timer_cfg, timer2_event_handler);
    if (err_code != NRF_SUCCESS)
    {
        // handle error condition
    }
}
//timer2 dimming control time function 
void timer2_DimmingControlling_tme(uint32_t ui32Timer2Dutycycle)
{
    time2_ticks = nrf_drv_timer_us_to_ticks(&TIMER_2, ui32Timer2Dutycycle); //ui32Timer2Dutycycle is passed as duty cycle value 0 to 100%

     nrf_drv_timer_extended_compare(
         &TIMER_2, NRF_TIMER_CC_CHANNEL0, time2_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);       //timer 2 configured as continous timer

    nrf_drv_timer_clear(&TIMER_2); 
    nrf_drv_timer_enable(&TIMER_2);
}
/**********************Duty Cycle timer Configuration End *************************************************/

/*************GPIO Configuration*******************************/
/* ************************************************************
*function to configure ZCD, Tigger and Button pin 
*  Configure ZCD as Digital input pin (P0_6)
*  Configure Trigger as Digital output pin (P0_8)
*  Configure Button as Digital input pin (P1_9)
*
*  Function : GPIO_pin_configuration(void);
***************************************************************/
static void GPIO_pin_configuration (void)
{
   uint32_t err_code;

     //Set ZCD pin as input pin and Configure ZCD handler
    if(!nrf_drv_gpiote_is_init())
    {
      err_code = nrf_drv_gpiote_init();
    }

    /**********Trigger pin Configuration Start *************************************************/
    //Set Trigger pin as output pin
     nrf_gpio_cfg_output(DIMMER_TRIGGER);
     /**********Trigger pin Configuration End *************************************************/
     
    /**********ZCD pin Configuration Start *************************************************/
    //Set ZCD pin as input pin and Configure ZCD handler
    nrf_drv_gpiote_in_config_t zcd_in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);   //raising edge detection
    zcd_in_config.pull = NRF_GPIO_PIN_PULLUP;   //configure ZCD pin as pull_up
    err_code = nrf_drv_gpiote_in_init(ZERO_CROSS_DETECTION, &zcd_in_config, zcd_in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(ZERO_CROSS_DETECTION, true);
    /**********ZCD pin Configuration End *************************************************/

   /**********Button1 pin Configuration Start *************************************************/
   //Set Button1 pin as input pin and Configure Button handler 
    nrf_drv_gpiote_in_config_t button_in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    button_in_config.pull = NRF_GPIO_PIN_PULLDOWN; //configure button pin as pull_down

    err_code = nrf_drv_gpiote_in_init(EXTSW1_CONTROL, &button_in_config, button_in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(EXTSW1_CONTROL, true);
    /**********Button1 pin Configuration End *************************************************/

    /**********Button2 pin Configuration Start *************************************************/
   //Set Button2 pin as input pin and Configure Button handler 
    nrf_drv_gpiote_in_config_t button2_in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    button2_in_config.pull = NRF_GPIO_PIN_PULLUP; //configure button pin as pull_up

    err_code = nrf_drv_gpiote_in_init(KEY_UP, &button2_in_config, button2_in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(KEY_UP, true);
    /**********Button2 pin Configuration End *************************************************/

       /**********Button3 pin Configuration Start *************************************************/
   //Set Button3 pin as input pin and Configure Button handler 
    nrf_drv_gpiote_in_config_t button3_in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    button3_in_config.pull = NRF_GPIO_PIN_PULLUP; //configure button pin as pull_up

    err_code = nrf_drv_gpiote_in_init(KEY_DOWN, &button3_in_config, button3_in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(KEY_DOWN, true);
    /**********Button3 pin Configuration End *************************************************/
}

/**@brief Function for application main entry.
 */
int main(void)
{
    zb_ret_t       zb_err_code;
    zb_ieee_addr_t ieee_addr;

    /* Initialize timer, logging system and GPIOs. */
    log_init();
    leds_buttons_init();

    GPIO_pin_configuration();   //GPIO initialization and configuration
    timer2_Configuration();     //Timer 2 as duty cycle time configured 
    timer1_Configuration();     //Timer 1 as negative cycle timer 
    adc_configure();            //ADC intialization and configuration as channal 2, 8 bit resolution

    /* 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("led_bulb");

    /* Set device address to the value read from FICR registers. */
    zb_osif_get_ieee_eui64(ieee_addr);
    zb_set_long_address(ieee_addr);

    /* Set static long IEEE address. */
    zb_set_network_router_role(IEEE_CHANNEL_MASK);
    zb_set_max_children(MAX_CHILDREN);
    zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));

    /* Initialize application context structure. */
    UNUSED_RETURN_VALUE(ZB_MEMSET(&m_dev_ctx, 0, sizeof(m_dev_ctx)));

    /* Register callback for handling ZCL commands. */
    ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);

    /* Register dimmer switch device context (endpoints). */
    ZB_AF_REGISTER_DEVICE_CTX(&dimmable_light_ctx);

    bulb_clusters_attr_init();   
   // m_dev_ctx.level_control_attr.current_level = 77;
    level_control_set_value(m_dev_ctx.level_control_attr.current_level);

    InitialSequence(); 

    /** Start Zigbee Stack. */
    zb_err_code = zboss_start();
    ZB_ERROR_CHECK(zb_err_code);
      

    while(1)
    {

        zboss_main_loop_iteration();
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());

    }
}


/**
 * @}
 */
