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

FreeRTOS with BLE and ADC (nrf52)

Hi,

I'm looking for an example which combines FreeRTOS, BLE and ADC on nrf52 board(10040). I'm able to have FreeRTOS with BLE, FreeRTOS with ADC but not everything together.

I have a conflict in using timer. FreeRTOS clock is launch via nrf_drv_clock_init(). BLE uses app_timer functionnalities. And ADC needs a timer for ppi configuration. I don't understand how the differents timers can coexist. On the differents example I found in github, there is no config with all these constants defined :

#define CLOCK_ENABLED  //Used for FreeRTOS clock
#define TIMER_ENABLED   //Used to enabled Timer 0
#define TIMER3_ENABLED //Timer used for adc (via ppi)

Is anyone has an example. It could help me to understand my misunderstanding of the way it works.

  • Your application cannot use RTC0 and TIMER0 if you are using BLE. Your application cannot use RTC1 if you are using FreeRTOS. Rest is normal clock rules, that you need to enable them before using any peripheral that needs it. Have you already started making your example and facing some conflicts? if so tell me exactly where and what conflict you are facing.

  • Thanks for the quick answer. I agree, I can't use TIMER0 + RTC0 if I use BLE. My bad! I updated my post. I defined TIMER3. This is what I did for now :

     - Initialize clock at the beginning of my program (before using any peripheral).
     - Initialize the saadc module with ppi :
    
    static const nrf_drv_timer_t   m_timer = NRF_DRV_TIMER_INSTANCE(3);
    
    ret_code_t err_code;
    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_timer_init(&m_timer, NULL, timer_handler);
    APP_ERROR_CHECK(err_code);
    
    /* setup m_timer for compare event every 400ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 1000);
    nrf_drv_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
    nrf_drv_timer_enable(&m_timer);
    
    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer, NRF_TIMER_CC_CHANNEL0);
    uint32_t saadc_sample_event_addr = nrf_drv_saadc_sample_task_get();
    
    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, timer_compare_event_addr, saadc_sample_event_addr);
    APP_ERROR_CHECK(err_code);
    
    error_code = nrf_drv_saadc_init(NULL, adc_handler);
    

    When I don't initialize adc, ble works fine. I don't understand in which part, adc configuration does conflicts. Is there a problem on my way to initialize ppi?

  • Hi, The code you posted have nothing to do with BLE. Your initialization looks fine (fine in a way that it does not seem to conflict BLE) . Did you see if any of the function returned error here? When you apply above code , what do you mean by saying BLE does not work. Does it get stuck somewhere? I suggest you to start the debugger and run the program and stop to see where the execution is. I am guessing that BLE API is not called at all in this scenario because i do not see any hardware conflicts in your code snippet above.

  • With debugger, I've no error return on nrf function. It's at the moment to launch schedule task in FreeRTOS that vPortStartFirstTask( void ) that a signal handler appeared which reset the board and re-init the app. I'm not able to give more details about what append next. My debbugger doesn't provide more details. The BLE API is not called because the code is in a freertos task.

    If i tried to call directly ble_function, an error appeared in the function softdevice_handler_init() when sd_softdevice_enable() is called. The error is 4097. I didn't found any trace of this error. Do you know where it came from?

Related