[uCsimm] Simple PWM audio driver

From: David Beckemeyer (david@bdt.com)
Date: Tue Apr 24 2001 - 15:00:40 EDT

I plan to add more features to this, but I may not get around to
it for a while, so I'm posting this now.

It is pretty crude and basic, only supporting one data format,
but it's been working for me:


The README from the archive follows.


April 24, 2001

This package contains a preliminary PWM audio driver for MC68EZ328
based uClinux systems.

This is very much a preliminary driver. It works but it isn't
pretty nor fancy. In particular, the driver only supports 8K
sample data. I'd like to add ioctl() calls to support other
sample rates, generate tones, and other features.

The archive includes the source for the driver, a sample program,
and two files containing audio sample data file in the raw audio
format used by the PWM device driver:



The pwm328.c source file should be placed in the kernel char driver
subdirectory (linux/drivers/char).

You will have to modify the following files to include the driver
in your kernel, as follows:

In linux/init/main.c add a call to pwm_init() wrapped around the
CONFIG option of your choice (I use CONFIG_PWM), e.g.

    #ifdef CONFIG_PWM
    extern void pwm_init();

    #ifdef CONFIG_PWM

And in linux/drivers/char/Makefile insert:

    ifeq ($(CONFIG_PWM),y)
      L_OBJS += pwm328.o

In linux/arch/m68knommu/config.in within the
'if [ "$CONFIG_M68EZ328" = "y" ]; then'" block, insert:

    bool 'PWM audio support' CONFIG_PWM

You will also need to create the device node in the uClinux /dev
romdisk tree, typically something like:

    mknod romdisk/dev/pwm c 120 0


To use the driver in your applications, you simply open the device
and write the sample data to it. The driver uses a simple double
buffering scheme with 16K buffers, so optimal performance will be
achieved by writing 16K blocks in each write() system call. Smaller
buffer writes will work, but writing a single byte at a time may

The sample program 'playrt.c' sends files given as arguments to the
/dev/pwm device, e.g:

    playrt cow.ub ferrari.ub


The driver accepts raw audio data at 8000 hz in "unsigned byte"
format. The readily available 'sox' program (included in most
Linux distributions) can convert files to this format, using a
command-line of the following form, assuming the 'inputfile'
below is in a standard format that sox understands (e.g. aiff, au,
voc, wav, etc.):

    sox inputfile outputfile.ub

The '.ub' extension tells sox to create an 8Khz sample in "raw
unsigned byte" format. The format can also be explicitly set as in:

    sox inputfile -t ub -r 8000 outputfile


It takes a lot of the little EZ328 at 16 Mhz to keep the PWM buffer
full, so there isn't a lot of CPU left over for other tasks when
the driver is playing audio. Other interrupt code can create blips
in the audio output as a result of the PWM running out of input
data (e.g. console RS-232 interrupts).

This driver is based very much on the work of others, mostly the
dac0800.c driver by Greg Ungerer.


 -- David Beckemeyer
This message resent by the ucsimm@uclinux.com list server http://www.uClinux.com/

This archive was generated by hypermail 2b30 : Sun Apr 07 2002 - 00:01:43 EST