timer interrupt

whitebank
Hi there (i'm sorry because my question seems generously)

I'm writing a device driver on mini2440 to read encoder from motor, then
calculate the velocity. --> I need "timer interrupt".

But, i don't know clearly about timer interrupt on linux, I used to use
timer interrupt on Microcontroller (PIC16F84 and atmega8) to read encoder
of motor. Is there any kind of timer interrupt on Linux which is similar to
Microcontroller?? And if any, how could use it?

(i've heard that, timer interrupt programming on Linux is really hard, even
impossible???)

Nor
If you don't need too precise timers then a userspace application would be
more suitable for the purpose (depending on how the motor is connected to
the board).

About the kernel:
Some information about interrupt handling is available here:
http://www.linuxtopia.org/online_books/linux_kernel/linux_kernel_module_...

And delayed tasks:
http://www.linuxtopia.org/online_books/linux_kernel/linux_kernel_module_...

However the interrupt part is only needed if you're reconfiguring one of
the PWM timers (which is not recommended since it's not that easy and the
kernel might already be using it for other purposes).

The safe way is to simply queue a delayed task to run after N ms, and the
handler will do the reading part.

whitebank
thanks, i did it (even though i dont understand much)

Andy
See http://www.codeguru.com/forum/showthread.php?t=356101 for example!

Usama Masood
See the module

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>

#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/regs-timer.h>
#include <plat/regs-adc.h>

#define __TIMREG(name)  (*(volatile unsigned long *)(BaseAddr + name))
#define TIMCON      __TIMREG(S3C2410_TCON)  

#define DEVICE_NAME  "tim"

typedef struct {
  int delay;
} TIM_DEV;


static TIM_DEV TimDev;

int RUNNED = 0;
int test;


static irqreturn_t TimerINTHandler(int irq,void *TimDev)
{
  
  unsigned TimerINTControl;
  TimerINTControl = readl(S3C_TINT_CSTAT);
  
  RUNNED ++;
  
  TimerINTControl |= S3C_TINT_CSTAT_T2INT;
  writel(TimerINTControl, S3C_TINT_CSTAT); 

  return IRQ_HANDLED;
}

static ssize_t TimerRead(struct file *filp, char *buffer, size_t count,
loff_t *ppos)
{
  char str[20];
  size_t len;

  len = sprintf(str, "%d\n", RUNNED);
  copy_to_user(buffer, str, len);
  
    if (*ppos == 0) {
        *ppos+=len;
        return len;
    } else {
        return 0;
   }
}



static struct file_operations dev_fops = {
  owner:    THIS_MODULE,
  read:    TimerRead,  
};

static struct miscdevice misc = {
  .minor  = MISC_DYNAMIC_MINOR,
  .name  = DEVICE_NAME,
  .fops  = &dev_fops,
};

static int __init dev_init(void)
{
  int ret;
  unsigned TimerControl;
  unsigned TimerINTControl;
  unsigned TimerCNTB;
  unsigned TimerCMPB;
  
  RUNNED = 0;
  
  TimerControl = readl(S3C_TCON);
  TimerINTControl = readl(S3C_TINT_CSTAT);
  TimerCNTB = readl(S3C_TCNTB(2));
  TimerCMPB = readl(S3C_TCMPB(2));
  
  TimerCNTB = 0x0000100;
  TimerCMPB = 0x0000100;
  
  writel(TimerCNTB, S3C_TCNTB(2));
  writel(TimerCMPB, S3C_TCMPB(2));
  
  //TimerControl |= S3C_TCON_T2RELOAD;
  TimerControl |= S3C_TCON_T2MANUALUPD;
  TimerControl &= ~S3C_TCON_T2INVERT;
  //TimerControl |= S3C_TCON_T2START;
  
  TimerINTControl |= S3C_TINT_CSTAT_T2INTEN;
  
  writel(TimerControl, S3C_TCON);
  writel(TimerINTControl, S3C_TINT_CSTAT);
  
  
  TimerControl = readl(S3C_TCON);
  
  TimerControl |= S3C_TCON_T2RELOAD;
  TimerControl &= ~S3C_TCON_T2MANUALUPD; 
  TimerControl |= S3C_TCON_T2START;
  
  writel(TimerControl, S3C_TCON);

  ret = request_irq(IRQ_TIMER2, TimerINTHandler, IRQF_SHARED, DEVICE_NAME,
&TimDev);
  if (ret) {
    return ret;
  }

  ret = misc_register(&misc);

  printk (DEVICE_NAME"\tinitialized\n");
  return ret;
}

static void __exit dev_exit(void)
{
  free_irq(IRQ_TIMER2, &TimDev);
  misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Muhammad Usama Masood");

luiz
Usama Masood, how I use your code? I don't need compiler this code.