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

Not able to execute while (1) loop after soft reset using GPIO interrupt

Hi,

I am developing project using nrf52840 and currently developing  using SDK 3.0. (Once I complete my feature I will update to SDK4.1).

I am using the light bulb firmware (using ZigBee) available in the SDK

I wish to soft reset the device and start again using GPIO interrupt.
For this I have configured 1 on board dev-kit button and configured interrupt handler for same.
To reset I used NVIC_SystemReset() function. When I press button my interrupt get executed and also NVIC_SystemReset() function.
I can see that my variables are getting default values but while(1) loop is not executing after soft reset.
And In while(1) loop I have written my state machine State_Ready to State_End where I do some data handling tasks as per my requirement.
But due to while(1) loop not executing after NVIC_SystemReset() unable to execute state_machine also.

Any help will be greatly appreciated.

Thanks and regards

Ankeet Gugale

  • Hi

    Due to the summer vacation period we are currently understaffed, so delayed replies must be expected. I am sorry about any inconvenience this might cause.

    Can you explain where in your application this while(1) loop is located and what is executing after this soft reset? If you could provide a snippet of your main() function as well as the function calling NVIC_SystemReset for example, that would be helpful. You can add code snippets in DevZone replies by going to the Insert dropdown menu and Code.

    Best regards,

    Simon

  • Hi Simonr,

    Thank you for your reply.

    Please find the attached main.c and uart_statemachine.c file. 
    And also snippet of code where I have used NVIC_SystemReset() function. 
           
           //Master reset is executed
                  if(ui8GetFlagBuffer[2] & FLAGS_BYTE_2_MASTER_RESET_REQUEST)
                  {
                     //Erase bonding information
                     zigbee_erase_persistent_storage(ZB_TRUE);
                     //soft reset
                     NVIC_SystemReset();
                     
                  }

    /******************************************************************************
     uart_statemachine.c - uart state machine source file for communication
     Version: 0.9.1
     Created on: 21/05/2021
     Created by: Rohit Rajapure
    
     Copyright (c) 2017 Shalaka Connected Devices LLP.  All rights reserved.
     Software License Agreement
    
       Redistribution and use in source and binary forms, with or without
       modification, are not permitted.
    
       Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    
       Redistributions in binary form 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.
    
       Neither the name of Shalaka Connected Devices LLP nor the names of
       its contributors may be used to endorse or promote products derived
       from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     ******************************************************************************/
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include "stdlib.h"
    #include "string.h"
    #include "zigbee_helpers.h"
    #include "app_uart.h"
    #include "nrf_drv_uart.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "nrf.h"
    
    #include "uart_config.h"
    #include "gpio_config.h"
    #include "timer_config.h"
    #include "uart_statemachine.h" 
    #include "commands.h"
    #include "app_rtc.h"
    #include "zb_custom1_thermostat.h"
    #include "custom_app_event.h"
    
    /*******************************************************************************************
    *MACROS
    *
    *******************************************************************************************/
    
    /******************************************************************************************
    *TYPEDEFS
    *
    *******************************************************************************************/
    State CurrentState, PreviousState;
    
    State CurrentState = State_Ready;
    
    E_StateMachine e_StateMachine;
    E_StateMachineThermostat e_StateMachineThermostat;
    
    E_StateMachine e_StateMachine = IDLE_STATE;
    E_StateMachineThermostat e_StateMachineThermostat = POWER_CYCLE;
    
    App_tsEventUart sAppUartEvent;
    App_tsEventBootloader sAppBootloaderEvent;
    App_tsEventProduction sAppProductionEvent;
    
    /******************************************************************************************
    *EXTERNAL VARIABLES
    *
    *******************************************************************************************/
    
    extern bool boolReady;
    extern bool boolSetTemperature;
    extern uint8_t ui8GetCommandBuffer[BUFFER_SIZE], ui8SetCommandBuffer[BUFFER_SIZE],ui8SendDeviceConfig[BUFFER_SIZE], ui8GetFlagBuffer[BUFFER_SIZE], ui8ResponceValueSend[BUFFER_SIZE], ui8ResponceValueSend2[BUFFER_SIZE], ui8StartFirmwareUpdate[BUFFER_SIZE], ui8TransferFirmware[BUFFER_SIZE], ui8TempGetFlagBuffer[BUFFER_SIZE];
    extern bool boolGetStatus;
    extern bool boolSetHostflags;
    extern uint32_t ui32HostflagsData;
    extern bool boolSendDeviceConfig;
    /******************************************************************************************
    *LOCAL VARIABLES
    *
    *******************************************************************************************/
    uint8_t ui8ReadGetFlagBuffer[BUFFER_SIZE] = {0};
    uint8_t ui8SetpointChange[SET_POINT_CHANGE_BUFFER] = {0}; //store set point change value into buffer
    uint8_t ui8BatteryStatus[4] = {0};
    uint8_t ui8ValvePositionChange[2] = {0};
    uint8_t ui8FirmwareVersion[26] = {0};
    uint8_t ui8DeviceConfigData[6] = {0};
    uint8_t ui8GetBootloaderStatus[2] = {0};
    uint8_t ui8Rx = 0, ui8RxIndex =0, ui8Index =0;
    uint16_t ui16LocalTemperature = 0, ui16SetPointChange = 0, ui16UnOccupiedTemp = 0, ui16OccupiedTemp = 0;
    uint8_t ui8TelegramRepeatCount = 0;
    uint32_t ui32ReadHostFlagsByte = 0;
    uint32_t ui32CurrentVersion[6] = {0};
    
    char u8CurrentRFVersionString[] = "";
    char u32CurrentVersionString[] = "";
    
    uint16_t  ui16BatteryVoltage = 0;
    float flBatteryPercentage = 0.0;
    
    
    uint16_t ui16SaveAttributeID;
    uint8_t ui8TrvModeBackup;
    bool StartFrimwareUpdateTimer = false;
    
    static uint32_t ui32HostImageStartAddress;
    static uint32_t ui32HostImageEndAddress;
    bool boolSetCommand = false;
    bool boolIsMCURequest = false; //this flag is general to send getflag command whenever requried. So, set this flag accordingly.
    bool boolMCUInterrupt = false;
    bool FirmwareUpdateTransferFinished  = false;
    /******************************************************************************************
    *BOOLEAN VARIABLES FOR GETFLAG COMMANDS
    *
    *******************************************************************************************/
    //Data 01
    bool boolManualMode = false; 
    bool boolHeatingMode = false;
    bool boolKeyProtection = false;
    bool boolInternalWindowOpen = false;
    bool boolExternalWindowOpen = false;
    bool boolRTCInValid = false;
    bool boolBatteryWeak = false;
    bool boolHolidayMode = false;
    //Data 02
    bool boolEncoderChange = false;
    bool boolSetPointChange = false;
    bool boolMasterResetRequest = false;
    bool boolMeasuredTempChange = false;
    bool boolMasterResetChange = false;
    bool boolBoostModeActive = false;
    bool boolProductModeRF = false;
    bool boolValvePositionChange = false;
    //Data 03
    bool boolButton1Push = false;
    bool boolButton2Push = false;
    bool boolButton3Push = false;
    bool boolButton4Push = false;
    bool boolButton5Push = false;
    bool boolButtonShortPush = false;
    bool boolButtonLongPush = false;
    bool boolButtonVeryLongpush = false;
    //Data 04
    bool boolADAPSuccess = false;
    bool boolErrorE1State = false;
    bool boolErrorE2State = false;
    bool boolErrorE3State = false;
    bool boolPrepMode = false;
    bool boolINST = false;
    bool boolADAP = false;
    bool boolADAPNotValid = false;
    //Data 05
    bool boolPairRequest = false;
    bool boolUnPairRequest = false;
    bool boolPairTimeOut = false;
    bool boolDevicePairState = false;
    
    /******************************************************************************************
    *FUNCTIONS
    *
    *******************************************************************************************/
    
    
    /******************************************************************************************
    *function for communication state handling between MCU and Network processor 
    *(this function used to execute the state machine between Radiator and nRF node)
    *return void
    *******************************************************************************************/
    
    void CommunicationStateExecution(void)
    {
       if(boolReady)
       {
           switch(CurrentState)
           {
            case State_Ready:         
                    Uart_Init_Func(); 
                    PreviousState = CurrentState;   //if interrupt on ULP switch state to command
                    CurrentState  = State_Command;
                    ui8TelegramRepeatCount =0;
            break;
    
            case State_Command:             
                  ulp_pin_transaction();  //ULP pin toggle configuration and high for 5msec
                  //send get flag telegram message to device 
                  if(!boolIsMCURequest)
                  {
                     GetMessageIdResponse(GET_FLAGS); 
                    
                  }
                 
                  Uart_PutData(ui8GetCommandBuffer,sizeof(ui8GetCommandBuffer));   
                  memset(ui8GetCommandBuffer,0,sizeof(ui8GetCommandBuffer)); 
    
                  PreviousState = CurrentState;   //after command sent switch state to read ACK
                  CurrentState  = State_ACKRead;
            break;
    
            case State_ACKRead: 
                  //after get flag read ACK and send EOC 
                  Uart_GetByte(&ui8Rx);
                  if((ui8Rx ==RESP_ACK) && (boolSetCommand == true))
                  {                                       
                      ui8TelegramRepeatCount =0;
                      boolSetCommand = false;
                      PreviousState = CurrentState;   //if EOC and Set command then switch to state Set_Command
                      CurrentState  = State_SetCommand;
                  }
                  else if((ui8Rx ==RESP_ACK) && (boolSetTemperature == true))
                  {                            
                      ui8TelegramRepeatCount =0;                  
                      PreviousState = CurrentState;   //if EOC and Set command then switch to state Set_Command
                      CurrentState  = State_SetCommand;
                  }
                  else if((ui8Rx ==RESP_ACK) && (boolSetHostflags == true))
                  {              
                    ui8TelegramRepeatCount =0;                       
                    PreviousState = CurrentState;   //if EOC and Set command then switch to state Set_Command
                    CurrentState  = State_SetCommand;
                  }
                  else if((ui8Rx ==RESP_ACK) && (boolSendDeviceConfig == true))
                  {                
                    ui8TelegramRepeatCount =0;                       
                    PreviousState = CurrentState;   //if EOC and Set command then switch to state Set_Command
                    CurrentState  = State_SetCommand;
                  }
                  else if(ui8Rx ==RESP_ACK)
                  {                                
                    ui8TelegramRepeatCount =0;                       
                    PreviousState = CurrentState;   //after EOC read switch state to send EOC 
                    CurrentState  = State_SendEOC;
                  }
                  //if statement to check NACK response and perform the repeatation action 
                  if(ui8Rx == RESP_NACK)
                  {
                     ui8TelegramRepeatCount++;
    
                     if(ui8TelegramRepeatCount == 3)
                     {
                         PreviousState = CurrentState;   //After command repeatation is done for 3 times switch state to Ready state
                         CurrentState  = State_Ready;
                         ui8TelegramRepeatCount =0;
                         boolReady = false;
                     }
                     else
                     {
                         //if NACK then repeat the command for 3 time.
                         CurrentState  = PreviousState;
                     }
                  }
    
                  if(ui8Rx == RESP_TNS)
                  {
                       PreviousState = CurrentState;   //After command repeatation if it not supportive command (TNS) then go to ready state
                       CurrentState  = State_Ready;
                       boolReady = false;
                  }
            break;
    
            case State_SendEOC:
                  Uart_PutByte(EOC);
                  
                  PreviousState = CurrentState;   //after EOC read switch state to read dummy ACK
                  CurrentState  = State_ACKReadDummy;
            break;
    
            case State_ACKReadDummy: 
                  //after get flag read ACK and send EOC 
                  Uart_GetByte(&ui8Rx);
                  if(ui8Rx ==RESP_ACK)
                  {                       
                    ui8TelegramRepeatCount =0;
                    PreviousState = CurrentState;   //after dummy ACK read switch state to read response data 
                    CurrentState  = State_ReadDataResponse;             
                  }
            break;
    
            case State_SetCommand:
                 if((!boolSetTemperature) && (!boolSetHostflags) && (!boolSendDeviceConfig))
                 {
                   SetFlags();  //send set flag command
                   
                   Uart_PutData(ui8SetCommandBuffer,sizeof(ui8SetCommandBuffer));
                   memset(ui8SetCommandBuffer,0,sizeof(ui8SetCommandBuffer)); 
                 }
                 else if((boolSetTemperature) && (!boolSetHostflags) && (!boolSendDeviceConfig))
                 {
                   SendSetTemperature();
                  
                   boolSetTemperature = false;   
                   Uart_PutData(ui8SetCommandBuffer,sizeof(ui8SetCommandBuffer));
                   memset(ui8SetCommandBuffer,0,sizeof(ui8SetCommandBuffer)); 
                 }
                 else if(boolSetHostflags)
                 {
                   UARTStateSendFlags();  
                   boolSetHostflags = false;
                   
                   Uart_PutData(ui8SetCommandBuffer,sizeof(ui8SetCommandBuffer));
                   memset(ui8SetCommandBuffer,0,sizeof(ui8SetCommandBuffer)); 
                 }
                 else if(boolSendDeviceConfig)
                 {
                     UARTStateSendDeviceConfig();          //send set device config command
                     boolSendDeviceConfig = false;
                    
                     Uart_PutData(ui8SendDeviceConfig,sizeof(ui8SendDeviceConfig));
                     memset(ui8SendDeviceConfig,0,sizeof(ui8SendDeviceConfig)); 
                 }            
                  PreviousState = CurrentState;   //after command sent switch state to read ACK
                  CurrentState  = State_ACKRead;
             break;
    
            case State_ReadDataResponse: 
                  //read command response from MCU             
                  Uart_GetByte(&ui8Rx);
                  if(ui8Rx == SYNC)
                  {                
                     //read length of data
                     Uart_GetByte(&ui8Rx);
                     ui8RxIndex = ui8Rx;
    
                     GetFlagsResponse();   //store getflag data into buffer
    
                    // after data read send ACK to device 
                     Uart_PutByte(RESP_ACK);
    
                     PreviousState = CurrentState;   //after data read send ACK to device  switch state EOC  
                     CurrentState  = State_EOCRead;
    
                  }
            break;
    
            case State_EOCRead: 
                 //After data read from MCU check for EOC
                  Uart_GetByte(&ui8Rx);
                  if(ui8Rx ==EOC)
                  {                      
                    //send ACK back
                      Uart_PutByte(RESP_ACK);
                      PreviousState = CurrentState;   //all state executed then switch to ready state
                      CurrentState  = State_EndCommunication; 
    //                  boolReady = false; 
    //                  boolMCUInterrupt = true;   
                  }              
                  
            break;
    
            case State_EndCommunication:                
                    boolReady = false; 
                    boolMCUInterrupt = true;   
                    PreviousState = CurrentState;   //all state executed then switch to ready state
                    CurrentState  = State_Ready;
                    ResetFlags();                                
            break;
    
            default:
            break;
    
             
           }
       }
    
    }
    
    /******************************************************************************************
    *function for read the getflag bits and store into variable
    *return void
    *******************************************************************************************/
    void GetFlagsResponse (void)
    {
         for(ui8Index = 0; ui8Index< ui8RxIndex-2; ui8Index++)  //loop to store read get flag data into variable
         {
            //store data into buffer
            Uart_GetByte(&ui8Rx);
            ui8ReadGetFlagBuffer[ui8Index] = ui8Rx;
         }
         
    }
    
    
    /******************************************************************************************
    *This function is used to process the commands based on Id comparision.
    *return void
    *******************************************************************************************/
    void DataProcessing(void)
    {
       if(boolMCUInterrupt)
       {
           switch(ui8ReadGetFlagBuffer[0])
           {
              case GET_FLAGS:
                   memcpy(ui8GetFlagBuffer,ui8ReadGetFlagBuffer,sizeof(ui8ReadGetFlagBuffer));  
                   nrf_delay_ms(25);                         
    
                    //Data 01 of flag byte
                   if(ui8GetFlagBuffer[1] & FLAGS_BYTE_1_MANU_MODE)
                   {
    //                  SetTRVMode(ZB_ZCL_THERMOSTAT_TRV_MODE_DEFAULT_VALUE);
                      m_dev_ctx.thermostat_attr.trv_mode = ZB_ZCL_THERMOSTAT_TRV_MODE_DEFAULT_VALUE;
                      m_dev_ctx.thermostat_attr.host_flags |= FLAGS_BYTE_1_MANU_MODE;
    //                  HostFlagStatus(ui32ReadHostFlagsByte);
                   }
    
                   if(ui8GetFlagBuffer[1] & FLAGS_BYTE_1_KEY_PROTECTION_ACTIVE)
                   {
                     m_dev_ctx.thermostat_attr.host_flags |= 0x000080;
    //                 HostFlagStatus(ui32ReadHostFlagsByte);
                   }
                   if((ui8GetFlagBuffer[1] ^ FLAGS_BYTE_1_KEY_PROTECTION_ACTIVE)& FLAGS_BYTE_1_KEY_PROTECTION_ACTIVE)
                   {
                     m_dev_ctx.thermostat_attr.host_flags &=m_dev_ctx.thermostat_attr.host_flags ^ 0x000080;
    //                 HostFlagStatus(ui32ReadHostFlagsByte);
                   }
    
                   if(ui8GetFlagBuffer[1] & FLAGS_BYTE_1_INT_WINDOW_TRIGGERD)
                   {
                      m_dev_ctx.thermostat_attr.host_flags |= START_INTERNAL_WINDOW_OPEN;
    //                  HostFlagStatus(ui32ReadHostFlagsByte);
                   }
                  if ((ui8GetFlagBuffer[1] ^ FLAGS_BYTE_1_INT_WINDOW_TRIGGERD)& FLAGS_BYTE_1_INT_WINDOW_TRIGGERD) 
                  {
                      m_dev_ctx.thermostat_attr.host_flags &= m_dev_ctx.thermostat_attr.host_flags ^ STOP_INTERNAL_WINDOW_OPEN;
    //                  HostFlagStatus(ui32ReadHostFlagsByte);
                  }
                  
                  if (ui8GetFlagBuffer[1] & FLAGS_BYTE_1_EXT_WINDOW_ACTIVATE) 
                  {      
                  // If the external window open detection is active, the same bit is set in the RF telegram as for the internal one.
                     m_dev_ctx.thermostat_attr.host_flags |= START_INTERNAL_WINDOW_OPEN;
    //                 HostFlagStatus(ui32ReadHostFlagsByte);
                  }
    
                  if (ui8GetFlagBuffer[1] & FLAGS_BYTE_1_BATTERY_WEAK) 
                  {  
    //                  ReadErrorStatus(BATTERY_WEAK_ERROR);
                      m_dev_ctx.thermostat_attr.error |= 0x01;
                      boolReady = true; //set flag to execute communication state
                      boolIsMCURequest = true;
                      e_StateMachineThermostat = RUNNING_STATE;
                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_BATTERY;
                  }
    
                  if((ui8GetFlagBuffer[1] ^ FLAGS_BYTE_1_BATTERY_WEAK) & FLAGS_BYTE_1_BATTERY_WEAK )
                  {                
    //                  ui32ReadHostFlagsByte &= ui32ReadHostFlagsByte ^ 0x01;
    //                  ReadErrorStatus(0);
                      m_dev_ctx.thermostat_attr.error &=  m_dev_ctx.thermostat_attr.error ^ 0x01;
                  }
    
                   //Data 02 of flag byte
                   //Query whether setpoint temperature has been changed
                  if (ui8GetFlagBuffer[2] & FLAGS_BYTE_2_SETPOINT_CHANGED) 
                  {
                      boolReady = true; //set flag to execute communication state
                      boolIsMCURequest = true;        
                      e_StateMachineThermostat = RUNNING_STATE;
                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_TEMPERATURE;
                  }
                  
                  //Master reset is executed
                  if(ui8GetFlagBuffer[2] & FLAGS_BYTE_2_MASTER_RESET_REQUEST)
                  {
                     //Erase bonding information 
                     zigbee_erase_persistent_storage(ZB_TRUE);
                     //soft reset 
                     NVIC_SystemReset(); 
                     
                  }
                  //Has the ACTUAL temperature changed, a request is sent to the controller.
                  if(ui8GetFlagBuffer[2] & FLAGS_BYTE_2_MEASURED_TEMP_CHANGED)
                  {
                      boolReady = true; //set flag to execute communication state
                      boolIsMCURequest = true;        
                      e_StateMachineThermostat = RUNNING_STATE;
                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_TEMPERATURE;
                  }
    
                  if(ui8GetFlagBuffer[2] & FLAGS_BYTE_2_BOOST_MODE)
                  {
                    m_dev_ctx.thermostat_attr.host_flags |= 0x04;
    //                HostFlagStatus(ui32ReadHostFlagsByte);
                  }
    
                  if((ui8GetFlagBuffer[2] ^ FLAGS_BYTE_2_BOOST_MODE) & FLAGS_BYTE_2_BOOST_MODE) 
                  {
                    m_dev_ctx.thermostat_attr.host_flags &= m_dev_ctx.thermostat_attr.host_flags ^ 0x04; 
    //                HostFlagStatus(ui32ReadHostFlagsByte);       
                  }
    
                  if (ui8GetFlagBuffer[2] & FLAGS_BYTE_2_VALVE_POSITION_CHANGED)
                  {
                     boolReady = true; //set flag to execute communication state
                     boolIsMCURequest = true;
                     e_StateMachineThermostat = RUNNING_STATE;
                     sAppUartEvent.eType_UartNextState  = APP_E_EVENT_UART_GET_VALVE_POSITION;
                  }
    
                  //Data 04 flag byte
                  if(ui8GetFlagBuffer[4] == FLAGS_BYTE_4_ADAP_SUCCESSFUL)
                  {
                    ReadErrorStatus(NO_ERROR);
                  }
                  if((ui8GetFlagBuffer[4] & (0x07)) == FLAGS_BYTE_4_ERROR_E1)
                  {
                    ReadErrorStatus(VALVE_ADAPTATION_FAIL_E1);//Error ER1 Adaptation failed because not mounted
                  }
                  if((ui8GetFlagBuffer[4] & (0x07)) == FLAGS_BYTE_4_ERROR_E2)
                  {
                    ReadErrorStatus(VALVE_MOVEMENT_SLOW_E2); //Error ER2 adaptation failed because closing point not found
                  }
                  if((ui8GetFlagBuffer[4] & (0x07)) == FLAGS_BYTE_4_ERROR_E3)
                  {
                    ReadErrorStatus(VALVE_NOT_MOVING_E3); //Error ER3 adaptation failed because valve stroke too short or adaptation not possible
                  }
    
              break;
    
              case GET_BOOTLOADER_STATE:
                   memcpy(ui8GetBootloaderStatus,ui8ReadGetFlagBuffer,sizeof(ui8GetBootloaderStatus));
    
                   if(ui8GetBootloaderStatus[1] == 0x01)
                   {
                      e_StateMachineThermostat = BOOTLOADER_STATE;
                      sAppBootloaderEvent.eType_BootloaderState = APP_E_EVENT_UART_START_FIRMWARE_UPDATE;
    //                  sAppBootloaderEvent.eType_BootloaderState = APP_E_EVENT_UART_TRANSFER_FRIMWARE_UPDATE;
                   }
                   else if(ui8GetBootloaderStatus[1] == 0x00)
                   {
                      e_StateMachineThermostat = RUNNING_STATE;
                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_FIRMWARE_VERSION; // this state should execute only once when device starts 
                   }
                    boolIsMCURequest = false;
              break;
    
              case GET_TEMPERATURES:
                   memcpy(ui8SetpointChange,ui8ReadGetFlagBuffer,sizeof(ui8SetpointChange));
                  
                  ui16LocalTemperature = ui8SetpointChange[1] << 8;
                  ui16LocalTemperature = ui16LocalTemperature + ui8SetpointChange[2];
                  localTemperatureValue(ui16LocalTemperature);
    
                  ui16SetPointChange   = ui8SetpointChange[5] << 8;
                  ui16SetPointChange   = ui16SetPointChange + ui8SetpointChange[6];              
                  CurrentSetpointChangeValue(ui16SetPointChange);        
                  
                  ReadOccupiedHeatingSetpoint(ui16SetPointChange);  // When get temperature in requested copy the set point value on Occupied heating point id. 
    
                  boolIsMCURequest = false;
                  nrf_delay_ms(25);
                  e_StateMachineThermostat = RUNNING_STATE;
                  sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_BATTERY;
    
              break;
    
              case GET_BATTERY_STATUS:
                   memcpy(ui8BatteryStatus, ui8ReadGetFlagBuffer,sizeof(ui8BatteryStatus));
                   //flBatteryPercentage = ((ui8BatteryStatus[1] * 100)/255);
                   vCalculateBattery(ui8BatteryStatus[1]);
    
    //               ui16BatteryVoltage = ui8BatteryStatus[2] << 8;    /**voltage calculation**/
    //               ui16BatteryVoltage = ui16BatteryVoltage + ui8BatteryStatus[3];
                  
                   boolIsMCURequest = false;
                   nrf_delay_ms(25);
                    if(boolGetStatus)
                    {
                        boolGetStatus = false;
                        e_StateMachineThermostat = RUNNING_STATE;
                        sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_DEVICE_CONFIG; 
                    }
                    else
                    {
                        sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
                    }
              break;
    
              case GET_FIRMWARE_VER:
                   memcpy(ui8FirmwareVersion,ui8ReadGetFlagBuffer,sizeof(ui8FirmwareVersion));
                   ui32CurrentVersion[0] = (ui8FirmwareVersion[19] - 0x30)	* 100000; 
                   ui32CurrentVersion[1] = (ui8FirmwareVersion[20] - 0x30)	* 10000; 
                   ui32CurrentVersion[2] = (ui8FirmwareVersion[21] - 0x30)	* 1000; 
                   ui32CurrentVersion[3] = (ui8FirmwareVersion[22] - 0x30)	* 100; 
                   ui32CurrentVersion[4] = (ui8FirmwareVersion[23] - 0x30)	* 10; 
                   ui32CurrentVersion[5] = (ui8FirmwareVersion[24] - 0x30); 
                    
    //               itoa(m_dev_ctx.basic_attr.app_version,u8CurrentRFVersionString,8);
    //               itoa((int*)ui32CurrentVersion,u32CurrentVersionString,8);
    
    //               strcat(u8CurrentRFVersionString, u32CurrentVersionString);
    //
    //               memcpy(m_dev_ctx.basic_attr.sw_ver,u8CurrentRFVersionString, 8);
    
                   boolIsMCURequest = false; 
                   nrf_delay_ms(25);
                   e_StateMachineThermostat = RUNNING_STATE;
                   sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_GET_DEVICE_CONFIG;
              break;
    
              case GET_DEVICE_CONFIG:
                   memcpy(ui8DeviceConfigData,ui8ReadGetFlagBuffer,sizeof(ui8DeviceConfigData));
                   
                   if(ui8DeviceConfigData[3] == DEVICE_CONFIG_BYTE_3_VALVE_CONTROLLER)
                   {
                      m_dev_ctx.thermostat_attr.trv_mode = 0x01;     //TRV position mode 
                   }
                   boolIsMCURequest = false;
                  
                   sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
              break;
                   
    
              case GET_POSITION:
                   memcpy(ui8ValvePositionChange,ui8ReadGetFlagBuffer, sizeof(ui8ValvePositionChange));
                   SetValvePosition(ui8ValvePositionChange[1]);   //if valve position change then set valve and copy the data on pi heating demand attribute.
                   boolIsMCURequest = false;
                    sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE; 
              break;
              
    
              default:
              break;
           }
           memset(ui8ReadGetFlagBuffer,0,sizeof(ui8ReadGetFlagBuffer)); 
           boolMCUInterrupt = false; 
                      
       }
    }
    
    
    
    //function to reset all flags 
    void ResetFlags(void)
    {
      boolReady = false;
      boolSetCommand = false;
      boolSetTemperature = false;
      boolSetHostflags = false;
      boolSetPointChange = false;
    }
    /****************************************************************************
     *
     * NAME: vUART_STATE_StateMachine
     *
     * DESCRIPTION:
     * Check different states of Thermostat and RF
     *
     * RETURNS:
     * void
     *
    ****************************************************************************/
    void UARTStateStateMachine(void)
    {
       if (e_StateMachineThermostat == BOOTLOADER_STATE)
       {
            switch (sAppBootloaderEvent.eType_BootloaderState) 
            {			
                case APP_E_EVENT_UART_START_FIRMWARE_UPDATE:                                 
                        //bRestartBootloaderMode = FALSE;  did not get declaration
                      UARTStateStartFirmwareUpdate();  
                break;
                case APP_E_EVENT_UART_TRANSFER_FRIMWARE_UPDATE:		
                        //UARTStateTransferFirmwareUpdate(); This function is not created here
                break;
                case APP_E_EVENT_BOOTLOADER_STATE_IDLE:
                break;
                default:			
                break;
            }
    
       }
       else if (e_StateMachineThermostat == PRODCUTION_MODE)
       {
    
            switch (sAppProductionEvent.eType_ProductionState) 
            {
                case APP_E_EVENT_PRODUCTION_STATE:
                     GetMessageIdResponse(GET_PRODUCTION_MODE);  // send get production mode command 
                break;
                default:
                break;
                    
            }
       }
       else if (e_StateMachineThermostat == RUNNING_STATE)
       {
                switch (sAppUartEvent.eType_UartNextState)
                {
                  case APP_E_EVENT_UART_SEND_TEMPERATURE:
                         //UARTStateSendTemperature(u16SaveAttributeID);  TBD for replacement send set temperature command
                  break;
    
                  case APP_E_EVENT_UART_GET_TEMPERATURE:                    
                        GetMessageIdResponse(GET_TEMPERATURES); //send get temeperature command
                        boolReady = true; //set flag to execute communication state
                        boolIsMCURequest = true;
                  break;
    
                  case APP_E_EVENT_UART_GET_BATTERY:                     
                         GetMessageIdResponse(GET_BATTERY_STATUS); //send get battey status command
                         boolReady = true; //set flag to execute communication state
                         boolIsMCURequest = true;
    //                     sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
                  break;
    
                  case APP_E_EVENT_UART_GET_COMPOSITE_DATA:                     
                          GetMessageIdResponse(GET_COMPOSITE_DATA1); //send get comosite data command
                  break;
    
                  case APP_E_EVENT_UART_ULP_WAS_TRIGGERED:                      
                          GetMessageIdResponse(GET_FLAGS);   //send get flag command
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS:                    
                       sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_AUTO_MODE:
                          UARTStateSendFlagsAuto();     //send set flag with auto mode flag command
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_MANU_MODE:
                          UARTStateSendFlagsManu();     //send set flag with manual mode flag command
                  break;
    
                  case APP_E_EVENT_UART_SEND_VALVE_POSITION:                      
                          UARTStateSendValvePosition();   //send set valve position command
                  break;
    
                  case APP_E_EVENT_UART_GET_VALVE_POSITION:                    
                          GetMessageIdResponse(GET_POSITION);   //send get valve position command
                         
                  break;
    
                  case APP_E_EVENT_UART_SEND_DEVICE_CONFIG:                      
    //                      UARTStateSendDeviceConfig();          //send set device config command
    //                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE; 
                  break;
    
                  case APP_E_EVENT_UART_SEND_DEVICE_CONFIG_2:                    
                          UARTStateSendDeviceConfig2();           //send set device config2 command   
                  break;
    
                  case APP_E_EVENT_UART_GET_DEVICE_CONFIG:                    
                          GetMessageIdResponse(GET_DEVICE_CONFIG);   //send get device config command
                          boolReady = true; //set flag to execute communication state
                          boolIsMCURequest = true;
    //                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_JOINED:                                           
                          UARTStateSendFlagsJoined();            //send set flag command with joined parameter
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_LEAVE:                     
                          UARTStateSendFlagsLeave();             //send set flag command with leave ntw parameter
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_RF_COMMUNICATION_OK:                     
                          UARTStateSendFlagsRFCommunicationOK();   //send set flag with RF communication okay command
                  break;
    
                  case APP_E_EVENT_UART_SEND_FLAGS_RF_COMMUNICATION_LOST:                      
                          UARTStateSendFlagsRFCommunicationLost();    //send set flag with RF communication lost command
                  break;
    
                  case APP_E_EVENT_UART_SEND_RTC:
                          UARTStateSendRTC();                    //send set RTC command 
                  break;
    
                  case APP_E_EVENT_UART_GET_RTC:
                          GetMessageIdResponse(GET_RTC);          //send get RTC command
                  break;
    
                  case APP_E_EVENT_UART_GET_FIRMWARE_VERSION:                     
                          GetMessageIdResponse(GET_FIRMWARE_VER);   //send get firmware version command
                          boolReady = true; //set flag to execute communication state
                          boolIsMCURequest = true;
    //                      sAppUartEvent.eType_UartNextState = APP_E_EVENT_UART_IDLE;
                  break;
    
                  case APP_E_EVENT_UART_IDLE:
                       app_uart_close(); //close UART module
                         
                  break;
                  case APP_E_EVENT_UART_SEND_SYSTEM_MODE:
                         // vUART_STATE_SendDeviceConfig();    This is not created here
                  break;
    
                  case APP_E_EVENT_UART_GET_RTC_FROM_COORDINATOR:                     
                        //  vRTC_vRequestTimeFromCoordiantor();
                  break;
    
                  case APP_E_EVENT_UART_SEND_MASTER_RESET_REQUEST:
                          UARTStateMasterResetRequest();                 //send master reset with request flag command
                  break;
    
                  case APP_E_EVENT_UART_SEND_MASTER_RESET_SUCCESS:                     
                          UARTStateMasterResetSuccess();                //send master reset with rest flag command
                  break;
    
                  case APP_E_EVENT_UART_SEND_GET_PRODUCTION_MODE:
                          GetMessageIdResponse(GET_PRODUCTION_MODE);    //send get production mode command 
                  break;
    
                  case APP_E_EVENT_UART_SEND_SET_PRODUCTION_MODE_PASS:
                          UARTStateSendSetProductionModePass();    //send set production mode pass command
                  break; 
    
                  case APP_E_EVENT_UART_SEND_START_PRODUCTION_MODE:
                          UARTStateSendStartProductionMode();     //send set production mode start command
                  break;
    
                  case APP_E_EVENT_UART_LEAVE_NETWORK:                     
                       //   vUART_STATE_vLeaveNetwork();   This function not created here
                  break;
    
                  case APP_E_EVENT_UART_IDENTIFY_MODE:                     
                  break;
    
                  case APP_E_EVENT_UART_SEND_SWITCHPOINTS:
                        //UARTStateSendSwitchPoints();   //send switch point function. This function not created here
                  break;
    
    
                  default:
                  break;
                }
       }
    
    }
    
    
    /**
     * 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.
     *
     */
    
    #include "sdk_config.h"
    #include "zboss_api.h"
    #include "zboss_api_addons.h"
    #include "zb_mem_config_med.h"
    #include "zb_error_handler.h"
    #include "zb_nrf52_internal.h"
    #include "zigbee_helpers.h"
    
    #include "bsp.h"
    #include "boards.h"
    #include "app_timer.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "app_uart.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "nrf.h"
    
    /**User Include file*********/
    #include "uart_config.h"
    #include "gpio_config.h"
    #include "timer_config.h"
    #include "commands.h" 
    #include "uart_statemachine.h" 
    #include "app_flash_memory.h"
    #include "zb_custom1_thermostat.h"
    #include "custom_app_event.h"
    
    #define IEEE_CHANNEL_MASK                 (ZB_TRANSCEIVER_ALL_CHANNELS_MASK)    //(1l << ZIGBEE_CHANNEL)                /**< Scan only one, predefined channel to find the coordinator. */
    
    #define ERASE_PERSISTENT_CONFIG           ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */
    
    #define ZIGBEE_NETWORK_STATE_LED          BSP_BOARD_LED_2                       /**< LED indicating that light switch successfully joind Zigbee network. */
    
    
    
    #if !defined ZB_ED_ROLE
    #error Define ZB_ED_ROLE to compile End Device source code.
    #endif
    
    
    /******************************************************************
    * GLOBAL VARIABLES
    *
    *******************************************************************/
    uint16_t ui16CurrentTemp =0, ui16OccupiedHeatSetpoint = 0, ui16UnOccupiedHeatSetpoint = 0;
    uint8_t  ui8LocalTemperatureCalibration = 0;
    uint32_t ui32HostflagsData = 0;
    
    bool boolSetTemperature = false;
    bool boolGetStatus = false;
    bool boolSetHostflags = false;
    bool boolSendDeviceConfig = false;
    /******************************************************************************************
    *EXTERNAL VARIABLES
    *
    *******************************************************************************************/
    extern bool boolReady;
    extern bool boolMCUInterrupt;
    extern bool boolSetCommand;
    extern uint8_t ui8SendDeviceConfig[BUFFER_SIZE];
    
    extern App_tsEventUart sAppUartEvent;
    extern E_StateMachineThermostat e_StateMachineThermostat;
    /******************************************************************************************
    *FUNCTIONS 
    *
    *******************************************************************************************/
    
    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);
    
    /* Declare attribute list for Identify cluster. */
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list,
                                        &m_dev_ctx.identify_attr.identify_time);
    
    /**power attributes**/
    ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_EXT(power_config_attr_list,
                                            &m_dev_ctx.power_attr.battery_voltage,
                                            &m_dev_ctx.power_attr.battery_size,
                                            &m_dev_ctx.power_attr.battery_quantity,
                                            &m_dev_ctx.power_attr.battery_rated_voltage,
                                            &m_dev_ctx.power_attr.battery_alarm_mask,
                                            &m_dev_ctx.power_attr.battery_voltage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_remaining,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold1,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold2,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold3,
                                            &m_dev_ctx.power_attr.battery_percentage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold1,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold2,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold3,
                                            &m_dev_ctx.power_attr.battery_alarm_state);
    
    ZB_ZCL_DECLARE_TIME_ATTRIB_LIST(time_attr_list,
                                    &m_dev_ctx.time_attr.timeId,
                                    &m_dev_ctx.time_attr.time_status,
                                    &m_dev_ctx.time_attr.time_zone,
                                    &m_dev_ctx.time_attr.dst_start,
                                    &m_dev_ctx.time_attr.dst_end,
                                    &m_dev_ctx.time_attr.dst_shift,
                                    &m_dev_ctx.time_attr.standard_time,
                                    &m_dev_ctx.time_attr.local_time,
                                    &m_dev_ctx.time_attr.last_settime,
                                    &m_dev_ctx.time_attr.valid_untilTime);
    
    ZB_ZCL_DECLARE_CUSTOM_THERMOSTAT_ATTRIB_LIST_EXT(thermostat_attr_list,
                                              &m_dev_ctx.thermostat_attr.local_temperature,                                          
                                              &m_dev_ctx.thermostat_attr.pi_heating_demand,                                         
                                              &m_dev_ctx.thermostat_attr.local_temperature_calibration,                                          
                                              &m_dev_ctx.thermostat_attr.occupied_heating_setpoint,                                         
                                              &m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                                              &m_dev_ctx.thermostat_attr.min_heating_setpoint_limit,
                                              &m_dev_ctx.thermostat_attr.max_heating_setpoint_limit,                                                                                 
                                              &m_dev_ctx.thermostat_attr.remote_sensing,
                                              &m_dev_ctx.thermostat_attr.control_seq_of_operation,
                                              &m_dev_ctx.thermostat_attr.system_mode,         
                                              &m_dev_ctx.thermostat_attr.trv_mode,
                                              &m_dev_ctx.thermostat_attr.set_valve_position,
                                              &m_dev_ctx.thermostat_attr.error,
                                              &m_dev_ctx.thermostat_attr.current_setpoint,
                                              &m_dev_ctx.thermostat_attr.host_flags);
    
    /* Declare cluster list for custom Thermostat device  */
    ZB_DECLARE_CUSTOM_THERMOSTAT_CLUSTER_LIST(thermostat_clusters,
                                          basic_attr_list,
                                          identify_attr_list,
                                          power_config_attr_list,
                                          thermostat_attr_list,
                                          time_attr_list);
    
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_EP(thermostat_ep,
                                   THERMOSTAT_SENSOR_ENDPOINT,
                                   thermostat_clusters);
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_CTX(thermostat_ctx, thermostat_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();
    }
    
    /**@brief Function for initializing all clusters attributes.
     */
    static void thermostat_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 = THERMOSTAT_INIT_BASIC_APP_VERSION;
         m_dev_ctx.basic_attr.stack_version = THERMOSTAT_INIT_BASIC_STACK_VERSION;
         m_dev_ctx.basic_attr.hw_version = THERMOSTAT_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,
                              THERMOSTAT_INIT_BASIC_MANUF_NAME,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MANUF_NAME));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                              THERMOSTAT_INIT_BASIC_MODEL_ID,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MODEL_ID));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                              THERMOSTAT_INIT_BASIC_DATE_CODE,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_DATE_CODE));
    
          m_dev_ctx.basic_attr.power_source = THERMOSTAT_INIT_BASIC_POWER_SOURCE;
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                              THERMOSTAT_INIT_BASIC_LOCATION_DESC,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_LOCATION_DESC));
    
    
          m_dev_ctx.basic_attr.ph_env = THERMOSTAT_INIT_BASIC_PH_ENV;
          //m_dev_ctx.basic_attr.sw_ver = "00000000";
          memcpy( m_dev_ctx.basic_attr.sw_ver,"00000000", 8);
        
        /* Identify cluster attributes data */
        m_dev_ctx.identify_attr.identify_time        = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
         
         /**power configuration attributes data**/
        m_dev_ctx.power_attr.battery_percentage_remaining = 0x02;
        m_dev_ctx.power_attr.battery_quantity = ZB_POWER_CONFIG_BATTERY_QUANTITY;
        m_dev_ctx.power_attr.battery_size = ZB_ZCL_POWER_CONFIG_BATTERY_SIZE_AA;
       
          /* Thermostat cluster attributes with extended data */
        m_dev_ctx.thermostat_attr.local_temperature             = 0x07D0;
        m_dev_ctx.thermostat_attr.local_temperature_calibration = 0x00;
        m_dev_ctx.thermostat_attr.pi_heating_demand             = 0xFF;
        m_dev_ctx.thermostat_attr.occupied_heating_setpoint     = 0x07D0;
        m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint   = 0x0640;
        m_dev_ctx.thermostat_attr.min_heating_setpoint_limit    = 0x01F4;
        m_dev_ctx.thermostat_attr.max_heating_setpoint_limit    = 0x0BB8;
        m_dev_ctx.thermostat_attr.control_seq_of_operation      = ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_HEATING_ONLY;
        m_dev_ctx.thermostat_attr.system_mode                   = ZB_ZCL_THERMOSTAT_SYSTEM_MODE_HEAT;
        m_dev_ctx.thermostat_attr.current_setpoint             = 0x0898;
        m_dev_ctx.thermostat_attr.trv_mode                     = ZB_ZCL_THERMOSTAT_TRV_MODE_DEFAULT_VALUE;
        m_dev_ctx.thermostat_attr.set_valve_position           = 0;
        m_dev_ctx.thermostat_attr.error                        = 0;
        m_dev_ctx.thermostat_attr.host_flags                   = 0x000001;
         
        /***time cluster attributes data**/
        m_dev_ctx.time_attr.timeId = ZB_ZCL_TIME_TIME_DEFAULT_VALUE;
        m_dev_ctx.time_attr.time_status = ZB_ZCL_TIME_TIME_STATUS_DEFAULT_VALUE;
        
        /*local temperature set attribute**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.local_temperature,
                            ZB_FALSE);
     
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.occupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                             (zb_uint8_t *)&m_dev_ctx.thermostat_attr.host_flags, 
                             ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID, 
                             (zb_uint8_t *)& m_dev_ctx.thermostat_attr.trv_mode, 
                             ZB_FALSE);
    
       /**Battery percentage value**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_percentage_remaining,
                            ZB_FALSE);  
                                      
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_QUANTITY_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_quantity,
                            ZB_FALSE);
    }
    
    /**@brief Function for local temperature
     *
     * @param[in]   new_value local temp value
     */
    void localTemperatureValue(zb_uint16_t ui16local_tempvalue)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID, 
                                         (zb_uint8_t *)&ui16local_tempvalue , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set local temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    void CurrentSetpointChangeValue(zb_uint16_t ui16CurrentSetpoint)
    {
       zb_zcl_status_t zcl_status;
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID,
                                        (zb_uint8_t *)&ui16CurrentSetpoint,
                                        ZB_FALSE);
       
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Setc current set point temperature value fail. zcl_status: %d", zcl_status);
       }
    
       
       if(ui16CurrentSetpoint != 0xFFFF)
       {
          ui16CurrentTemp = ui16CurrentSetpoint;
       }
       else
       {
          ui16CurrentTemp = 0xFFFF;
       }
    
    }
    
    /**
    **function to read/write the occupied heating setpoint 
    **Any change in occupied heating value will automatically copied to set point change attribute
    **
    **/
    void OccupiedHeatingSetpoint(zb_uint16_t ui16OccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16OccupiedSetpoint,
                                        ZB_FALSE);
       
         
       if(ui16OccupiedSetpoint != 0xFFFF)
       {
          ui16OccupiedHeatSetpoint = ui16OccupiedSetpoint;
          ui16CurrentTemp = ui16OccupiedSetpoint;
          CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
          ui16OccupiedHeatSetpoint == 0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void ReadOccupiedHeatingSetpoint(zb_uint16_t ui16ReadOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16ReadOccupiedSetpoint,
                                        ZB_FALSE);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the unoccupied heating setpoint 
    **Any change in unoccupied heating value will automatically copied to set point change attribute
    **
    **/
    void UnOccupiedHeatingSetpoint(zb_uint16_t ui16UnOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16UnOccupiedSetpoint,
                                        ZB_FALSE);
       
       if(ui16UnOccupiedSetpoint != 0xFFFF)
       {
         ui16UnOccupiedHeatSetpoint = ui16UnOccupiedSetpoint;
         ui16CurrentTemp = ui16UnOccupiedSetpoint;
         CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
         ui16UnOccupiedHeatSetpoint =  0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set unoccupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**
    **function to read value of pi heating demand
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    static void PIHeatingDemand (zb_uint8_t ui8PiHeatingDemand)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_PI_HEATING_DEMAND_ID,
                                        &ui8PiHeatingDemand,
                                        ZB_FALSE);
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read pi heating demand value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function for read/write local temperature calibration
    **Any change in local temperature attribute then add this value to D11 and D12 of set temperature command
    **
    **/
    static void LocalTemperatureCalibration(zb_uint8_t ui8localTempCalibration)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID,
                                        &ui8localTempCalibration,
                                        ZB_FALSE);
       
       ui8LocalTemperatureCalibration = ui8localTempCalibration;
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("local temperature calibration value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the valve position
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    void SetValvePosition(zb_uint8_t ui8ValvePosition)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID,
                                        &ui8ValvePosition,
                                        ZB_FALSE);
       
       PIHeatingDemand(ui8ValvePosition);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set valve position value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void SetTRVMode (zb_uint8_t ui8TRVMode)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID,
                                        &ui8TRVMode,
                                        ZB_FALSE);
       
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set trv mode value fail. zcl_status: %d", zcl_status);
       }
    }
    /**@brief Function for remaining battery percentage 
     *
     * @param[in]   new_value local temp value
     */
    void ReadRemainigBatteryPercentage(zb_uint8_t ui8BatteryPercentage)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_POWER_CONFIG, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, 
                                         &ui8BatteryPercentage , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set Battery percentage value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read the error status for different valve status 
    **Any change in valve status respective error state copied to Error attribute which is read only attribute
    **
    **/
    void ReadErrorStatus(zb_uint8_t ui8ErrorStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_ERROR_ID, 
                                         &ui8ErrorStatus , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read error status fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the flag status for different operation 
    **
    **
    **/
    void HostFlagStatus(zb_uint32_t ui32HostFlagsStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                                         (zb_uint8_t *)&ui32HostFlagsStatus, 
                                         ZB_FALSE);
       ui32HostflagsData = ui32HostFlagsStatus;
    
        //Rotate LCD by 180
        if((ui32HostflagsData & 0x000002)== 0x02)
        {    
          boolSetHostflags = false;
    
          boolSendDeviceConfig = true;
          if((ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION) & DEVICE_CONFIG_BYTE_3_LCD_ROTATION ) 
          {
            ui8SendDeviceConfig[5] |= DEVICE_CONFIG_BYTE_3_LCD_ROTATION;        
          }
        }
        //LCD in default position
        if((ui32HostflagsData ^ 0x000002) & 0x02 )
        {
          boolSetHostflags = false;
          boolSendDeviceConfig = true;
          if(ui8SendDeviceConfig[5]  & DEVICE_CONFIG_BYTE_3_LCD_ROTATION) 
          {
            ui8SendDeviceConfig[5]  &= ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION;		        
          }
        }
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Host flag status fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**@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]   bufid   Reference to Zigbee stack buffer used to pass received data.
     */
    static zb_void_t zcl_device_cb(zb_bufid_t bufid)
    {
        zb_uint16_t                cluster_id;
        zb_uint16_t                attr_id;
        zb_zcl_device_callback_param_t * p_device_cb_param = ZB_BUF_GET_PARAM(bufid, 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_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_THERMOSTAT)
                 {
                      if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          OccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                          
                      }
                      else if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          UnOccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                         
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          CurrentSetpointChangeValue(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                           
                      }
                      else if(attr_id ==ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          LocalTemperatureCalibration(value);
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          SetValvePosition(value);
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID)
                      {
                         zb_uint32_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data32;
                         HostFlagStatus(value);
                         boolSetHostflags  = true; 
                         boolReady = true;
                         boolMCUInterrupt = false; 
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID)
                      {
                         zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                         SetTRVMode(value);
                      }
                 }
                   
              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]   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);
    
        /* No application-specific behavior is required. Call default signal handler. */
        ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    
        if (bufid)
        {
            zb_buf_free(bufid);
        }
    }
    
    
    /**@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. */
        nrf_delay_ms(1500);
    
        log_init();
        
    /********User initialization (uart, timer and ulp)**********/
        timer_config_func();
    
        ulp_input_pin_configuration();
    
        Flashinitialization();
         
        /* 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("thermostat");
    
        /* 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_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(3000));
        zb_set_rx_on_when_idle(ZB_FALSE);
        zigbee_power_down_unused_ram();
    
        zb_set_node_descriptor_manufacturer_code(ZB_ZCL_MANF_CODE);
    
        /* 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(&thermostat_ctx);
    
        thermostat_clusters_attr_init();
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start_no_autostart();
        ZB_ERROR_CHECK(zb_err_code);
    
    
        CommandBootloader();    //get bootloader command 
        
        while(1)
        {
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    
            CommunicationStateExecution();   //MCU and NP communication state     
            DataProcessing();                //Flag bit processing
            UARTStateStateMachine();  
        }
    }
    
    
    /**
     * @}
     */
    

    Thanks and regards

    Ankeet Gugale

  • Hi

    As the main() loop starts over again once you reset your device, all the initializations will start over as well. I think you need to do some debugging to find out at what point your application stops/fails, as it must be halting somewhere before this while loop is called. I would try setting break points at various functions in the main loop to see if one of the inits fail for some reason (maybe something isn't uninitialized correctly when the device is reset for example).

    It could also be that the state machine is in an invalid state at the moment of the reset, that's hindering it from starting up again after the reset.

    Best regards,

    Simon

  • Hi,

    Thank you for the response.

    As per your suggestion I did step by step after NVIC_SystemReset();
    I posted query when I tested on SDK3.0 for zigbee and thread but I upgraded to SDK 4.1 for Zigbee and thread again tested same but this time while() loop executed so I am using SDK4.1. So the problem seems to be solved. 

    And as nordic engineers are on leave and we have late response, I need one more help and which little urgent for me so I am requesting you here. I request you to help me with this query also.

    I want my attribute reporting should happen automatically. For my project I am using nRF52840 and deCONZ gateway for communication. So whenever I write on attribute on gateway GUI it not reflecting unless and untill I click on Read.

    I have our nxp based product which works perfect with attribute reporting when the reporting interval in changed using deCONZ. Same I want to implement in nRF. It will be helpful if you could explain us how to handle the attribute reporting in nRF.

    Thanks and regards

    Ankeet Gugale

  • Hi again Ankeet

    We have a few cases explaining how to do attribute reporting in Zigbee already on DevZone. Please check out this case for example, where Marte has provided a code snippet showing how to configure this from the reporting device.

    You can also check out this case where Marjeris explains how to do attribute reporting for custom clusters. If none of these are what you're looking for, there are more attribute reporting tickets around on DevZone.

    Best regards,

    Simon

Related