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

App Timer tutorial, nrf_drv_clock_lfclk_request

I am debugging a small program for the nRF52, which uses the App Timer and communicates over UART. I am trying to keep up with bug fixes, and so I'm using SDK 11.0.

The UART works fine, my program prints a greeting in the first few lines of main(). But I don't seem to be setting up timer interrupts correctly, since the printing that is supposed to occur at each timer tick (every 5 seconds), in my timer handler function, is not taking place.

In order to get my program to compile at all, I had to write the LFCLK request in my timer configuration function as follows:

nrf_drv_clock_lfclk_request(false);

I copied that from an example somewhere, I'm not sure exactly where.

However, the App Timer tutorial shows that nrf_drv_clock_lfclk_request takes NO arguments. The function definition that I'm seeing wants a pointer to a nrf_drv_clock_handler_item_t.

I have to wonder why this discrepancy exists. It might be because the tutorial isn't written for SDK 11.0, but I don't know for sure. I also wonder whether my code in fact fails to start the LFCLK.

I will post my complete program if it helps. I thought that I would start with the first discrepancy I found before dumping 100 lines of code to the forums. Thanks for your help.

Parents
  • Hey.

    Documentation of the clock driver is found here.

    The rtc example shows how to set up the rtc, as referenced by the APP_TIMER_INIT documentation:

    This module assumes that the LFCLK is already running. If it is not, the module will be non-functional, since the RTC will not run. If you do not use a SoftDevice, you must start the LFCLK manually. See the rtc_example's lfclk_config() function for an example of how to do this. If you use a SoftDevice, the LFCLK is started on SoftDevice init.

    Let me know if you need some code snippets

    -Anders

    UPDATE 7 April. Trying it out on PCA10040 (nRF52 DK)

    I did the following, which let me print something periodically with a app_timer. It was compiled with Keil 5. I am not sure if this will help you or not, but at least we know that this works with the Keil compiler.

    1: Start with the example project "uart" found in "nRF5_SDK_11\examples\peripheral".

    2: include app_timer and clock headers. (and add the files to the include paths)

    #include "app_timer.h"
    #include "nrf_drv_clock.h"
    

    3: define some timer variables

    #define APP_TIMER_PRESCALER             0                                           /**< Value of the RTC1 PRESCALER register. */
    #define APP_TIMER_OP_QUEUE_SIZE         4 
    

    4: Add the .c files to Keil (right click ->add existing files)

    5: Create a timer id

    APP_TIMER_DEF(periodic_print_id);
    

    6: Create clock setup and timer handler

    static void periodic_print(void * p_context){
        printf("\n Periodic print: \n\r");
    }
    
    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);
    }
    

    7: Edit main to initialize and start the timer task.

        lfclk_config();
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
        err_code = app_timer_create(&periodic_print_id, APP_TIMER_MODE_REPEATED, periodic_print);
        APP_ERROR_CHECK(err_code);
        err_code = app_timer_start(periodic_print_id, APP_TIMER_TICKS(500, APP_TIMER_PRESCALER),NULL);
        APP_ERROR_CHECK(err_code);
    
Reply
  • Hey.

    Documentation of the clock driver is found here.

    The rtc example shows how to set up the rtc, as referenced by the APP_TIMER_INIT documentation:

    This module assumes that the LFCLK is already running. If it is not, the module will be non-functional, since the RTC will not run. If you do not use a SoftDevice, you must start the LFCLK manually. See the rtc_example's lfclk_config() function for an example of how to do this. If you use a SoftDevice, the LFCLK is started on SoftDevice init.

    Let me know if you need some code snippets

    -Anders

    UPDATE 7 April. Trying it out on PCA10040 (nRF52 DK)

    I did the following, which let me print something periodically with a app_timer. It was compiled with Keil 5. I am not sure if this will help you or not, but at least we know that this works with the Keil compiler.

    1: Start with the example project "uart" found in "nRF5_SDK_11\examples\peripheral".

    2: include app_timer and clock headers. (and add the files to the include paths)

    #include "app_timer.h"
    #include "nrf_drv_clock.h"
    

    3: define some timer variables

    #define APP_TIMER_PRESCALER             0                                           /**< Value of the RTC1 PRESCALER register. */
    #define APP_TIMER_OP_QUEUE_SIZE         4 
    

    4: Add the .c files to Keil (right click ->add existing files)

    5: Create a timer id

    APP_TIMER_DEF(periodic_print_id);
    

    6: Create clock setup and timer handler

    static void periodic_print(void * p_context){
        printf("\n Periodic print: \n\r");
    }
    
    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);
    }
    

    7: Edit main to initialize and start the timer task.

        lfclk_config();
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
        err_code = app_timer_create(&periodic_print_id, APP_TIMER_MODE_REPEATED, periodic_print);
        APP_ERROR_CHECK(err_code);
        err_code = app_timer_start(periodic_print_id, APP_TIMER_TICKS(500, APP_TIMER_PRESCALER),NULL);
        APP_ERROR_CHECK(err_code);
    
Children
  • Thanks for your reply, Anders. I thought that the purpose of the App Timer was to provide a higher-level interface than the RTC, and to make using multiple timers easy (I will eventually need two)? Does my App Timer code still need to reference the lower-level RTC functions?

    In any case: the lfclk_config() in the SDK11 RTC example reads thus:

    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);
    

    My own code is nearly identical, the only difference is that I declare err_code on an earlier line. The App Timer tutorial shows nrf_drv_clock_lfclk_request being called with no arguments. Consistent with the SDK11 docs, that doesn't work for me. I get a compiler error because nrf_drv_clock_lfclk_request wants a pointer to a nrf_drv_clock_handler_item_t (NULL, or false, substitutes when you don't need a callback function).

  • Are you using the nRF52 Development kit, or a custom board? If DK, which version?

  • Hello again Anders, thanks for staying with me. I am using the nRF52 Preview Kit, PCA10036. My development environment is pure Linux, using GCC with the ARM toolchain.

    My code has every single line that the example you posted has, it's just organized a little differently. It still doesn't print the periodic message I want. I will try to copy your example and see what I get.

    I am working on several other programs for the PCA10036. I've noticed that the Makefiles changed between SDK 9.1 and SDK 11. There are a lot more compiler flag settings in the most recent version. I'm not sure what they all do. Perhaps my CFLAGS in the Makefile require some changes. Where are all of the CFLAGS settings documented? There are so many.

Related