TTC0 timer takes some time to start

0

Im triyng to develop a kernel module which have a triple timer counter 0 (TTC0) in zync microzed board. But it takes some time (nearly 10 to 15 seconds) to start. The timer is configured as give interrupts in ~250ms. Here is the sample code. In here I have set the clock setup register (0x01F) for set the prescaler, mode configuration register (0x022) for start the counter and set interval mode , interval value (424) and interrupt enable (0x01).

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/signal.h>

MODULE_LICENSE("GPL");

#define IRQ_NUM         42              // interrupt line
#define TIMER_BASE      0xF8001000

#define TIMER_SIZE      0x0000FFFF

#define LOAD_VAL        424     // address load value ~0.25 sec

#define TTC1_CLOCK_CONTROL              0xF8001000
#define TTC1_COUNTER_CONTROL            0xF800100C
#define TTC1_COUNTER_VALUE              0xF8001018
#define TTC1_INTERVAL_COUNTER_VALUE     0xF8001024
#define TTC1_INTERRUPT_REGISTER         0xF8001054
#define TTC1_INTERRUPT_ENABLE           0xF8001060

unsigned long *pTIMER_TTC_CLOCK_CONTROL;                // pointer to timer clock control register
unsigned long *pTIMER_TTC_COUNTER_CONTROL;              // pointer to timer counter control register
unsigned long *pTIMER_INTERVAL_VALUE;                   // pointer to timer Interval load register
unsigned long *pTIMER_COUNTER_VALUE;                    // pointer to timer Counter load register
unsigned long *pTIMER_INTERRUPT_ENABLE;                 // pointer to timer Interrupt enable register
unsigned long *pTIMER_INTERRUPT_REGISTER;               // pointer to timer Interrupt register load register

#define DEVICE_NAME "ttc"               // device name
#define TTC_MAJOR 22                    // device major number // 22
#define BUF_LEN 80                      // max buffer length
#define SUCCESS 0                       // success return value

//unsigned long *pSYSCALL_Virtual;      // base address

static int intcount;

static irqreturn_t irq_handler(int irq,void*dev_id);

// init module
static int __init mod_init(void)  
{
        unsigned long temp;
        printk(KERN_ERR "Init TTC module. \n");

        if (request_irq(IRQ_NUM,irq_handler,0x00, DEVICE_NAME, NULL))          //request timer interrupt
        {
                printk(KERN_ERR "Not Registered IRQ. \n");
                return -EBUSY;
        }
        printk(KERN_ERR "Registered IRQ. \n");

        pTIMER_TTC_CLOCK_CONTROL = ioremap_nocache(TTC1_CLOCK_CONTROL,0x4);             // map timer clk control register
        pTIMER_TTC_COUNTER_CONTROL = ioremap_nocache(TTC1_COUNTER_CONTROL,0x4);         // map timer counter control register
        pTIMER_COUNTER_VALUE = ioremap_nocache(TTC1_COUNTER_VALUE,0x4);                 // map timer count register
        pTIMER_INTERVAL_VALUE = ioremap_nocache(TTC1_INTERVAL_COUNTER_VALUE,0x4);       // map timer interval value register
        pTIMER_INTERRUPT_ENABLE = ioremap_nocache(TTC1_INTERRUPT_ENABLE,0x4);           // map timer interrupt control register
        pTIMER_INTERRUPT_REGISTER = ioremap_nocache(TTC1_INTERRUPT_REGISTER,0x4);       // map timer interrupt register
        iowrite32(LOAD_VAL, pTIMER_INTERVAL_VALUE);                                     // place load value in load register
        temp = ioread32(pTIMER_INTERVAL_VALUE);                                         // debug: read load value to check
        printk("Load value: %lu.\n",temp);                                              // debug: print the read load value

        ioread32(pTIMER_COUNTER_VALUE);

        iowrite32(0x00000022,pTIMER_TTC_COUNTER_CONTROL); // start the timer
        iowrite32(0x00000001,pTIMER_INTERRUPT_ENABLE);    // enable interrupts
        iowrite32(0x0000001F,pTIMER_TTC_CLOCK_CONTROL);   // set the pre-scale

                                                                // value,no load,enable IRQ,enable Timer
        intcount = 0;                                   // set interrupt count to 0, driver will unload on 100 interrupts

        return SUCCESS;
}

// exit module
static void __exit mod_exit(void)              
{
        iowrite32(0x00000023,pTIMER_TTC_COUNTER_CONTROL);

        iowrite32(0x00000000,pTIMER_INTERRUPT_ENABLE);
        iowrite32(0x00000000,pTIMER_TTC_CLOCK_CONTROL);

        iounmap(pTIMER_TTC_CLOCK_CONTROL);                              // unregister timer hardware
        iounmap(pTIMER_TTC_COUNTER_CONTROL);
        iounmap(pTIMER_COUNTER_VALUE);
        iounmap(pTIMER_INTERVAL_VALUE);
        iounmap(pTIMER_INTERRUPT_ENABLE);
        iounmap(pTIMER_INTERRUPT_REGISTER);
        free_irq(IRQ_NUM, NULL);                                        // unregister timer interrupt
        printk(KERN_ERR "Exit ttc Module. \n");                         // print unload message
}

static irqreturn_t irq_handler(int irq,void*dev_id)            
{      
        unsigned long temp;
        unsigned long timervalue;

        timervalue = ioread32(pTIMER_COUNTER_VALUE);                    // Read Timer/Counter Register
        printk( KERN_EMERG "Interrupt! Timer counter value : %lu Cycles and %d counts\n",(timervalue-LOAD_VAL), intcount);  // Display timer value

        temp = ioread32(pTIMER_INTERRUPT_REGISTER);                             // clear timer IRQ

        intcount++;
        if (intcount>=100){                                      // after 100 interrupts
                printk("100 interrupts have been registered.\nDisabling timer");// print timer status message
                //iowrite32(0x00000050,pTIMER_TCSR0);           //disable timer;
                iowrite32(0x00000023,pTIMER_TTC_COUNTER_CONTROL);

                iowrite32(0x00000000,pTIMER_INTERRUPT_ENABLE);
                iowrite32(0x00000000,pTIMER_TTC_CLOCK_CONTROL);
        }

        return IRQ_HANDLED;
}

module_init(mod_init);
module_exit(mod_exit);

MODULE_INFO(intree, "Y");

your help is appreciated.

linux
timer
kernel
zynq
asked on Stack Overflow Sep 27, 2019 by BLLGG Z27

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0