[ nRF52833] Duplicate definition of TIMER1_IRQHandler

Hello Experts,

I my main.c,  I have defined my own TIMER1_IRQHandler() and when I build the code I get the error 

Rebuilding 'timer_pca10100' from solution 'timer_pca10100' in configuration 'Debug'

Linking 'timer_pca10100.elf'
in function `TIMER1_IRQHandler':
/home/lenovo/projects/nordic/SDK/nRF5SDK160098a08e2/examples/peripheral/timer_running/main.c:13: multiple definition of `TIMER1_IRQHandler'; Output/Debug/Obj/timer_pca10100/nrfx_timer.o:/home/lenovo/projects/nordic/SDK/nRF5SDK160098a08e2/modules/nrfx/drivers/src/nrfx_timer.c:300: first defined here
Build failed, exit status 0x1
Build failed

In the file nrfx_timer.c there is definition of nrfx_timer_1_irq_handler() that is defined to TIMER1_IRQHandler in nrfx_irqs_nrf52833.h

modules/nrfx/soc/nrfx_irqs_nrf52833.h:99:#define nrfx_timer_1_irq_handler    TIMER1_IRQHandler

Do not understand how exactly to resolve this issue ? 

Thanks,

Best Regards

AbhiAsh

Parents
  • It looks like you are trying to implement your own timer1 IRQ handler and older deprecated nRF5SDK from the looks of it. Correct me if that assumption is wrong. But if the assumption is correct, we strongly recommend you to use newer nrF Connect SDK instead of the maintenance only nrF5SDK

    The nrfx_timer driver already includes a definition for TIMER1_IRQHandler. This is achieved through a mapping in nrfx_irqs_nrf52833.h, where nrfx_timer_1_irq_handler is defined as TIMER1_IRQHandler. Since you are defining your own version of TIMER1_IRQHandler in your code, the linker detects two competing definitions and throws an error. The nrfx_timer driver automatically sets up its own interrupt handler to manage timer events if the driver is enabled. Therefore, if you try to define your own ISR (TIMER1_IRQHandler), the linker sees it as a conflict

    There are few ways that you can fix this

    1)  If you must use your own TIMER1_IRQHandler, you need to prevent the nrfx_timer from using the same interrupt. To do this:

    • Disable the use of TIMER1 in the nrfx_timer configuration:
      #define NRFX_TIMER1_ENABLED 0
    • Define your own TIMER1_IRQHandler after ensuring that the nrfx_timer driver is not using it.

    2) If you need the timer functionality provided by the nrfx_timer driver, consider using its API instead of manually implementing your own TIMER1_IRQHandler. You can set up a timer instance and use the nrfx_timer's event handler mechanism to manage timer events.

    • You would initialize the timer like this:
      nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG; 
      nrfx_timer_init(&TIMER_INSTANCE, &timer_cfg, timer_event_handler);
      Implement your functionality within timer_event_handler instead of writing a custom ISR. The nrfx_timer driver will handle the interrupt for you and call your event handler function

    3) If you do not need the functionality provided by the nrfx_timer driver, you can disable it in your project's configuration file (usually sdk_config.h):

             
    #define NRFX_TIMER_ENABLED 0
    • Disabling the nrfx_timer driver will prevent it from defining the TIMER1_IRQHandler, allowing your custom handler to be used without conflict.
  • Hello Susheel,

    Thanks a lot for your elaborate reply.

    Yes I using nRF5 SDK version 16. Unfortunately, need to continue on this as development is on legacy product.

    I am implementing a free running timer with 1ms tick using 32MHz external crystal osc.

    and using the below given code as I need to explicity change the PreScaler and other settings.

    Nowhere in the solution space or examples did I find this so doing manually without API

    Now I am confused where to adjust the assignment of the ISR or IRQ handler ? i.e. below two lines

    as nrfx_timer_config_t does not have prescaler setting.

    nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
    nrfx_timer_init(&TIMER_INSTANCE, &timer_cfg, timer_event_handler);

    -----------------------------------------------------------------------------------------------

    I would need to use Timer1 for obvious reasons.

    // Timer1 Initialization
    void timer1_init(void)
    {
    // Stop TIMER1 before configuring it
    NRF_TIMER1->TASKS_STOP = 1;

    // Set TIMER1 in 32-bit mode
    NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;

    // Set prescaler so that TIMER1 runs at 1 MHz (32 MHz / 2^4 = 1 MHz)
    NRF_TIMER1->PRESCALER = 4

    // Set compare value for 1 ms tick (1000 ticks at 1 MHz = 1 ms)
    NRF_TIMER1->CC[0] = 1000

    // Enable interrupt for COMPARE[0]
    NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;

    // Enable TIMER1 interrupt in the NVIC
    NVIC_EnableIRQ(TIMER1_IRQn);

    // Clear and start TIMER1
    NRF_TIMER1->TASKS_CLEAR = 1;
    NRF_TIMER1->TASKS_START = 1;
    }

    Thanks,

    AbhiAsh

  • Hi,

    Now I am trying out the below code using API

    // Initialize Timer 1 to create a free-running timer
    void timer1_init(void)
    {
    // Stop Timer 1 before configuring
    nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_STOP);

    // Set the timer mode to Timer mode (not counter mode)
    nrf_timer_mode_set(NRF_TIMER1, NRF_TIMER_MODE_TIMER);

    // Set the bit width to 32-bit for a larger range of counts
    nrf_timer_bit_width_set(NRF_TIMER1, NRF_TIMER_BIT_WIDTH_32);

    // Set the timer frequency (32 MHz clock divided by 2 = 16 MHz)
    nrf_timer_frequency_set(NRF_TIMER1, NRF_TIMER_FREQ_16MHz);

    // Clear the timer and start it in free-running mode
    nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_CLEAR);
    nrf_timer_task_trigger(NRF_TIMER1, NRF_TIMER_TASK_START);
    }

    Let me know your comments

    Thanks,

    AbhiAsh

  • Using nrfx hal API directly should be OK, Then you do not have to implement your own IRQ handler and let the nrfx handle it for you

Reply Children
No Data
Related