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.

setting up gptimer1 on omap4460

Hi,

I'm writing bare metal code(no os) on omap4460 (cortex a9), and i am unable to set up correctly gptimer1.

This is my code ( by following the OMAP4460 TRM)

/* for forwarding pending interrupts from distributor
      to Cpu interfaces */
    *(volatile unsigned int *)(GICD_BASE + GICD_CTLR ) |= 0x00000001;

    /* signaling interrupt by the cpu interface to the connected processor*/
    *(volatile unsigned int *)(GICC_BASE + GICC_CTLR ) |= 0x00000001;

    /* position the timer1 handler */
    irq_table_function[GPT1_IRQ] = timer1handler;

    /* clocks timer1 block */
    *(volatile unsigned int *)CM_WKUP_CLKSTCTRL |= 0x00000003;
    *(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x01000000;
	*(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x00000002;

	/* enable GPTimer1 functional and interface blocks */
	*(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000300;

    /* capture interrupt enable */
    *(volatile unsigned int *)GPT_TIER |= 0x00000004;
    /* enable autoreload */
    *(volatile unsigned int *)GPT_TCLR |= 0x00000002;
    /* prescaler equal to zero */
    *(volatile unsigned int *)GPT_TCLR &= ~0x0000003C;
    /* positive increment value */
    *(volatile unsigned int *)GPT_TPIR = 232000;
    /* negative increment value */
    *(volatile int *)GPT_TNIR = -768000;
    /* load value */
    *(volatile unsigned int *)GPT_TLDR = 0xFFFFFFE0;

    /* enable timer1 */
    *(volatile unsigned int *)GPT_TIER |= 0x00000001;

When i run the code, i never go to my interrupt vector table, my interrupt vector table is correctly set, since "svc 0" works.

I don't even see the timer counter running.


Please any idea, on what i'm missing?

Thanks,

Rony.

  • Move this post to the proper E2E forum section.

    BR

    Tsvetolin Shulev

  • Hello Rony,

    The correct sequence to initialize a GP timer (in your case 1ms GPTimer 1) you should do the following:

    1. Configure Cortex A9 interrupt controller

    2. Configure PRCM registers

    Looking at your code, you've already done that.

    Next you need to:

    1. Perform software reset:
     GPT1MS_TIOCP_CFG[0] SOFTRESET = 0x1

     Wait until reset release GPT1MS_TIOCP_CFG[0] SOFTRESET = 0x0

    2. Apply your specific timer settings

      As per your code:
       - enable GPTimer1 functional and interface blocks

       - capture interrupt enable

       - enable autoreload

       - set prescaler

       - Configure TPIR/TNIR & load value

     3. After all that you need to start the timer.  Currently you are doing that with:
     /* enable timer1 */

     *(volatile unsigned int *)GPT_TIER |= 0x00000001;

     Which actually enables the MATCH Interrupt event.

    Instead you should set the ST bit, which starts the timer:
    GPT_TCLR[0] ST = 0x1   //start the timer

    Best Regards,

    Yordan

  • Hi Yordan,

    Thanks for your response, i have modify my initialization code for gptimer1 (1ms).

    But now i see two things

    when i run the initialization step by step with a jtag probe, nothing happen after the initialization of the timer, i don't see timer counter running, and i don't go to my vector table.

    When i just run the code (no step by step), i got an abort, i reach my interrupt vector table at the abort entry.

    The link register doesn't give me a correct address instruction from where i got the abort. (After the Initialization of the timer, i do nothing, just an inifintite loop to see if i jump to my vector table)

    This is my new code

    unsigned int waitingtime = 0;
    
    	/* 1. clocks timer1 block */
    	*(volatile unsigned int *)CM_WKUP_CLKSTCTRL |= 0x00000003;
    	*(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x01000000;
    	*(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x00000002;
    
    	/* 2. setting the pad muxing in control module */
    	*(volatile unsigned int *)CONTROL_WKUP_PAD0_FREF_CLK4_OUT_PAD1_SYS_32K |= 0x40180000;
    
    	/* enable for forwarding pending interrupts from distributor
          to Cpu interfaces */
        *(volatile unsigned int *)(GICD_BASE + GICD_CTLR ) |= 0x00000003;
    
        /*enable signaling interrupt by the cpu interface to the connected processor*/
        *(volatile unsigned int *)(GICC_BASE + GICC_CTLR ) |= 0x00000003;
    
        /* position the timer1 handler */
        irq_table_function[GPT1_IRQ] = timer1handler;
    
        /* software reset */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000002;
    
        /* wait until reset release */
        while( (*(volatile unsigned int *)GPT1MS_TIOCP_CFG & 0x00000002) != 0)
        	waitingtime++;
    
        /* idle mode equals to smart-idle */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000010;
    
        /* Functional clock is maintained during wake-up period */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000300;
    
    	/* Wake-up line assertion enabled in smart-idle mode */
    	*(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000004;
    
    	/* Enable wake-up interrupt events */
    	*(volatile unsigned int *)GPT_TWER |= 0x00000007;
    
    	/* Posted mode active */
    	*(volatile unsigned int *)GPT_TSICR |= 0x00000004;
    
    	/* enable autoreload */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000002;
    
    	/* enable prescaler */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000020;
    
    	/* Overflow interrupt enable */
    	*(volatile unsigned int *)GPT_TIER |= 0x00000002;
    
    	/* Load timer counter value */
    	*(volatile unsigned int *)GPT_TCRR = 0xFFFFFFE0;
    
    	/* load value */
    	*(volatile unsigned int *)GPT_TLDR = 0xFFFFFFE0;
    
    	/* positive increment value */
    	*(volatile unsigned int *)GPT_TPIR = 232000;
    	/* negative increment value */
    	*(volatile int *)GPT_TNIR = -768000;
    
    	/* enable timer1 */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000001;

    Any idea?

    Best regards,

    Rony.

  • Rony, 

    What I can suggest is:

    Timer1 is not outputted on device pad, so I think it is safe to skip step 2 in your code (CTRL_MODULE configuration):
    /* 2. setting the pad muxing in control module */

    You can leave the default values of this register.

    After that could you just try to initialize the module following & configure timer1 to work in timer mode (this is a basic timer initialization, just for test), follow the steps given in: 
    Table 22-13. GP Timer Module Global Initialization
    And

    Table 22-14. GP Timer Mode Configuration

    Try changing the posted/nonposted mode configuration GPT_TSICR[2] POSTED. Programming model given in OMAP4 TRM is validated and should work fine. 

    Let me know the results of your test.

    Best Regards,

    Yordan

  • Hi ,

    If u are using thease configuration in kernel make sure GPTIMER1 is not uses by other module.That creates data abort.In pandaboard GPTIMER1 is using by DUCATI module, make sure u disabled this before configure GPTIMER1 for urself.

    Regards

    Vikram

  • Hi,

    i still don't succeed to correctly setting up the timer1 in omap4460, i have change the source clock from sys_32khz to sys_clk, then now i don't have an abort. When i set the EMUFREE bit (for emulation mode) of GPT1MS_TIOCP_CFG, i see the timer counter running, and that all (i don't go my vector table).

    i try to set up gptimer2 and i have exactly the same behavior as describe above for the gptimer1.

    My guess now it that there is something that i have to do but which is missing in the TRM (chap. 22.2.5.2.1.1 &  22.2.5.2.1.2) because i have followed exactly what is specified.

    Please do you have a snippet of code from which, the procedure specify in the TRM has been validated? i have looked in to u-boot code but the initialization of the timer has been done in many different files.

    This is my initialization code

    /* clocks timer1 block */
    	*(volatile unsigned int *)CM_WKUP_CLKSTCTRL |= 0x00000003;
    	*(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL &= ~0x01000000;
    	*(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x00000002;
    
    /* enables for forwarding pending interrupts from distributor
          to Cpu interfaces */
        *(volatile unsigned int *)(GICD_BASE + GICD_CTLR ) |= 0x00000003;
    
        /* enables signaling interrupt by the cpu interface to the connected processor*/
        *(volatile unsigned int *)(GICC_BASE + GICC_CTLR ) |= 0x00000003;
        /* software reset */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000002;
    
        /* wait until reset release */
        while( (*(volatile unsigned int *)GPT1MS_TIOCP_CFG & 0x00000002) != 0)
        	waitingtime++;
    
        /* idle mode equals to smart-idle */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000010;
    
        /*Functional clock is maintained during wake-up period */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000300;
    
    	/* Wake-up line assertion enabled in smart-idle mode */
    	*(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000004;
    
    	/* Enable wake-up interrupt events */
    	*(volatile unsigned int *)GPT_TWER |= 0x00000007;
    
    	/* Posted mode active */
    	*(volatile unsigned int *)GPT_TSICR |= 0x00000004;
    
    	/* enable autoreload */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000002;
    
    	/* set prescale clock timer value (PTV) to 1 */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000004;
    
    	/* enable prescaler */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000020;
    
    	/* Overflow interrupt enable */
    	*(volatile unsigned int *)GPT_TIER |= 0x00000007;
    
    	/* Load timer counter value */
    	*(volatile unsigned int *)GPT_TCRR = 0xFFFFFFE0;
    
    	/* load value */
    	*(volatile unsigned int *)GPT_TLDR = 0xFFFFFFE0;
    
    	/* positive increment value */
    	*(volatile unsigned int *)GPT_TPIR = 232000;
    	/* negative increment value */
    	*(volatile int *)GPT_TNIR = -768000;
    
    	/* enable timer1 */
    	*(volatile unsigned int *)GPT_TCLR |= 0x00000001;

    Best regards,

    Rony.

    PS: @Vikram, i have no os in my board

  • Hello Rony,

    I cannot share the validation source code with you, but the configuration is bellow; I've highlighted the differences with your configuration:

       /* clocks timer1 block */
        *(volatile unsigned int *)CM_WKUP_CLKSTCTRL |= 0x00000003;
        *(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x01000000;   //recommend to use posted rd/wr afterwords
        *(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x00000002;
        
       /* enables for forwarding pending interrupts from distributor
          to Cpu interfaces */
        *(volatile unsigned int *)(GICD_BASE + GICD_CTLR ) |= 0x00000003;
        /* enables signaling interrupt by the cpu interface to the connected processor*/
        *(volatile unsigned int *)(GICC_BASE + GICC_CTLR ) |= 0x00000003;
        /* software reset */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000002;

        /* RESET & Power settings*/
        /* wait until reset release */
        while( (*(volatile unsigned int *)GPT_TISTAT & 0x00000001) == 0)
            waitingtime++;
        /*GPT1MS_TIOCP_CFG [0]AUTOIDLE =0x0 : L4 clock free-running*/
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG &= ~(0x1 << 0)
        /* idle mode equals to no-idle mode */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000008;
        /*Functional clock is maintained during wake-up period */
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000300;
        /*NO Wake-up line assertion GPT1MS_TIOCP_CFG[2]ENAWAKEUP=0x0*/
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG &= ~(0x1 << 2) ;
        /*GPT1MS_TIOCP_CFG [5]EMUFREE =0x1 : Timer counter free running in emulation*/
        *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= (0x1 << 5)

        /* Enable wake-up interrupt events */
        *(volatile unsigned int *)GPT_TWER |= 0x00000007;
        /* Posted mode active */
        *(volatile unsigned int *)GPT_TSICR |= 0x00000004;
        /* enable autoreload */
        *(volatile unsigned int *)GPT_TCLR |= 0x00000002;
        
        /* set prescale clock timer value (PTV) to 1 */
        /* In posted mode try to set PREscaler =128
    and thus FCLK=38.4 MHz / 128 = 300 KHz << OCPCLK=38.4 / 4 = 9.6 MHz */
        *(volatile unsigned int *)GPT_TCLR |= 0x00000004;
        /* enable prescaler */
        *(volatile unsigned int *)GPT_TCLR |= 0x00000020;
        /* Overflow interrupt enable */
        *(volatile unsigned int *)GPT_TIER |= 0x00000007;

        /* Load timer counter value */
        /* Try to load lower value to TCRR. Try loading TCRR to start from 0xFD00 0000,
           thus the time interval to overflow is 4 sec, if prescaler is set to 128 */
        *(volatile unsigned int *)GPT_TCRR = 0xFFFFFFE0;

        /* load value */
        /*Also try to load lower value to TLDR i.e. 0xFFE0 0000 */
        *(volatile unsigned int *)GPT_TLDR = 0xFFFFFFE0;

        /* positive increment valueWrite -768000 in TNIR  -> FFF44800 */
        *(volatile unsigned int *)GPT_TPIR = 232000;
        /* negative increment value */
        *(volatile int *)GPT_TNIR = 0;

        /* enable timer1 */
        *(volatile unsigned int *)GPT_TCLR |= 0x00000001;

    Hope this helps.

    Best Regards,
    Yordan

  • Hi,

    i finally get the right initialization sequence, but forget to post back my code.

    This is how i initialize gptimer1, hope it may help

    /* clocks timer1 block */
    	    *(volatile unsigned int *)CM_WKUP_CLKSTCTRL |= 0x00000003;
    	    
    	    *(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL &= ~0x01000000;
    	    *(volatile unsigned int *)CM_WKUP_GPTIMER1_CLKCTRL |= 0x00000002;
    
    	   /* enables for forwarding pending interrupts from distributor
    	      to Cpu interfaces */
    	    *(volatile unsigned int *)(GICD_BASE + GICD_CTLR ) |= 0x00000003;
    
    	    /* set the priority of the interrupt */
    	    *(volatile unsigned int *)(GICD_BASE + GICD_IPRIORITYR_IRQ37 ) |= 0x00000200;
    	    /* set enable bit of IRQ37 */
    	    *(volatile unsigned int *)(GICD_BASE + GICD_ISENABLER37) |= 0x00000002;
    
    	    /* enables signaling interrupt by the cpu interface to the connected processor*/
    	    *(volatile unsigned int *)(GICC_BASE + GICC_CTLR ) |= 0x00000003;
    
    	    /* interrupt priority mask */
    	    *(volatile unsigned int *)(GICC_BASE + GICC_PMR ) = 0x00000080;
    
    	    /* forward the interrupt only to the processor which request the interrupt */
    	    *(volatile unsigned int *)(GICD_BASE + GICD_SGIR) |= 0x02000000;
    
    	    /* software reset */
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000002;
    
    	    /* RESET & Power settings*/
    	    /* wait until reset release */
    	    while( (*(volatile unsigned int *)GPT_TISTAT & 0x00000001) == 0)
    	        waitingtime++;
    	    /*GPT1MS_TIOCP_CFG [0]AUTOIDLE =0x0 : L4 clock free-running*/
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG &= ~(0x1 << 0);
    	    /* idle mode equals to no-idle mode */
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000008;
    	    /*Functional clock is maintained during wake-up period */
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= 0x00000300;
    	    /*NO Wake-up line assertion GPT1MS_TIOCP_CFG[2]ENAWAKEUP=0x0*/
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG &= ~(0x1 << 2) ;
    	    /*GPT1MS_TIOCP_CFG [5]EMUFREE =0x1 : Timer counter free running in emulation*/
    	    *(volatile unsigned int *)GPT1MS_TIOCP_CFG |= (0x1 << 5);
    
    	    /* Enable wake-up interrupt events */
    	    *(volatile unsigned int *)GPT_TWER |= 0x00000007;
    	    /* Posted mode active */
    	    *(volatile unsigned int *)GPT_TSICR |= 0x00000004;
    	    /* enable autoreload */
    	    *(volatile unsigned int *)GPT_TCLR |= 0x00000002;
    
    	    /* set prescale clock timer value (PTV) to 1 */
    	    /* set PREscaler =128
    	and thus FCLK=38.4 MHz / 128 = 300 KHz << OCPCLK=38.4 / 4 = 9.6 MHz */
    	    *(volatile unsigned int *)GPT_TCLR |= 0x00000018;
    	    /* enable prescaler */
    	    *(volatile unsigned int *)GPT_TCLR |= 0x00000020;
    	    /* Overflow interrupt enable */
    	    *(volatile unsigned int *)GPT_TIER |= 0x00000007;
    
    	    /* Load timer counter value */
    	    *(volatile unsigned int *)GPT_TCRR = 0xFD000000;
    
    	    /* load value */
    	    *(volatile unsigned int *)GPT_TLDR = 0xFFE00000;
    
    	   
    	    *(volatile unsigned int *)GPT_TPIR = 232000;
    	    /* negative increment value */
    	    *(volatile int *)GPT_TNIR = 0xFFF44800;
    
    	    /* we position the timer1 handler */
    	     irq_table_function[GPT1_IRQ] = timer1handler;
    
    	    /* enable timer1 */
    	    *(volatile unsigned int *)GPT_TCLR |= 0x00000001;

    Best regards,

    Rony