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
micro second resolution timer for Sin PWM gen.
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.
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.
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.
that's a bummer.... This explains why we need a 10Ghz processor to do .doc ;) Thanks for your answers! Sebastien
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");
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