micro second resolution timer for Sin PWM gen.

Sebastien
Hi,

I am trying to create a timer that execute code every 50micro seconds.
The goal is to generate a 60Hz PWM sin wave  (using the pwm io interface)

I am doing all this in QT and realized that Qtimer works only with ms and I
need us... so duno where I should move from there.

I don't know how to approach this problem..

any suggestion ?

Thanks, Sebastien

Juergen Beisert
Did you check first if your hardware is capable to hande interrupts at this
rate? I guess this interrupt rate will bring in 100 % load to your system.

Sebastien
That is exactly what I do not understand:

Not so long ago I was able to generate a 60Hz sin PWM on a 2Mhz Microchip
PIC.
I generated an interrupt every 50us so about 20khz and it worked quite
well.
I did it in assembly code.

Now that I have a much powerful system in my hand I am trying to do
everything with it. And as the processor clock is 400Mhz I am assuming this
is enough mips for that SPWM generation.
I am pretty sure that some assembly code would allow to do this , but as I
have linux and developed my code in QT, I was thinking of using the high
level software for the SPWM...

Maybe this should be done at a lower level programming but I really have no
clue on how to proceed as this is all new to me.


Thanks, Sebastien.

Juergen Beisert
Run your system in bare metall and this CPU is powerfull enough to do the
job. Run it with a full operating system (which makes use of the virtual
caches, memory management unit, protection and so on) and it is not.

Sebastien
that's a bummer.... This explains why we need a 10Ghz processor to do .doc
;)
Thanks for your answers!
Sebastien

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

fatbrain
Hi Muhammad ,
Could you please post Makefile for the timer driver and instructions as how
to compile the timer module, and also sample code as to how to use it from
user space application.


thanks
--fatbrain