Accessing Buzzer and PWM

From InCircuit
Jump to: navigation, search

The buzzer found on some ICnova ADB is connected to a pin corresponding to PWM channel 1. It can be used by accessing that channel. While the buzzer's channel usally is preconfigured to use the PWM, the other channels are switched off in the delivery state, as configured ports can't be used as GPIO at the same time.


Accessing a PWM-Channel

Access to the different PWM-Channel from userspace can be done via the sysfs interface. The PWM-channels can be accessed within the directory /sys/devices/platform/atmel-pwm-hwmon.0. For each (activated) PWM-channel two files exist, one to control the frequency and one for the pulse-width.

Setting the frequency

For each (activated) channel a file pwmX_freq (with 'X' replaced by the channels number) exist. This file can be used to set the output-frequency of the channel in Hz. As the controller can only a couple of frequencies, the frequency set by the controller might not match the frequency set by the user. The following example will try to set a frequency of 1.5kHz on channel 1 and read the status again. As shown, the controller has set a frequency of 1041Hz.

 $ echo 1500 > pwm1_freq
 $ cat pwm1_freq

If using eg. a C-program to access these files, please be aware to convert all numbers to ASCII-strings before writing or reading them.

Setting the pulse-width

Analogous to the frequency, the file pwmX will set the pulse-width of a certain channel. A full pulse has a width of 1000; the part of the pulse, the pin is on will be set in that file. So writing a value of '0' or '999' will set the pin to a specific level all of the time. The following example will make the output of channel 1 clock with a pulse-width of 50%

 $ echo 500 > pwm1

Configuring further channels

The use of further PWM-channels can't be done from userspace but must be done in the kernel. To do this, within the Buildroot_directories, go into the directory of your projects linux-kernel. Within that, you'll find the directories arch/arm/mach-at91. Here a couple of files called board-*.c can be found. Each is specific for a certain product; the product choosen can be identified most easily by searching for a corresponding .o file. This file is further called boardfile for your board.

Just adding another channel

Open your boardfile in a texteditor and search for a line calling the command at91_add_device_pwm(). This might look like in the following example

 /* Buzzer */

change this to integrate the pwm-channel you want to access. To enable pwm-channel 2, the following should suceed:

 /* Buzzer */

Adding the PWM-controller

If there was no PWM-Controller enabled in advance, this must be done, too. So open your board-file in a texteditor, now before the start of the function ek_board_init(void), add the following declaration:

 static struct platform_device icnova_pwmdev = {
   .name = "atmel-pwm-hwmon",
   .id = 0,

Now, at the end of the function ek_board_init(void), you can add the following lines, replacing the channel-definition by the channel you want to access:

 /* Buzzer */

Compiling a new kernel

To make buildroot to integrate the changes and built a new kernel, the corresponding stamp-file has to be changed. This can be done most easily by running the following command in the buildroot's directory before the execution of make.

 $ touch project_build_arm/adb1000g45/linux-

The project name (adb1000g45) has to be replaced by the projectname effectivly in use.

Access features not implemented

The Controllers PWM-Hardware support further features, not accessible with this interface. To utilize them, the corresponding drivers within the kernel have to be modified accordingly. How to do this, would exceed this tutorial.

Personal tools