cassemblyarmcortex-a8omap

setting up gptimer1 on omap4460


I'm writing bare metal code(no os) on omap4460 (cortex a9), and i do not succeed 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? Rony.


Solution

  • 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