Lesson 5-PWM

Source: Internet
Author: User

In a twinkling of an eye, we have arrived at the last class-PWM-provided by the mini2440 manufacturer. The driver uses the timer 0 to generate the PWM pulse signal, and the gpb0 pin output is connected to the buzzer. The Code is as follows:

 

# Include <Linux/module. h>
# Include <Linux/kernel. h>
# Include <Linux/fs. h>
# Include <Linux/init. h>
# Include <Linux/delay. h>
# Include <Linux/poll. h>
# Include <Linux/interrupt. h>
# Include <Linux/gpio. h>

 

# Include <ASM/IRQ. h>
# Include <ASM/IO. h>
# Include <ASM/uaccess. h>
# Include <Mach/regs-gpio.h>
# Include <Mach/hardware. h>
# Include <plat/regs-timer.h>
# Include <Mach/regs-irq.h>
# Include <ASM/Mach/time. h>
# Include <Linux/CLK. h>
# Include <Linux/cdev. h>
# Include <Linux/device. h>
# Include <Linux/miscdevice. h>

 

# Define device_name "PWM" // device name

 

# Define pwm_ioctl_set_freq 1 // macro variable, used for the CMD variable of IOCTL
# Define pwm_ioctl_stop 0

 

Static struct semaphore lock; // defines the semaphore lock

 

/* Freq: pclk/50/16/65536 ~ Pclk/50/16
* If pclk = 50 MHz, freq is 1Hz to 62500Hz
* Human ear: 20Hz ~ 20000Hz
*/
Static void pwm_set_freq (unsigned long freq)
{
Unsigned long tcon;
Unsigned long tcnt;
Unsigned long tcfg1;
Unsigned long t00000;

Struct CLK * clk_p;
Unsigned long pclk;

 

S3c2410_gpio_cfgpin (s3c2410_gpb (0), s3c2410_gpb0_tout0 );

// Set gpb0 to PWM output mode

Tcon = _ raw_readl (s3c2410_tcon); // read the register tcon
Tcfg1 = _ raw_readl (s3c2410_tcfg1); // read and access tcfg1
T1_0 = _ raw_readl (s3c2410_t1_0); // read the t1_0 register.

 

T00000 & = ~ S3c2410_t1__prescaler0_mask; // pre-division mask: t00000 [0: 7]

T00000 | = (50-1); // sets the 50-bit frequency.

 

Tcfg1 & = ~ S3c2410_t00000000mux0_mask; // split value mask: tcfg1 [0: 3]
Tcfg1 | = s3c2410_t00000000mux0_div16; // The timer 0 performs 16 segmentation.

 

_ Raw_writel (tcfg1, s3c2410_tcfg1); // Save the set data to tcfg1 and t1_0
_ Raw_writel (t1_0, s3c2410_t1_0 );

 

Clk_p = clk_get (null, "pclk ");

Pclk = clk_get_rate (clk_p); // obtain the pclk clock.
Tcnt = (pclk/50/16)/freq; // obtain the timer initialization value.
 
_ Raw_writel (tcnt, s3c2410_tcntb (0); // write tcnt to the timer count register
_ Raw_writel (tcnt/2, s3c2410_tcmpb (0); // duty cycle 50%

Tcon & = ~ 0x1f; // disable deadzone, auto-Reload, inv-off,

Tcon | = 0xb; // update tcntb0 & tcmpb0, start timer 0

_ Raw_writel (tcon, s3c2410_tcon );
 
Tcon & = ~ 2; // clear manual update bit
_ Raw_writel (tcon, s3c2410_tcon );
}

 

Static void pwm_stop (void)
{// Set gpb0 to the output mode, and output the low level to stop PWM.
S3c2410_gpio_cfgpin (s3c2410_gpb (0), s3c2410_gpio_output );

S3c2410_gpio_setpin (s3c2410_gpb (0), 0 );
}

 

Static int s3c24xx_pwm_open (struct inode * inode, struct file * file)
{
If (! Down_trylock (& lock) // semaphores-1. If it succeeds, down_trylock (& lock) returns 0.
Return 0;
Else
Return-ebusy;
}

Static int s3c24xx_pwm_close (struct inode * inode, struct file * file)
{
Pwm_stop (); // call the stop function to disable PWM.
Up (& lock); // release the semaphore
Return 0;
}

Static int s3c24xx_pwm_ioctl (struct inode * inode, struct file * file, unsigned int cmd, unsigned long Arg)
{// Select an operation based on the cmd
Switch (CMD)

{
Case pwm_ioctl_set_freq: If (ARG = 0)
Return-einval;
Pwm_set_freq (ARG );
Break;

 

Case pwm_ioctl_stop: pwm_stop ();
Break;
}

Return 0;
}

Static struct file_operations dev_fops =

{// Funtion provided by the driver to the upper layer
. Owner = this_module,
. Open = s3c24xx_pwm_open,
. Release = s3c24xx_pwm_close,
. IOCTL = s3c24xx_pwm_ioctl,
};

 

Static struct miscdevice MISC =

{
. Minor = misc_dynamic_minor,
. Name = device_name,
. Fops = & dev_fops,
};

 

Static int _ init dev_init (void)
{
Int ret;

Init_mutex (& lock); // initialize the mutex lock
Ret = misc_register (& MISC); // register the mise Device

Printk (device_name "/tinitialized/N ");
Return ret;
}

 

Static void _ exit dev_exit (void)
{
Misc_deregister (& MISC); // cancel the mise Device
}

 

Module_init (dev_init );
Module_exit (dev_exit );
Module_license ("GPL ");
Module_author ("friendlyarm Inc .");
Module_description ("S3C2410/S3C2440 PWM driver ");

 

Conclusion:

Through the study and testing of these drivers, I have a deeper understanding of the linxu driver. The example may be simple and superficial, but it must be more suitable for beginners, it provides a good starting point for the majority of beginners. There are many shortcomings in this series of articles. The most bad thing for me is that I did not post the upper-layer applications to share with you, let's see how the upper-layer applications call the functions provided by the underlying driver. (Because you are a little lazy ~~) If you need to view the application code, you can contact your colleagues at any time.

Because this series of driving learning is followed by one course, in the program annotation, the subsequent courses have not repeated the previous ones, if you have any questions, you can refer to your blog post on the same topic. If you have not found a satisfactory answer yet, contact me and learn and make progress together!

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.