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

"app_timer","pwm_library","nrf_drv_timer "can not coexist

"app_timer"

static void timers_init(void)
{
    ret_code_t err_code;

    // Initialize timer module.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
    
    err_code = app_timer_create(&m_heart_rate_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                heart_rate_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);
}

"pwm_library"

APP_PWM_INSTANCE(PWM1,1);                   // Create the instance "PWM1" using TIMER1.

void init_pwm(void)
{
    ret_code_t err_code;

    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5, PWM_DRIVER_PIN);

    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;

    err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
    APP_ERROR_CHECK(err_code);    
}

"nrf_drv_timer "

const nrf_drv_timer_t MYTIMER_2 = NRF_DRV_TIMER_INSTANCE(2);

void init_my_timer(void)
{
    ret_code_t err_code;
    uint32_t time_us = 60, time_ticks;
    
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&MYTIMER_2, &timer_cfg, mytimer_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_us_to_ticks(&MYTIMER_2, time_us);

    nrf_drv_timer_extended_compare(
         &MYTIMER_2, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
        
}

main

int main(void)
{
    bool erase_bonds = false;
    log_init();
    // Initialize.
    timers_init();
     
    ble_stack_init();

    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();

    conn_params_init();
    peer_manager_init();

    // Start execution.
    NRF_LOG_INFO("Heart Rate Sensor example started.");
    application_timers_start();
    advertising_start(erase_bonds);

    init_my_timer();//------------------1
    init_pwm();//-----------------------2

    
    // Enter main loop.
    for (;;)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            power_manage();
        }
    }
}

nRF5_SDK_14.0.0_3bcc1f7

as above hree pieces of code, if put them together with softdevice, i can get fault when run to "main()-------init_pwm();//-----------------------2"

debug "init_pwm();" in function :

ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config,
app_pwm_callback_t p_ready_callback)

{

    ............................
    
    ............................
    
    ............................
    
    // Initialize timer:
    nrf_timer_frequency_t timer_freq = pwm_calculate_timer_frequency(p_config->period_us);
    nrf_drv_timer_config_t timer_cfg = {
    .frequency = timer_freq,
    .mode = NRF_TIMER_MODE_TIMER,
    .bit_width = NRF_TIMER_BIT_WIDTH_16,
    .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
    .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id
    };
    err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg,
    pwm_ready_tick);//---------------------------3
    if (err_code != NRF_SUCCESS)
    {
        pwm_dealloc(p_instance);
        return err_code;
    }

............................

............................

............................
}

"nrf_drv_timer_init" return "NRF_ERROR_INVALID_STATE".

How do they conflict with each other?

  • Hi,

    Have you made sure to enable both TIMER1 and TIMER2 in your sdk_config.h file?

    // <q> TIMER1_ENABLED  - Enable TIMER1 instance
    
    #ifndef TIMER1_ENABLED
    #define TIMER1_ENABLED 1
    #endif
    
    // <q> TIMER2_ENABLED  - Enable TIMER2 instance
    
    #ifndef TIMER2_ENABLED
    #define TIMER2_ENABLED 1
    #endif

    If this does not work, can you upload your project for us to reproduce the issue?

    Best regards,
    Jørgen

  • yes yes,you are right,i forget that. but, why didn't keil give errors?

  • I think this is caused by how the timer instances are defined in the driver. In nrf_drv_timer.h in SDK 14.0.0, the instances are all defined, and the instance number is assigned depending on the previous index and the enable config. If the timer is not enabled in the config, it will receive the same index as the previously enabled timer.

    #define TIMER0_INSTANCE_INDEX 0
    #define TIMER1_INSTANCE_INDEX TIMER0_INSTANCE_INDEX+TIMER0_ENABLED
    #define TIMER2_INSTANCE_INDEX TIMER1_INSTANCE_INDEX+TIMER1_ENABLED
    #define TIMER3_INSTANCE_INDEX TIMER2_INSTANCE_INDEX+TIMER2_ENABLED
    #define TIMER4_INSTANCE_INDEX TIMER3_INSTANCE_INDEX+TIMER3_ENABLED

    In SDK 15.x.0, with the introduction of NRFX driver, the instance is only defined if the timer is enabled, generating a compile error when you try to use the timer:

    enum {
    #if NRFX_CHECK(NRFX_TIMER0_ENABLED)
        NRFX_TIMER0_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER1_ENABLED)
        NRFX_TIMER1_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER2_ENABLED)
        NRFX_TIMER2_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER3_ENABLED)
        NRFX_TIMER3_INST_IDX,
    #endif
    #if NRFX_CHECK(NRFX_TIMER4_ENABLED)
        NRFX_TIMER4_INST_IDX,
    #endif
        NRFX_TIMER_ENABLED_COUNT
    };

    Luckily the state checking in the code will provide you with an error, preventing the driver for running both libraries on the same timer. That would cause unpredictable behavior.

Related