nrf52840 Timer0 not work

Hello. I am a beginner and I have a nrf52840 Dongle board. I tried to use the interrupt from TIMER0. I defined the timer and it works correctly, but when I enable the interrupt "NVIC_EnableIRQ(TIMER0_IRQn)", it seems that the program jumps to an empty area. What I found from using the timer did not help me. Could you advise me? I am uploading a test project.
Best regards
Jaroslav Štrba.

Parents Reply Children
  • Hello. I solved the problem with the timer interrupt. The problem was solved when I used IRQ_DIRECT_CONNECT(TIMER1_IRQn, IRQ_PRIO_LOWEST,TIMER1_IRQHandler, 0); irq_enable(TIMER1_IRQn); The example is for TIMER1 but it is also tested for TIMER0.  I am attaching "main.c".

    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    
    #define PORT0_NI DT_NODELABEL(gpio0)
    #define PORT1_NI DT_NODELABEL(gpio1)
    const struct  device *port0 = DEVICE_DT_GET(PORT0_NI);
    const struct  device *port1 = DEVICE_DT_GET(PORT1_NI);
    
    #define LED_G 6
    #define Out_1ms 10
    
    bool F_500ms;
    uint16_t Count_500ms;
    
    // ôbsluha timer1 - dosiahlo porovnanie - 1 ms - 1kHz
    void Timer1_1ms(void)
    {
            NRF_TIMER1->EVENTS_COMPARE[0]=0;
            if(++Count_500ms>499)   // pol sekundy
            {
                    Count_500ms=0;
                    F_500ms=1;
                    // prečítanie Timer4
                    NRF_TIMER1->TASKS_CAPTURE[1]=1;
                    Count_500ms=NRF_TIMER1->CC[1];
                    printf("Timer1 = %d\n\r", Count_500ms);
    
                    gpio_pin_toggle(port0,LED_G);
            }
    
    }
    
    // 1kHz = 1ms
    void TIMER1_IRQHandler(void)
    {
            if(NRF_TIMER1->EVENTS_COMPARE[0] != 0)
            {
                 NRF_TIMER1->EVENTS_COMPARE[0]=0;  
                 
                 Timer1_1ms();
            }
    
            gpio_pin_toggle(port1, Out_1ms);       
    }
    
    void Start_Timer1(void)
    {
            NRF_TIMER1->TASKS_CLEAR = 1;
            NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
            NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled;       // automaticky vynuluje TIMER4 po compare ???
            
            NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
            NRF_TIMER1->PRESCALER = 1;   // nie je možné použiť v Counter mode
            NRF_TIMER1->CC[0] = 8000;       // set value compare register 0 = 16MHz / 8000 / 2 = 1000 = 1kHz
            // NRF_TIMER1->CC[1] = 1000;       // set value compare register 1 - celkovo sú 5 alebo 6
            
            NRF_TIMER1->INTENSET = (TIMER_INTENCLR_COMPARE0_Enabled << TIMER_INTENCLR_COMPARE0_Pos);        // enable interrupt compare CC[0]
    
            // enable interrupt compare CC[0] + CC[1]
            // NRF_TIMER1->INTENSET = (TIMER_INTENCLR_COMPARE0_Enabled << TIMER_INTENCLR_COMPARE0_Pos) | (TIMER_INTENCLR_COMPARE1_Enabled << TIMER_INTENCLR_COMPARE1_Pos); 
            IRQ_DIRECT_CONNECT(TIMER1_IRQn, IRQ_PRIO_LOWEST, TIMER1_IRQHandler, 0);
            irq_enable(TIMER1_IRQn);
            // NVIC_EnableIRQ(TIMER1_IRQn);  // nastavenie prerušenia - nefunguje
            NRF_TIMER1->TASKS_START=1;
    }
    
    int main(void)
    {
            gpio_pin_configure(port0, 6, GPIO_OUTPUT);
            gpio_pin_configure(port1, Out_1ms, GPIO_OUTPUT);
            gpio_pin_set(port0, LED_G, 0);
            gpio_pin_set(port1, Out_1ms, 0);
            
            Start_Timer1();
     
            while(1)
            {
    
            }
    
            return 0;
    }
    
    IRQ_DIRECT_CONNECT(TIMER1_IRQn, IRQ_PRIO_LOWEST, TIMER1_IRQHandler, 0);
    irq_enable(TIMER1_IRQn);
    

  • Thanks for informing this and making this thread compelete and useful to others. 

Related