This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Double timer overflow interrupts

Hello,


I am using the GP timers on DM8168 to toggle a GPIO output in a given pattern (IR signal).

I have written a kernel module to do this, but have one remaining issue.

Sometimes the interrupt routine is being called TWICE per timer overflow interrupt.  I suspect this might be because the INT clear write has not happened by the time I exit the interrupt routine, thus it fires again immediately.

I have tried reading back the interrupt enable register in the IRQ, but this didn't help.

The hw pointer is declared using ioremap_nocache, so it shouldn't be cached. 

Any ideas?

BTW, the dmtimer routines do NOT work properly on dm8168.  Because of this, I am controlling the HW regs directly.

Code:

static irqreturn_t timer_irq_handler(int irq, void *dev_id)
{

        int ret;
        // reset the timer interrupt status
        //omap_dm_timer_write_status(timer_ptr, OMAP_TIMER_INT_OVERFLOW);
        //omap_dm_timer_read_status(timer_ptr); // YES, you really need to do this 'wasteful' read
        vsir_timer1[0x28>>2]=0x2;
        ret = vsir_timer1[0x28>>2];
        if (ret != 0){
                // repeat clear
                vsir_timer1[0x28>>2]=0x2;
        }
        //omap_writew(0x2, vsir_timer_base+0x28);
        //ret = omap_readw(vsir_timer_base+0x28);

        //printk("TIMER FIRED idx:%d cnt:%d",vsir_index,vsir_count);

        // set GPIO
        //    use set/clear registers
        //      GPIO0 set 0x48032194
        //      GPIO0 clear 0x48032190
        //    based on output variable
        if (((vsir_count%2)==0)&&((vsir_index%2)==0)){
                //gpio_set_value(outp,1);
                //writel(outp, vsir_gpio + 0x4);
                vsir_gpio[(0x194)>>2] = outp;
                //omap_writew(outp, GPIO_BASE);
        }else{
                //gpio_set_value(outp,0);
                vsir_gpio[(0x190)>>2] = outp;
                //omap_writew(outp, GPIO_BASE + 4);
        }
      // inc timer count
        vsir_count -= 1;
        if (vsir_count <=0){

                // get next sequence
                vsir_index++;
                if (vsir_index < time_max){
                        vsir_count = time_arr[vsir_index];
                }else if ((vsir_repeat>1)){
                        // restart
                        vsir_index=0;
                        vsir_count = time_arr[vsir_index];
                        if (vsir_repeat<999){vsir_repeat--;}
                }else{
                        vsir_stop_timers();
                }
        }

        // tell the kernel it's handled
        return IRQ_HANDLED;
}



  • James,

    Which GP timer you are using? At which line of your code you are clearing the timer interrupt? Which register you are using to clear the overflow interrupt, IRQSTATUS or IRQSTATUS_CLR?

    See if the below links will be in help:

    http://processors.wiki.ti.com/index.php/TI81xx_PSP_Porting_Guide#Using_Hardware_Timers_from_Kernel_Module.2FDriver
    http://processors.wiki.ti.com/index.php/Avoiding_Double_Interrupts_with_the_GPIO_Peripheral
    http://processors.wiki.ti.com/index.php/Configuring_GPIO_Interrupts

    http://e2e.ti.com/support/embedded/tirtos/f/355/t/150811
    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/186165

    Regards,
    Pavel
  • Hi Pavel,

    My IRQ code is posting above. You can see I clear the interrupt on the first line of the routine (and then read it back, hoping that would force it to wait until it clears OCP). I have also used the writeb/readb functions instead of the ioremaped pointers, but it makes no difference.

    From the links you sent,
    http://e2e.ti.com/support/embedded/tirtos/f/355/t/150811
    this one references an error with spurious interrupts on timers 3 and 7.
    I am using timer3.

    That page links to another to describe the issue,
    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/int-dm81x/f/518/p/112465/400989.aspx#400989
    However, I get "you do not have permissions" to view that link.

    Could you repost this information since this is likely the cause of this issue?
  • James,

    Are you using DM816x EZSDK 5.05.02.00? Or DVR RDK?

    James Michael said:
    That page links to another to describe the issue,
    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/int-dm81x/f/518/p/112465/400989.aspx#400989
    However, I get "you do not have permissions" to view that link.

    Could you repost this information since this is likely the cause of this issue?

    This thread is for GPTimer #3 seems to count faster than #1, #4 & #5. Using GPTimer #3 with BIOS causes the BIOS Clock module to tick twice as fast as expected. Setting the tick period to 1000 ms (which is the default) results in ~57,000 ticks in 30s, which suggests that the timer is actually ticking ~twice as fast as it should.

    Can you try with using other timers (other than 3 and 7)?

    This internal thread points to this external thread:

    Regards,
    Pavel

  • See also if the below pointers will be in help:


    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/270632
    http://e2e.ti.com/support/embedded/linux/f/354/t/102044
    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/343881
    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/100/t/108733
    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/363612
    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/217024

    arch/arm/mach-omap2/timer-gp.c
    arch/arm/mach-davinci/time.c



    BR
    Pavel