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

Work with Softdevice and RTC with internal RC oscillator on nRF52832

Hi,

I need to run RTC simultaneously with Softdevice without external low frequency clock source (32.768kHz oscillator).

I used following settings to setup RTC,

RTC_ENABLED 1
RTC2_ENABLED 1
NRFX_RTC_ENABLED 1
NRFX_RTC2_ENABLED 1
NRFX_CLOCK_ENABLED 1
NRF_CLOCK_ENABLED 1

with above settings I was able to use RTC without any problem. And it works with and without external low frequency oscillator.

Then try to work with softdevice. With external oscillator no problem occured. RTC works simultaneously with softdevice, no issue with provisioning or controlling device through mesh.

I can run RTC with internal RC oscillator with following settings,

NRF_CLOCK_LF_SRC_RC 0
NRF_SDH_CLOCK_LF_RC_CTIV 16
NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
NRF_SDH_CLOCK_LF_ACCURACY 1

So when I try to provision device stuck and give Initial Configuration Failed message. If I wasn't try to provision it works fine. (App stuck at Scanning for provisioned node state after sending provision data to the node)

But the device also work fine without RTC with above settings.

So Is there any other configurations need to made ?

Thank you

Parents
  • Hi Hung Bui,

    I have set configurations in sdk_config.h as follow for work with internal RC oscillator.

    Mesh system works with above settings without RTC configurations. 

    When provisioning through app following screens appear,

    After sending provisioning data,

    Then it try to find provisioned node,

      

    After this loading page app go back to main page with following message,

    This the Initial Configuration Failed message.

    I tried to follow the steps shown in this page but I was't able connect to the node that I have try to provision.

    This is the log window through debugger. 

    So I'm using Mesh SDK 3.0.0

    And I'm try to modify light_switch server example

    I'm using GATT bearer

    Thank you

Reply
  • Hi Hung Bui,

    I have set configurations in sdk_config.h as follow for work with internal RC oscillator.

    Mesh system works with above settings without RTC configurations. 

    When provisioning through app following screens appear,

    After sending provisioning data,

    Then it try to find provisioned node,

      

    After this loading page app go back to main page with following message,

    This the Initial Configuration Failed message.

    I tried to follow the steps shown in this page but I was't able connect to the node that I have try to provision.

    This is the log window through debugger. 

    So I'm using Mesh SDK 3.0.0

    And I'm try to modify light_switch server example

    I'm using GATT bearer

    Thank you

Children
  • Hi Prasad, 

    This could be related to an issue we had that the softdevice after provisioning wasn't restarted so that the app couldn't connect to do configuration. But I'm not sure why it would related to the RTC2. If you don't start the RTC but only configure it do you see the issue ?

    Could you reproduce the issue with SDK v3.2 ? Could you provide a minimal example that we can test here to reproduce the issue ?

  • Hi Hung Bui,

    I comment out the rtc_config() function in initialize(). And then try to provision node through app, but it also gave me the same issue.

    And that lfclk_config() function which is in RTC example isn't used in my mesh example code. Is that a problem.

    With above lfclk_config function I got mesh assert error

    But without this lfclk_config() I was able to run timer.

    As you suggested I'll try to use SDK v3.2

    And this is my main.c file and sdk_config.h file configurations and libraries added as comments.

    Mesh SDK v3.0.0

    nRF5 SDK V15.2.0

    Main.c

    /* 
    
    Added Libraries
    nRF_Drivers
        nrf_drv_clock.c
        nrfx_clock.c
        nrfx_rtc.c
    
    RTC Config
    RTC_ENABLED 1
    RTC2_ENABLED 1
    NRFX_RTC_ENABLED 1
    NRFX_RTC2_ENABLED 1
    NRFX_CLOCK_ENABLED 1
    NRF_CLOCK_ENABLED 1
    
    Clock Config 
    NRF_SDH_CLOCK_LF_SRC 0                
    NRF_SDH_CLOCK_LF_RC_CTIV 16               
    NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    NRF_SDH_CLOCK_LF_ACCURACY 1                 
    
    
    
    The ending "UL" is a way to specify that a constant in C is of type Unsigned Long.
    
    f_RTC [kHz] = 32.768 / (PRESCALER + 1 )
    
    
    if (PRESCALER = 4095)
        f_RTC = 0.008kHz = 8 Hz
    
    
    So this run in 8Hz frequency
    So 8, 16, 24, 32, 40.... values can compare
    
    if we want to compare 3 seconds we need to 3 * 8 = 24
    
    Read
    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Frtc.html&cp=2_2_0_24_1&anchor=concept_iwc_1mj_sr
    
    
     */
    
    #include <stdint.h>
    #include <string.h>
    
    /* HAL */
    #include "boards.h"
    #include "simple_hal.h"
    #include "app_timer.h"
    
    /* Core */
    #include "nrf_mesh_config_core.h"
    #include "nrf_mesh_configure.h"
    #include "nrf_mesh.h"
    #include "mesh_stack.h"
    #include "device_state_manager.h"
    #include "access_config.h"
    #include "proxy.h"
    
    /* Provisioning and configuration */
    #include "mesh_provisionee.h"
    #include "mesh_app_utils.h"
    
    /* Models */
    #include "generic_onoff_server.h"
    
    /* Logging and RTT */
    #include "log.h"
    #include "rtt_input.h"
    
    /* Example specific includes */
    #include "app_config.h"
    #include "example_common.h"
    #include "nrf_mesh_config_examples.h"
    #include "light_switch_example_common.h"
    #include "app_onoff.h"
    #include "ble_softdevice_support.h"
    
    
    /* Newly Added*/
    #include "nrf_drv_clock.h"
    #include "nrf_drv_rtc.h"
    
    #include "nrf_delay.h"
    
    #define COMPARE_COUNTERTIME  (60UL)        
    /* 60UL = 60s     10min = 10*60 = 600s --> 600UL
    52min = 52*60 =
    
    */
    
    
    #define ONOFF_SERVER_0_LED          (BSP_LED_0)
    #define APP_ONOFF_ELEMENT_INDEX     (0)
    
    /*************************************************************************************************/
    const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2); /**< Declaring an instance of nrf_drv_rtc for RTC0. */
    
    
    
    /*************************************************************************************************/
    
    
    static bool m_device_provisioned;
    
    /*************************************************************************************************/
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff);
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff);
    
    /* Generic OnOff server structure definition and initialization */
    APP_ONOFF_SERVER_DEF(m_onoff_server_0,
                         APP_CONFIG_FORCE_SEGMENTATION,
                         APP_CONFIG_MIC_SIZE,
                         app_onoff_server_set_cb,
                         app_onoff_server_get_cb)
    
    /* Callback for updating the hardware state */
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff)
    {
        /* Resolve the server instance here if required, this example uses only 1 instance. */
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Setting GPIO value: %d\n", onoff)
    
        hal_led_pin_set(ONOFF_SERVER_0_LED, onoff);
    }
    
    /* Callback for reading the hardware state */
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff)
    {
        /* Resolve the server instance here if required, this example uses only 1 instance. */
    
        *p_present_onoff = hal_led_pin_get(ONOFF_SERVER_0_LED);
    }
    
    static void app_model_init(void)
    {
        /* Instantiate onoff server on element index APP_ONOFF_ELEMENT_INDEX */
        ERROR_CHECK(app_onoff_init(&m_onoff_server_0, APP_ONOFF_ELEMENT_INDEX));
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "App OnOff Model Handle: %d\n", m_onoff_server_0.server.model_handle);
    }
    
    /*************************************************************************************************/
    
    static void node_reset(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
        /* This function may return if there are ongoing flash operations. */
        mesh_stack_device_reset();
    }
    
    static void config_server_evt_cb(const config_server_evt_t * p_evt)
    {
        if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
        {
            node_reset();
        }
    }
    
    static void button_event_handler(uint32_t button_number)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
        switch (button_number)
        {
            /* Pressing SW1 on the Development Kit will result in LED state to toggle and trigger
            the STATUS message to inform client about the state change. This is a demonstration of
            state change publication due to local event. */
            case 0:
            {
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "User action \n");
                hal_led_pin_set(ONOFF_SERVER_0_LED, !hal_led_pin_get(ONOFF_SERVER_0_LED));
                app_onoff_status_publish(&m_onoff_server_0);
                break;
            }
    
            case 1:
            {
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Timer\n");
                uint32_t err_code;
                
    
                //Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
                err_code = nrf_drv_rtc_cc_set(&rtc,0,COMPARE_COUNTERTIME * 8,true);
                APP_ERROR_CHECK(err_code);
    
                //Power on RTC instance
                nrf_drv_rtc_enable(&rtc);
                break;
            }
    
            /* Initiate node reset */
            case 3:
            {
                /* Clear all the states to reset the node. */
                if (mesh_stack_is_device_provisioned())
                {
    #if MESH_FEATURE_GATT_PROXY_ENABLED
                    (void) proxy_stop();
    #endif
                    mesh_stack_config_clear();
                    node_reset();
                }
                else
                {
                    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "The device is unprovisioned. Resetting has no effect.\n");
                }
                break;
            }
    
            default:
                break;
        }
    }
    
    static void app_rtt_input_handler(int key)
    {
        if (key >= '0' && key <= '4')
        {
            uint32_t button_number = key - '0';
            button_event_handler(button_number);
        }
    }
    
    static void device_identification_start_cb(uint8_t attention_duration_s)
    {
        hal_led_mask_set(LEDS_MASK, false);
        hal_led_blink_ms(BSP_LED_2_MASK  | BSP_LED_3_MASK, 
                         LED_BLINK_ATTENTION_INTERVAL_MS, 
                         LED_BLINK_ATTENTION_COUNT(attention_duration_s));
    }
    
    static void provisioning_aborted_cb(void)
    {
        hal_led_blink_stop();
    }
    
    static void provisioning_complete_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");
    
    #if MESH_FEATURE_GATT_ENABLED
        /* Restores the application parameters after switching from the Provisioning
         * service to the Proxy  */
        gap_params_init();
        conn_params_init();
    #endif
    
        dsm_local_unicast_address_t node_address;
        dsm_local_unicast_addresses_get(&node_address);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);
    
        hal_led_blink_stop();
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
    }
    
    static void models_init_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
        app_model_init();
    }
    
    static void mesh_init(void)
    {
        uint8_t dev_uuid[NRF_MESH_UUID_SIZE];
        uint8_t node_uuid_prefix[NODE_UUID_PREFIX_LEN] = SERVER_NODE_UUID_PREFIX;
    
        ERROR_CHECK(mesh_app_uuid_gen(dev_uuid, node_uuid_prefix, NODE_UUID_PREFIX_LEN));
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = dev_uuid,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    }
    
    static void lfclk_config(void)
    {
        ret_code_t err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_clock_lfclk_request(NULL);
    
    }
    
    static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
    {
        if(int_type == NRF_DRV_RTC_INT_COMPARE0)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- RTC Handler -----\n");
            hal_led_pin_set(BSP_LED_1, true);
            //nrf_delay_ms(2000);
            //hal_led_pin_set(BSP_LED_1, false);
        } 
    }
    
    static void rtc_config(void)
    {
        uint32_t err_code;
        //Initialize RTC instance
        nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
        config.prescaler = 4095;
        err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_rtc_tick_enable(&rtc, true);
    //
    //    //Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
    //    err_code = nrf_drv_rtc_cc_set(&rtc,0,COMPARE_COUNTERTIME * 8,true);
    //    APP_ERROR_CHECK(err_code);
    //
    //    //Power on RTC instance
    //    nrf_drv_rtc_enable(&rtc);
    }
    
    static void initialize(void)
    {
        __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS | LOG_SRC_BEARER, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Light Switch Server Demo -----\n");
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    
    #if BUTTON_BOARD
        ERROR_CHECK(hal_buttons_init(button_event_handler));
    #endif
    
        ble_stack_init();
    
    #if MESH_FEATURE_GATT_ENABLED
        gap_params_init();
        conn_params_init();
    #endif
    
        mesh_init();
        
    //    lfclk_config();
        rtc_config();
        
    }
    
    static void start(void)
    {
        rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
    
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data    = static_auth_data,
                .prov_complete_cb = provisioning_complete_cb,
                .prov_device_identification_start_cb = device_identification_start_cb,
                .prov_device_identification_stop_cb = NULL,
                .prov_abort_cb = provisioning_aborted_cb,
                .p_device_uri = NULL
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
        
    
        const uint8_t *p_uuid = nrf_mesh_configure_device_uuid_get();
        UNUSED_VARIABLE(p_uuid);
        __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, "Device UUID ", p_uuid, NRF_MESH_UUID_SIZE);
    
        ERROR_CHECK(mesh_stack_start());
    
        hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
    }
    
    int main(void)
    {
        initialize();
        start();
    
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }
    

    Thank you

  • I'm quite lost on what work and what wouldn't work. 

    Please test with SDK v3.2 and start with unmodified example and add the RTC configuration to it and let me know at which step it stopped working. I suspect that it could be related to other bug and you may have the same issue even without the RTC configuration. 

    Please aware that when the softdevice is active the LFCLK is already started you don't really need to call lfclk_config. 

  • Hi Hung Bui,

    As you suggested I have implemented RTC with SDK v3.2, now I'm able to use use softdevice with RTC without above provisioning issue. 

     In here also I added below libraries to my project,

    • nrf_drv_clock.c
    • nrfx_clock.c
    • nrfx_rtc.c

    And used following settings to configure RTC and 

    • RTC_ENABLED 1
    • RTC2_ENABLED 1
    • NRFX_RTC_ENABLED 1
    • NRFX_RTC2_ENABLED 1 

    Below settings for configure internal RC

    • NRF_SDH_CLOCK_LF_SRC 0
    • NRF_SDH_CLOCK_LF_RC_CTIV 16 
    • NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    • NRF_SDH_CLOCK_LF_ACCURACY 1

    Thank for your to helping me to sort out this matter.

Related