timers and interrupts without OS problem

michael
Hi,
I am developing program with Leds (binary counter on leds) and timer with
interrupt, but it doesn't work.
Idea is when the timer counted one second then should request interrupt.
It's mean that Led must be on. I am writting in Eclipse.
I don't know what I do wrong.
This is my C code:

#include "2440addr.h"
#include "Def.h"


void init_timer (void);
static void timer_handler (void) __attribute__ ((interrupt("IRQ")));
void binary_leds (void);

U16 i=0,tmp=0;   /* temporary needed to binary counter*/

int main (void)
{

   init_timer();
   while (1);

return 0;
}

void init_timer (void)
{
   pISR_TIMER2   = (U32)timer_handler;   /* address of interrupt service
routine*/
   pISR_IRQ = (U32)timer_handler;
   ClearPending(BIT_TIMER2);   /* interrupt timer2 requested*/
   EnableIrq(BIT_TIMER2);   /* */


   rGPBCON &= 0xffffcc;   /* mask GPBCON and clear 5th and 4th bits and
buzzer off*/
   rGPBCON |= 0x000020;   /* set 5th and  4th bits at 2 binary value,
                     //it's mean that GPB2 is configured as TOUT2*/

   rGPBCON&=0xfc03ff; /*Port GPB is configured for leds
(GPB5,GPB6,GPB7,GPB8-output)*/
   rGPBCON|=0x0015400;

   rGPBDAT|=0x1e0;      /*LEDs are cleared*/

   rTCFG0 |= 0x0ff00;      /* prescaler configured as 255 value*/
   rTCFG1 |= 0x00300;      /* divider configured as 16 value */

   /******************* timer on ***************************/
   rTCMPB2 = 0;      /* set comparator at 0*/
   rTCNTB2 = 12207;      /* set counter to count 1 sec */
   rTCON = 0x00a000;   /* Auto-reload is on, manual update bit is set*/
   rTCON = 0x009000;   /* manual update bit is cleared, start bit is set */

}

static void timer_handler (void)
{
   ClearPending(BIT_TIMER2);
   binary_leds();
}

void binary_leds (void)
{
   tmp++;
         i=tmp;
         i = (~i)<<5;
         rGPBDAT|=0x1e0;
         rGPBDAT &= i;
}

Could You tell me what is wrong or what there isn't?
thank you for help

kppp
dear sir,
even i tried the same timer interrupt. my code in posted under s3c2440a and
i m also facing the problem of not starting hte inteerupt. my timer is
working fine. but it is unable to generate the interrupt. if you have got
clue then pls let me know.
thank you
regards

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");

Shahid Riaz
hi 
I am using timer4 as 1 mili sec timer for my applications. because I need
software timer and timer 4 dont have TOUT. So it run very perfectly. The
only problem with the timers are their initializing and timer value
setting, for what you have to understand the whole clock generation system
and PLL settings. 
This is very simple code. you can get delay upto 5.2 mili sec by dividing
the clock. This timer can be used as the integral part of any OS.

Keep enjoy.

Best regards.


#include "2440addr.h"
#include "Def.h"


int MiliSecCount


void Init_timer4(void);
void __irq Timer4_ISR(void);
void Led_Routine(void);


int main (void)
{

  Init_timer4;

  while(1);


}

void Init_timer4(void){

  rTCON &= 0xff8fffff;  //clear manual update bit, stop Timer1
  rTCFG0 &= 0xffff00ff;   //clear Timer 2,3 & 4 prescaler 1
  rTCFG0 |= 0xf00;        //set prescaler = 15+1 = 16  
  rTCFG1 &= 0xfff0ffff;   //set Timer4 1/2 Mux
  rTCFG1 |= 0x10000;      //set Timer4 MUX 1/4    
   rTCNTB4 = (PCLK / (4*15*1000)) - 1; // 1 mSec Time value    
  rTCON |= 0x200000;      //   manual updata 
  rTCON &= 0xff8fffff;    // down the manual update flag
  rTCON |= 0x500000;  // interval mode auto reload and start

  ClearPending(BIT_TIMER4);
  pISR_TIMER4= (U32) Timer4_ISR;
  EnableIrq(BIT_TIMER4);  
}


void __irq Timer4_ISR(void)
{

  if(++MiliSecCount==1000){
    MiliSec10Count = 0;
    
  }
}

void Led_Routine(void){


  //  what function do u want;



}