adding SUOTA service in firmware but going in platform_reset_func().

Hello there!

I am trying to add the SUOTA service in my ibeacon modified firmware.

i have included all SUOTA configuration as per prox reporter and tutorial with changing to undirected advertising by a flag condition. I have #define CFG_PRF_SUOTAR in user_profile_config.h

and it goes in platform_reset_func() while debugging. and if i see the uart logs it stops printing after rwip_schedule(); line no 399 in arch_main.c

log___1 and log___2 are visible.

 

__STATIC_INLINE void schedule_while_ble_on(void)
{
	printf_string(UART2,"log__1\n");
    // BLE clock is enabled
    while (ble_is_powered())
    {
        //execute messages and events
			printf_string(UART2,"log___2\n");
        rwip_schedule();
			printf_string(UART2,"log__3\n");
#if defined (__DA14531__)

And if i comment the #define CFG_PRF_SUOTAR in user_profile_config.h the whole program runs very well without going to reset error.

please guide me about this, How can i add SUOTA service in my code and why this error happening.

Parents
  • Hi piyush, 

    Thanks for your question online. This assertion means that a platform reset occurs. Τhe platform_reset_func() is invoked by the platform_reset(), which is implemented in the ROM code. The most probable reason for this assertion is due to insufficient memory, because you are allocating messages which are never consumed. For example, if you are allocating notification messages and you have a small connection interval the messages are piled up until a connection event arrives, but with a large connection interval, your run out of memory before the connection event arrives.

    So, it seems there is some kind of memory leakage.

    Please try to increase the MSG heap size – refer to  this tutorial: http://lpccs-docs.dialog-semiconductor.com/Tutorial_SDK6/heap_usage.html

    Regards, 

    PM_Renesas

  • Hello Thankyou for answering me!

    I have increased heap size by uncommenting the MACROS. but still it is going in platform_reset_func()

    Also when i comment #define CFG_PRF_SUOTAR the program runs well, i wonder why ?

    what can i do further for adding SUOTA?

  • Hi piyush, 

    Please try to remove the printf in schedule_while_ble_on(). Still the same results? 

    As mentioned, there is some kind of memory leakage which should not be related to the SUOTA functionality.

    Regards, 

    PM_Renesas

  • hello,

    I have drop all the printf lines after the "platform_reset_func()" error. so it is not an issue.

    I even maximized heap size still same error.

    And when i comment the "#define CFG_PRF_SUOTAR" line, the code works and advertise without any reset error.

    I can not understand why such behaviour comes up, even i haven't allocate any dynamic memory.

    So by which way i can put SUOTA service.

  • Hi piyush, 

    Can you please indicate which SDK project you are using in order to add SUOTA feature? 

    Please also share the modifications you have done.

    The SUOTA functionality is already added to the pxp_reporter project of the SDK6. 

    Best regards, 

    PM_Renesas

  • Hi,

    I have tried prox_reporter example for SUOTA which was successfully done.

    Now I am using ibeacon example and using SDK 6.0.16.1144. I have just modified advertising data and added a timer which will take system to extended sleep after 5 sec after the button press. and for SUOTA i have changed adv to   "app_easy_gap_undirected_advertise_start();" for now  so we can connect phone with device.

    I have changed following for adding SUOTA:

    #define CFG_PRF_SUOTAR in user_profile_config.
    #define CFG_SPI_FLASH_ENABLE in da1458x_config_basic.h
    #define EXCLUDE_DLG_SUOTAR          (0)
    
    added functions from prox_reporter:-
    void on_suotar_status_change();
    user_app_on_disconnect();

    And the whole program running well without defining cfg_prf_suotar. No memory leakage.

    No any other change in SDK. But when i define program goes in platform reset after this line in debug mode,

    // Close peripheral clock
            SetBits16(CLK_PER_REG, QUAD_ENABLE, 0);

    inside of system_init();

    And also i want to see the heap log, i am changing da14531 with da14531withheaplog library and  did #define CFG_LOG_HEAP_USAGE but when i type disp_heaplog(); it shows "error 34: undefined identifier"

    what can i do now, please guide me!

    Thnakyou

  • Hi piyush, 

    Can you please upload the modified iBeacon project so that I can take a look ? 

    Regards, 

    PM_Renesas

  • #include "rwip_config.h"
    #include "app_api.h"
    #include "user_sleepmode_vegg.h"
    #include "user_periph_setup.h"
    #include "user_callback_config.h"
    #include "app_default_handlers.h"
    #include "wkupct_quadec.h"
    #include "gpio.h"
    #include "uart_utils.h"
    //#include "arch_console.h"
    
    #if (BLE_SUOTA_RECEIVER)
    #include "app_suotar.h"
    #endif
    
    #if defined (CFG_SPI_FLASH_ENABLE)
    #include "spi_flash.h"
    #endif
    
    
    /* Advertising payload field sizes */
    #define FLAGS_LEN                                       3
    #define COMPANY_ID_LEN                                  2
    #define BEACON_TYPE_LEN                                 2
    #define UUID_LEN                                        16
    
    /* Fixed advertising fields */
    #define FLAG_0                                          0x02
    #define FLAG_1                                          0x01
    #define FLAG_2                                          0x06
    #define LENGTH                                          0x1A
    #define TYPE                                            0xFF
    #define COMPANY_ID_0                                    0x4C
    #define COMPANY_ID_1                                    0x00
    #define BEACON_TYPE_0                                   0x02
    #define BEACON_TYPE_1                                   0x15
    
    #if defined (TX_POWER_2d5Bm)
    #define MEASURED_POWER                                  0xC7
    #if !defined (__DA14531__)
    #error "Config error: Can not define TX_POWER_2d5Bm when device selected is DA14585 or DA14586."
    #endif
    #else    
    /* Output power 0dBm */
    #define MEASURED_POWER                                  0xC5
    #endif
    
    /* User defined advertising fields */
    #define UUID_STR                                        "DEADBEEF-A001-B301-D001-DEADBEEF0011"
    
    uint16_t MAJOR = 0x0000;
    uint16_t MINOR = 0x0000;
    
    /* Set the advertising rate */
    #define ADV_INTERVAL_ms                                 20
    
    #define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
    
    /*
    * TYPE DEFINITIONS
    ****************************************************************************************
    */
    /* Apple Proximity Beacon Specification - Release R1  */
    typedef struct __attribute__ ((__packed__)) {
        uint8_t  flags[FLAGS_LEN];
        uint8_t  length;
        uint8_t  type;
        uint8_t  company_id[COMPANY_ID_LEN];
        uint8_t  beacon_type[BEACON_TYPE_LEN];
        uint8_t  uuid[UUID_LEN];
        uint16_t major;
        uint16_t minor;
        uint8_t  measured_power;
    } ibeacon_adv_payload_t;
    
    /*
    * GLOBAL VARIABLE DEFINITIONS
    ****************************************************************************************
    */
    
    bool after_sleep = false;
    bool MINOR_bit                                __SECTION_ZERO("retention_mem_area0");
    
    timer_hnd app_adv_data_update_timer_used;
    
    /*
    * FUNCTION DEFINITIONS
    ****************************************************************************************
    */
    static uint8_t hex2byte(char *hex);
    static void uuid2hex(char *uuid, uint8_t *output);
    
    /**
    ****************************************************************************************
    * @brief Advertisement data update timer callback function.
    ****************************************************************************************
    */
    static void adv_data_update_timer_cb()
    {
        // Stop advertising air operation - a button press will wake-up the system
        //app_easy_gap_advertise_stop();
         printf_string(UART2,"TIMER CALLBACK OF ADVERTISING. now sleeping..\r\n");
    	   arch_set_sleep_mode(app_default_sleep_mode);
    	   arch_ble_ext_wakeup_on();
    }
    
    void user_app_init(void)
    {
    	  printf_string(UART2,"system init......");
        // Initialize default Data
        default_app_on_init();
    	  app_button_enable();
    	  arch_ble_ext_wakeup_on();
        //arch_printf("user_app_init_version_0_1\r\n");
    }
    
    //void user_app_adv_start(void){
    //    printf_string(UART2,"\nfrom advertising start fun.\n");
    //}
    
    void vlaue_change(void)
    {
           // MINOR_bit = !MINOR_bit;
        if(!MINOR_bit)
        {
            MINOR_bit = 1;
            // update minor with bit 0
            MINOR = MINOR+MINOR_bit;
    				//GPIO_SetActive(GPIO_PORT_0, GPIO_PIN_9);
        }
        else if(MINOR_bit)
        {
            MINOR_bit = 0;
            // update minor with bit 1
            MINOR = MINOR &(0xFF00+MINOR_bit);
    				//GPIO_SetInactive(GPIO_PORT_0, GPIO_PIN_9);
        }
    }	
    
    void user_app_adv_start(void)
    {
        ibeacon_adv_payload_t adv_payload;
        struct gapm_start_advertise_cmd *cmd = app_easy_gap_non_connectable_advertise_get_active(); 
    
        /* Setup the iBeacon advertising payload */
        adv_payload.flags[0]       = FLAG_0;
        adv_payload.flags[1]       = FLAG_1;
        adv_payload.flags[2]       = FLAG_2;
        adv_payload.length         = LENGTH;
        adv_payload.type           = TYPE;
        adv_payload.company_id[0]  = COMPANY_ID_0;
        adv_payload.company_id[1]  = COMPANY_ID_1;
        adv_payload.beacon_type[0] = BEACON_TYPE_0;
        adv_payload.beacon_type[1] = BEACON_TYPE_1;
    
        /* Convert ASCII UUID to hex format */
        uuid2hex((char *)UUID_STR, adv_payload.uuid);
        
    		vlaue_change(); 
    				
        adv_payload.major = ENDIAN_CHANGE_U16(MAJOR);
        adv_payload.minor = ENDIAN_CHANGE_U16(MINOR);
        adv_payload.measured_power = MEASURED_POWER;
    
        memcpy(cmd->info.host.adv_data, &adv_payload, sizeof(ibeacon_adv_payload_t));
        cmd->info.host.adv_data_len = sizeof(ibeacon_adv_payload_t);
    
        /* Set the advertising interval */
        cmd->intv_min = MS_TO_BLESLOTS(ADV_INTERVAL_ms);
        cmd->intv_max = MS_TO_BLESLOTS(ADV_INTERVAL_ms);
    
        app_easy_gap_update_adv_data(cmd->info.host.adv_data,
            sizeof(ibeacon_adv_payload_t),
            cmd->info.host.scan_rsp_data,
            sizeof(cmd->info.host.scan_rsp_data));
        /* Request advertising is started.. */
    		printf_string(UART2,"advertising started.....");
    		default_advertise_operation();
    
    }
    
    /**
    ****************************************************************************************
    * @brief Button press callback function. Registered in WKUPCT driver.
    ****************************************************************************************
    */
    static void app_button_press_cb(void)
    {
    	  //arch_printf("app_button_press_cb called......\r\n");
    	 // app_easy_timer_cancel(app_adv_data_update_timer_used);
    
    	  printf_string(UART2,"\n\nbutton interrupt came...\n\n");
    	  app_button_enable();
    #if !defined (__DA14531__)
        if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
    #endif
        {
            periph_init();
        }
        if (arch_ble_ext_wakeup_get())
        {
    				app_adv_data_update_timer_used = EASY_TIMER_INVALID_TIMER;
    	      app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);
            arch_set_sleep_mode(app_default_sleep_mode);
            arch_ble_force_wakeup();
            arch_ble_ext_wakeup_off();
            app_easy_wakeup();
            
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Application wakeup callback function. Registered in API message utility.
    ****************************************************************************************
    */
    static void app_wakeup_cb(void)
    {
    		  printf_string(UART2,"wakeup the system......\n");
    
        // If state is not idle, ignore the message
        if (ke_state_get(TASK_APP) == APP_CONNECTABLE)
        {
            //user_app_adv_start();
            after_sleep = false;
    			  user_app_adv_start();
            //arch_printf("ENABLE : app_btn_cb->after_sleep = false\r\n");
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Sets button as wakeup trigger
    ****************************************************************************************
    */
    static void app_button_enable(void)
    {
    	  printf_string(UART2,"button enebling...\n");
        app_easy_wakeup_set(app_wakeup_cb);
        wkupct_register_callback(app_button_press_cb);
        wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // select pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)
            WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low
            1, // 1 event
            20); // debouncing time = 0
        //arch_printf("[app_button_enable() for wakeup] after enter into sleep-> after_sleep = true\r\n");
    		//if(!after_sleep)
    		//	user_app_adv_start();
    }
    
    void user_app_adv_nonconn_complete(uint8_t status)
    {
        // Disable wakeup for BLE and timer events. Only external (GPIO) wakeup events can wakeup processor.
        if (status == GAP_ERR_CANCELED)
        {
    				after_sleep = true;
            arch_ble_ext_wakeup_on();
            //arch_printf("arch_ble_ext_wakeup_on goes to sleep -> app_button_enable\r\n");
            // Configure wakeup button
            app_button_enable();
        }
    }
    
    void user_catch_rest_hndl(ke_msg_id_t const msgid,
        void const *param,
        ke_task_id_t const dest_id,
        ke_task_id_t const src_id)
    {
    }
    
    #if (BLE_SUOTA_RECEIVER)
    void on_suotar_status_change(const uint8_t suotar_event)
    {
    #if (!SUOTAR_SPI_DISABLE)
        uint8_t dev_id;
    
        // Release the SPI flash memory from power down
        spi_flash_release_from_power_down();
    
        // Disable the SPI flash memory protection (unprotect all sectors)
        spi_flash_configure_memory_protection(SPI_FLASH_MEM_PROT_NONE);
    
        // Try to auto-detect the SPI flash memory
        spi_flash_auto_detect(&dev_id);
    
        if (suotar_event == SUOTAR_END)
        {
            // Power down the SPI flash memory
            spi_flash_power_down();
        }
    #endif
    }
    #endif
    
    void user_app_on_disconnect(struct gapc_disconnect_ind const *param)
    {
        default_app_on_disconnect(NULL);
    
    #if (BLE_BATT_SERVER)
        app_batt_poll_stop();
    #endif
    
    #if (BLE_SUOTA_RECEIVER)
        // Issue a platform reset when it is requested by the suotar procedure
        if (suota_state.reboot_requested)
        {
            // Reboot request will be served
            suota_state.reboot_requested = 0;
    
            // Platform reset
            platform_reset(RESET_AFTER_SUOTA_UPDATE);
        }
    #endif
    
    #if BLE_PROX_REPORTER
        app_proxr_alert_stop();
    #endif
    }
    
    /**
    ****************************************************************************************
    * @brief Converts UUID ASCII string to hex equivalent.
    * @return void
    ****************************************************************************************
    */
    static void uuid2hex(char *uuid, uint8_t *output)
    {
        uint8_t in_ix;
        uint8_t out_ix;
        for (out_ix = 0, in_ix = 0; out_ix < UUID_LEN; out_ix++, in_ix += 2) {
            if (uuid[in_ix] == '-') {
                in_ix++;
            }
            output[out_ix] = hex2byte(&uuid[in_ix]);
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Converts ASCII character to hex equivalent.
    * @return void
    ****************************************************************************************
    */
    static uint8_t hex2byte(char *hex)
    {
        uint8_t byte = 0;
        uint8_t digits = 2;
        while (digits--) {
            uint8_t c = *hex++; 
            if (c >= '0' && c <= '9') c = c - '0';
            else if (c >= 'a' && c <= 'f') c = c - 'a' + 10;
            else if (c >= 'A' && c <= 'F') c = c - 'A' + 10;
            else c = 0;
            byte = byte << 4;
            byte = byte | (c & 0x0F);
        }
        return byte;
    }
    /// @} APP
    

Reply
  • #include "rwip_config.h"
    #include "app_api.h"
    #include "user_sleepmode_vegg.h"
    #include "user_periph_setup.h"
    #include "user_callback_config.h"
    #include "app_default_handlers.h"
    #include "wkupct_quadec.h"
    #include "gpio.h"
    #include "uart_utils.h"
    //#include "arch_console.h"
    
    #if (BLE_SUOTA_RECEIVER)
    #include "app_suotar.h"
    #endif
    
    #if defined (CFG_SPI_FLASH_ENABLE)
    #include "spi_flash.h"
    #endif
    
    
    /* Advertising payload field sizes */
    #define FLAGS_LEN                                       3
    #define COMPANY_ID_LEN                                  2
    #define BEACON_TYPE_LEN                                 2
    #define UUID_LEN                                        16
    
    /* Fixed advertising fields */
    #define FLAG_0                                          0x02
    #define FLAG_1                                          0x01
    #define FLAG_2                                          0x06
    #define LENGTH                                          0x1A
    #define TYPE                                            0xFF
    #define COMPANY_ID_0                                    0x4C
    #define COMPANY_ID_1                                    0x00
    #define BEACON_TYPE_0                                   0x02
    #define BEACON_TYPE_1                                   0x15
    
    #if defined (TX_POWER_2d5Bm)
    #define MEASURED_POWER                                  0xC7
    #if !defined (__DA14531__)
    #error "Config error: Can not define TX_POWER_2d5Bm when device selected is DA14585 or DA14586."
    #endif
    #else    
    /* Output power 0dBm */
    #define MEASURED_POWER                                  0xC5
    #endif
    
    /* User defined advertising fields */
    #define UUID_STR                                        "DEADBEEF-A001-B301-D001-DEADBEEF0011"
    
    uint16_t MAJOR = 0x0000;
    uint16_t MINOR = 0x0000;
    
    /* Set the advertising rate */
    #define ADV_INTERVAL_ms                                 20
    
    #define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
    
    /*
    * TYPE DEFINITIONS
    ****************************************************************************************
    */
    /* Apple Proximity Beacon Specification - Release R1  */
    typedef struct __attribute__ ((__packed__)) {
        uint8_t  flags[FLAGS_LEN];
        uint8_t  length;
        uint8_t  type;
        uint8_t  company_id[COMPANY_ID_LEN];
        uint8_t  beacon_type[BEACON_TYPE_LEN];
        uint8_t  uuid[UUID_LEN];
        uint16_t major;
        uint16_t minor;
        uint8_t  measured_power;
    } ibeacon_adv_payload_t;
    
    /*
    * GLOBAL VARIABLE DEFINITIONS
    ****************************************************************************************
    */
    
    bool after_sleep = false;
    bool MINOR_bit                                __SECTION_ZERO("retention_mem_area0");
    
    timer_hnd app_adv_data_update_timer_used;
    
    /*
    * FUNCTION DEFINITIONS
    ****************************************************************************************
    */
    static uint8_t hex2byte(char *hex);
    static void uuid2hex(char *uuid, uint8_t *output);
    
    /**
    ****************************************************************************************
    * @brief Advertisement data update timer callback function.
    ****************************************************************************************
    */
    static void adv_data_update_timer_cb()
    {
        // Stop advertising air operation - a button press will wake-up the system
        //app_easy_gap_advertise_stop();
         printf_string(UART2,"TIMER CALLBACK OF ADVERTISING. now sleeping..\r\n");
    	   arch_set_sleep_mode(app_default_sleep_mode);
    	   arch_ble_ext_wakeup_on();
    }
    
    void user_app_init(void)
    {
    	  printf_string(UART2,"system init......");
        // Initialize default Data
        default_app_on_init();
    	  app_button_enable();
    	  arch_ble_ext_wakeup_on();
        //arch_printf("user_app_init_version_0_1\r\n");
    }
    
    //void user_app_adv_start(void){
    //    printf_string(UART2,"\nfrom advertising start fun.\n");
    //}
    
    void vlaue_change(void)
    {
           // MINOR_bit = !MINOR_bit;
        if(!MINOR_bit)
        {
            MINOR_bit = 1;
            // update minor with bit 0
            MINOR = MINOR+MINOR_bit;
    				//GPIO_SetActive(GPIO_PORT_0, GPIO_PIN_9);
        }
        else if(MINOR_bit)
        {
            MINOR_bit = 0;
            // update minor with bit 1
            MINOR = MINOR &(0xFF00+MINOR_bit);
    				//GPIO_SetInactive(GPIO_PORT_0, GPIO_PIN_9);
        }
    }	
    
    void user_app_adv_start(void)
    {
        ibeacon_adv_payload_t adv_payload;
        struct gapm_start_advertise_cmd *cmd = app_easy_gap_non_connectable_advertise_get_active(); 
    
        /* Setup the iBeacon advertising payload */
        adv_payload.flags[0]       = FLAG_0;
        adv_payload.flags[1]       = FLAG_1;
        adv_payload.flags[2]       = FLAG_2;
        adv_payload.length         = LENGTH;
        adv_payload.type           = TYPE;
        adv_payload.company_id[0]  = COMPANY_ID_0;
        adv_payload.company_id[1]  = COMPANY_ID_1;
        adv_payload.beacon_type[0] = BEACON_TYPE_0;
        adv_payload.beacon_type[1] = BEACON_TYPE_1;
    
        /* Convert ASCII UUID to hex format */
        uuid2hex((char *)UUID_STR, adv_payload.uuid);
        
    		vlaue_change(); 
    				
        adv_payload.major = ENDIAN_CHANGE_U16(MAJOR);
        adv_payload.minor = ENDIAN_CHANGE_U16(MINOR);
        adv_payload.measured_power = MEASURED_POWER;
    
        memcpy(cmd->info.host.adv_data, &adv_payload, sizeof(ibeacon_adv_payload_t));
        cmd->info.host.adv_data_len = sizeof(ibeacon_adv_payload_t);
    
        /* Set the advertising interval */
        cmd->intv_min = MS_TO_BLESLOTS(ADV_INTERVAL_ms);
        cmd->intv_max = MS_TO_BLESLOTS(ADV_INTERVAL_ms);
    
        app_easy_gap_update_adv_data(cmd->info.host.adv_data,
            sizeof(ibeacon_adv_payload_t),
            cmd->info.host.scan_rsp_data,
            sizeof(cmd->info.host.scan_rsp_data));
        /* Request advertising is started.. */
    		printf_string(UART2,"advertising started.....");
    		default_advertise_operation();
    
    }
    
    /**
    ****************************************************************************************
    * @brief Button press callback function. Registered in WKUPCT driver.
    ****************************************************************************************
    */
    static void app_button_press_cb(void)
    {
    	  //arch_printf("app_button_press_cb called......\r\n");
    	 // app_easy_timer_cancel(app_adv_data_update_timer_used);
    
    	  printf_string(UART2,"\n\nbutton interrupt came...\n\n");
    	  app_button_enable();
    #if !defined (__DA14531__)
        if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
    #endif
        {
            periph_init();
        }
        if (arch_ble_ext_wakeup_get())
        {
    				app_adv_data_update_timer_used = EASY_TIMER_INVALID_TIMER;
    	      app_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);
            arch_set_sleep_mode(app_default_sleep_mode);
            arch_ble_force_wakeup();
            arch_ble_ext_wakeup_off();
            app_easy_wakeup();
            
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Application wakeup callback function. Registered in API message utility.
    ****************************************************************************************
    */
    static void app_wakeup_cb(void)
    {
    		  printf_string(UART2,"wakeup the system......\n");
    
        // If state is not idle, ignore the message
        if (ke_state_get(TASK_APP) == APP_CONNECTABLE)
        {
            //user_app_adv_start();
            after_sleep = false;
    			  user_app_adv_start();
            //arch_printf("ENABLE : app_btn_cb->after_sleep = false\r\n");
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Sets button as wakeup trigger
    ****************************************************************************************
    */
    static void app_button_enable(void)
    {
    	  printf_string(UART2,"button enebling...\n");
        app_easy_wakeup_set(app_wakeup_cb);
        wkupct_register_callback(app_button_press_cb);
        wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // select pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)
            WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low
            1, // 1 event
            20); // debouncing time = 0
        //arch_printf("[app_button_enable() for wakeup] after enter into sleep-> after_sleep = true\r\n");
    		//if(!after_sleep)
    		//	user_app_adv_start();
    }
    
    void user_app_adv_nonconn_complete(uint8_t status)
    {
        // Disable wakeup for BLE and timer events. Only external (GPIO) wakeup events can wakeup processor.
        if (status == GAP_ERR_CANCELED)
        {
    				after_sleep = true;
            arch_ble_ext_wakeup_on();
            //arch_printf("arch_ble_ext_wakeup_on goes to sleep -> app_button_enable\r\n");
            // Configure wakeup button
            app_button_enable();
        }
    }
    
    void user_catch_rest_hndl(ke_msg_id_t const msgid,
        void const *param,
        ke_task_id_t const dest_id,
        ke_task_id_t const src_id)
    {
    }
    
    #if (BLE_SUOTA_RECEIVER)
    void on_suotar_status_change(const uint8_t suotar_event)
    {
    #if (!SUOTAR_SPI_DISABLE)
        uint8_t dev_id;
    
        // Release the SPI flash memory from power down
        spi_flash_release_from_power_down();
    
        // Disable the SPI flash memory protection (unprotect all sectors)
        spi_flash_configure_memory_protection(SPI_FLASH_MEM_PROT_NONE);
    
        // Try to auto-detect the SPI flash memory
        spi_flash_auto_detect(&dev_id);
    
        if (suotar_event == SUOTAR_END)
        {
            // Power down the SPI flash memory
            spi_flash_power_down();
        }
    #endif
    }
    #endif
    
    void user_app_on_disconnect(struct gapc_disconnect_ind const *param)
    {
        default_app_on_disconnect(NULL);
    
    #if (BLE_BATT_SERVER)
        app_batt_poll_stop();
    #endif
    
    #if (BLE_SUOTA_RECEIVER)
        // Issue a platform reset when it is requested by the suotar procedure
        if (suota_state.reboot_requested)
        {
            // Reboot request will be served
            suota_state.reboot_requested = 0;
    
            // Platform reset
            platform_reset(RESET_AFTER_SUOTA_UPDATE);
        }
    #endif
    
    #if BLE_PROX_REPORTER
        app_proxr_alert_stop();
    #endif
    }
    
    /**
    ****************************************************************************************
    * @brief Converts UUID ASCII string to hex equivalent.
    * @return void
    ****************************************************************************************
    */
    static void uuid2hex(char *uuid, uint8_t *output)
    {
        uint8_t in_ix;
        uint8_t out_ix;
        for (out_ix = 0, in_ix = 0; out_ix < UUID_LEN; out_ix++, in_ix += 2) {
            if (uuid[in_ix] == '-') {
                in_ix++;
            }
            output[out_ix] = hex2byte(&uuid[in_ix]);
        }
    }
    
    /**
    ****************************************************************************************
    * @brief Converts ASCII character to hex equivalent.
    * @return void
    ****************************************************************************************
    */
    static uint8_t hex2byte(char *hex)
    {
        uint8_t byte = 0;
        uint8_t digits = 2;
        while (digits--) {
            uint8_t c = *hex++; 
            if (c >= '0' && c <= '9') c = c - '0';
            else if (c >= 'a' && c <= 'f') c = c - 'a' + 10;
            else if (c >= 'A' && c <= 'F') c = c - 'A' + 10;
            else c = 0;
            byte = byte << 4;
            byte = byte | (c & 0x0F);
        }
        return byte;
    }
    /// @} APP
    

Children