 | |
rio car dot org Developer Information
Category: Main -> Device Input/Output
| · Display Output (todo: split into sections)
Accessing the Display
The display is accessed through /dev/display . You can mmap() 2048 bytes from this device and read from or write to it.
The display is 128x32, 2bpp. The memory layout is fairly straight-forward:
32 rows of 64 bytes each, where rows are laid left-to-right, top-to-bottom,
and each byte contains two 4-bit pixel values. The architecture is
little-endian, so bits 0-3 correspond to the "left" pixel, and bits 4-7 are
the "right" pixel. Since the display only supports 2bpp, only pixel values 0-3
are meaningful; the two highest bits are currently ignored. Value 0 is off; 1
is dim; 2 is medium; 3 is full brightness.
Changes you make to the display will not become active until you call
ioctl(fd, _IO('d', 0)) .
It is further possible to buffer and synchronize screen updates with the
audio DMA, but documentation of this feature is not yet available.
The entire display can be turned on and off with ioctl(fd,
_IOW('d', 1, int), state) where state is 1
(on) or 0 (off). When the display is off, the front LED is
enabled.
The LED can also be controlled, but no specification is available at this
time.
Contributed by
Rob Leslie
Example
Here is a sample program which reads 2048 bytes from standard input, dumps
them onto the display, and turns it on (in case it was off):
dblit.c
# include
# include
# include
# include
# include
# include
# define BLIT(fd) ioctl((fd), _IO('d', 0))
# define DISPLAY(fd, x) ioctl((fd), _IOW('d', 1, int), (x))
int main(int argc, char *argv[])
{
int fd;
caddr_t dmap;
fd = open("/dev/display", O_RDWR);
if (fd == -1)
return 1;
dmap = mmap(0, 2048, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (dmap == (caddr_t) -1)
return 2;
if (read(STDIN_FILENO, dmap, 2048) == -1)
return -1;
BLIT(fd);
DISPLAY(fd, 1);
if (munmap(dmap, 2048) == -1 ||
close(fd) == -1)
return 3;
return 0;
}
If you don't have a suitable bitmap image handy to test, try feeding in
/dev/urandom or /dev/zero . A similar program can be
written to copy the display to standard output.
Contributed by
Rob Leslie
Image Conversion
The above sample program just blits from stdin to display in the display's
raw format, which is 4-bits per pixel (little-endian).
I took the same code and added 8-bit -> 4-bit conversion to it, so that
you can load raw files with the example below. But if you consider programming
anything in larger scale, I would suggest to write a proper image reader.
So, to get your image to the display:
- compile the program below
- make your image 128x32 sized (image can use all 256 grayscales)
- after your image is ready, go to Image/Mode/Grayscale in Photoshop
- go to File/Save As, choose the .RAW format
- use the default options, header being 0 sized
- transfer the image to empeg (file size should be 4096 bytes)
- run
blitraw < pic.raw on your empeg, if you
named the program as blitraw and image as
pic.raw
This is the easiest way to get your own image to the empeg's display but
also the most unsophisticated way to do it. It relies that the raw image file
has no palette and that 0 means black and 255 white, on color indices. And it
only works with 128x32 images.
blitraw.c
#include
#include
#include
#include
#include
#include
#define BLIT(fd) ioctl((fd), _IO('d', 0))
#define DISPLAY(fd, x) ioctl((fd), _IOW('d', 1, int), (x))
int main(int argc, char *argv[])
{
int fd;
caddr_t dmap;
int i = 0, j = 0;
char cBuffer[ 4096 ];
char cLeft = 0, cRight = 0;
fd = open("/dev/display", O_RDWR);
if(fd == -1)
return 1;
dmap = mmap(0, 2048, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (dmap == (caddr_t) -1)
return 2;
if( read( STDIN_FILENO, cBuffer, 4096 ) == -1 )
return -1;
// shuffle bits
for( i = 0; i < 4096; i+=2, ++j )
{
cLeft = cBuffer[ i ] >> 6;
cRight = cBuffer[ i+1 ] >> 6;
dmap[ j ] = (cRight << 4) | cLeft;
}
BLIT(fd);
DISPLAY(fd, 1);
if (munmap(dmap, 2048) == -1 || close(fd) == -1)
return 3;
return 0;
}
Contributed by
Kim Salo
Back to Top
| · Audio Output
/dev/audio is vaguely
standard, except that
it requires fills of DMA buffer size (4608 bytes) and is locked at
44.1khz stereo. The buffer fill bit is a bug, but it's likely to stay locked
at that rate - we can't actually change the rate (the player does
interpolation & flash stuff for lower bitrates).
The mixer calls are pretty standard I believe, though there are lots of
other bits for controlling the DSP - many of which we simply can't document as
we're under NDA with the docs on the DSP.
Contributed by Hugo Fiennes
Here is a program which reads pairs of signed 16-bit little-endian PCM
samples from standard input and plays them at 44.1kHz stereo using
/dev/audio . It takes care always to write 4608 bytes at a
time.
Some of the ioctl() s probably aren't strictly necessary on the
empeg but they illustrate the API.
pcmplay.c
# include
# include
# include
# include
# include
# include
# include
# define AUDIO_DEVICE "/dev/audio"
# define AUDIO_FILLSZ 4608
static
int output(int fd, void const *buf, unsigned int len)
{
char const *ptr = buf;
int wrote;
while (len) {
wrote = write(fd, ptr, len);
if (wrote == -1) {
if (errno == EINTR)
continue;
else
return -1;
}
ptr += wrote;
len -= wrote;
}
return 0;
}
static
int audio_buffer(int fd, void const *buf, unsigned int len)
{
char const *ptr = buf;
static char hold[AUDIO_FILLSZ];
static unsigned int held;
unsigned int left, grab;
if (len == 0) {
if (held) {
memset(&hold[held], 0, &hold[AUDIO_FILLSZ] - &hold[held]);
held = 0;
return output(fd, hold, AUDIO_FILLSZ);
}
return 0;
}
if (held == 0 && len == AUDIO_FILLSZ)
return output(fd, ptr, len);
left = AUDIO_FILLSZ - held;
while (len) {
grab = len < left ? len : left;
memcpy(&hold[held], ptr, grab);
held += grab;
left -= grab;
ptr += grab;
len -= grab;
if (left == 0) {
if (output(fd, hold, AUDIO_FILLSZ) == -1)
return -1;
held = 0;
left = AUDIO_FILLSZ;
}
}
return 0;
}
# define audio_flush(fd) audio_buffer((fd), 0, 0)
static
int audio_init(int fd)
{
int format, stereo, speed;
format = AFMT_S16_LE;
if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) {
perror("ioctl(SNDCTL_DSP_SETFMT)");
return -1;
}
if (format != AFMT_S16_LE) {
fprintf(stderr, "AFMT_S16_LE not available
");
return -1;
}
stereo = 1;
if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
perror("ioctl(SNDCTL_DSP_STEREO)");
return -1;
}
if (!stereo) {
fprintf(stderr, "stereo selection failed
");
return -1;
}
speed = 44100;
if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) {
perror("ioctl(SNDCTL_DSP_SPEED)");
return -1;
}
if (speed != 44100) {
fprintf(stderr, "sample speed 44100 not available (closest %u)
", speed);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
static char buffer[AUDIO_FILLSZ];
int fd;
unsigned int len;
fd = open(AUDIO_DEVICE, O_WRONLY);
if (fd == -1) {
perror(AUDIO_DEVICE);
return 1;
}
if (audio_init(fd) == -1) {
close(fd);
return 2;
}
while ((len = fread(buffer, 4, AUDIO_FILLSZ / 4, stdin))) {
if (audio_buffer(fd, buffer, 4 * len) == -1) {
perror("write");
return 3;
}
}
if (ferror(stdin)) {
perror("read");
return 4;
}
if (audio_flush(fd) == -1) {
perror("write");
return 3;
}
if (close(fd) == -1) {
perror("close");
return 5;
}
return 0;
}
You will need a source of PCM data to try this program. If you have a
44.1kHz stereo WAV file, you can usually generate an appropriate PCM file by
stripping away the 44-byte RIFF header:
dd if=$file .wav of=$file .pcm ibs=44 skip=1
Contributed by
Rob Leslie
Back to Top
| · Beeps
Making Beeps
Here's some code to make the empeg beep. I've had to butcher it a little
but it should still compile... :-)
Pitch is in MIDI notes (thanks to John) - he informs me that 60 is probably
middle A - he may have the scale wrong.
Duration is in milliseconds. It is asynchronous but closing the device
kills off any pending notes (I think).
beep.c
#include
#include
#include
#include
#include
#include
#include
#define EMPEG_DSP_MAGIC 'a'
#define EMPEG_DSP_BEEP _IOW(EMPEG_DSP_MAGIC, 0, int)
int main(int ac, char *av[])
{
int fd;
int pitch = 60;
int duration = 500;
int args[2];
fd = open("/dev/dsp", O_RDONLY);
if (ac == 3)
{
pitch = atoi(av[1]);
duration = atoi(av[2]);
}
if (fd < 0)
{
perror("Couldn't open dsp.
");
return 1;
}
args[0] = pitch;
args[1] = duration;
if (ioctl(fd, EMPEG_DSP_BEEP, args) < 0)
perror("ioctl.
");
usleep(duration * 1000 + 125000);
close(fd);
return 0;
}
Contributed by Mike Crowe
Back to Top
| · Mixer Calls
Here's some untested code that might prove useful.
mute.c
#include
#include
#include
#include
#include
#include
#include
#include
#define EMPEG_MIXER_READ_FLAGS _IOR('m', 1, int)
#define EMPEG_MIXER_WRITE_FLAGS _IOW('m', 1, int)
#define EMPEG_MIXER_FLAG_MUTE (1<<0)
int main(int ac, char *av[])
{
int mute = -1;
int flags = 0;
int fd = -1;
while (*++av)
{
if(av[0][0] == '-')
{
switch(av[0][1])
{
case 'm':
mute = 1;
break;
case 'u':
mute = 0;
break;
default:
fprintf(stderr, "Usage: mute [-u|-m]
");
return 1;
}
}
else
{
fprintf(stderr, "Usage: mute [-u|-m]
");
return 1;
}
}
fd = open("/dev/mixer", O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Couldn't open /dev/mixer
");
return 2;
}
if (mute >= 0)
{
if (mute)
flags |= EMPEG_MIXER_FLAG_MUTE;
if (ioctl(fd, EMPEG_MIXER_WRITE_FLAGS, &flags) < 0)
printf("Write mute ioctl failed: %s (%d)
", strerror(errno), errno);
}
if (ioctl(fd, EMPEG_MIXER_READ_FLAGS, &flags) < 0)
printf("Read mute ioctl failed: %s (%d)
", strerror(errno), errno);
if (flags & EMPEG_MIXER_FLAG_MUTE)
printf("Output is currently muted.
");
else
printf("Output is currently unmuted.
");
return 0;
}
Contributed by Mike Crowe
The following code will view or change the input source (PCM, radio,
or line.)
mixersrc.c
# include
# include
# include
# include
# include
# define DEV_MIXER "/dev/mixer"
/* The following definitions are from include/asm-arm/arch-sa1100/empeg.h
in the beta9b kernel source */
# define EMPEG_MIXER_MAGIC 'm'
# define EMPEG_MIXER_READ_SOURCE _IOR(EMPEG_MIXER_MAGIC, 0, int)
# define EMPEG_MIXER_WRITE_SOURCE _IOW(EMPEG_MIXER_MAGIC, 0, int)
int main(int argc, char *argv[])
{
int fd, opt, source = 0;
char *source_str;
while ((opt = getopt(argc, argv, "prl")) != -1) {
switch (opt) {
case 'p':
source = SOUND_MASK_PCM;
break;
case 'r':
source = SOUND_MASK_RADIO;
break;
case 'l':
source = SOUND_MASK_LINE;
break;
default:
fprintf(stderr, "Usage: %s [-p|-r|-l]
", argv[0]);
return 1;
}
}
fd = open(DEV_MIXER, O_RDONLY);
if (fd == -1) {
perror(DEV_MIXER);
return 2;
}
if (source) {
if (ioctl(fd, EMPEG_MIXER_WRITE_SOURCE, &source) == -1) {
perror("ioctl(EMPEG_MIXER_WRITE_SOURCE)");
return 3;
}
}
if (ioctl(fd, EMPEG_MIXER_READ_SOURCE, &source) == -1) {
perror("ioctl(EMPEG_MIXER_READ_SOURCE)");
return 4;
}
if (source & SOUND_MASK_PCM)
source_str = "PCM";
else if (source & SOUND_MASK_RADIO)
source_str = "radio";
else if (source & SOUND_MASK_LINE)
source_str = "line";
else
source_str = "unknown";
printf("%s source selected
", source_str);
if (close(fd) == -1) {
perror("close");
return 5;
}
return 0;
}
Contributed by
Rob Leslie
An additional mute setting known as the Soft Audio Mute (SAM) can be
toggled with the following code.
sam.c
# include
# include
# include
# include
# include
# define DEV_MIXER "/dev/mixer"
/* The following definitions are from include/asm-arm/arch-sa1100/empeg.h
in the beta10a kernel source */
# define EMPEG_MIXER_MAGIC 'm'
# define EMPEG_MIXER_SET_SAM _IOW(EMPEG_MIXER_MAGIC, 15, int)
int main(int argc, char *argv[])
{
int fd, opt, sam = -1;
while ((opt = getopt(argc, argv, "mu")) != -1) {
switch (opt) {
case 'm':
sam = 1;
break;
case 'u':
sam = 0;
break;
default:
return 1;
}
}
if (sam == -1) {
fprintf(stderr, "Usage: %s {-u|-m}
", argv[0]);
return 1;
}
fd = open(DEV_MIXER, O_RDONLY);
if (fd == -1) {
perror(DEV_MIXER);
return 2;
}
if (ioctl(fd, EMPEG_MIXER_SET_SAM, &sam) == -1) {
perror("ioctl(EMPEG_MIXER_SET_SAM)");
return 3;
}
printf("Soft Audio Mute %s
", sam ? "enabled" : "disabled");
if (close(fd) == -1) {
perror("close");
return 5;
}
return 0;
}
Contributed by
Rob Leslie
Back to Top
| · IR Input
Intercepting the IR device
I've just written a little piece of code to intercept the IR device before
and make beeps.
This should be run before the player; one way to do this is to rename
/sbin/init to /sbin/init.empeg and replace the
original with something like this:
#!/bin/bash
#
/bin/intercept&
exec /sbin/init.empeg
ir.h
/*
* ir.h
*
* /dev/ir codes from the empeg
*
* the top 16 bits of each code should be zero
*/
/*
* Front panel buttons
*/
#define IR_TOP_BUTTON_PRESSED 0x00000000
#define IR_TOP_BUTTON_RELEASED 0x00000001
#define IR_RIGHT_BUTTON_PRESSED 0x00000002
#define IR_RIGHT_BUTTON_RELEASED 0x00000003
#define IR_LEFT_BUTTON_PRESSED 0x00000004
#define IR_LEFT_BUTTON_RELEASED 0x00000005
#define IR_BOTTOM_BUTTON_PRESSED 0x00000006
#define IR_BOTTOM_BUTTON_RELEASED 0x00000007
/*
* Kenwood RCA-R6A remote
*/
#define IR_0 0x0000B900
#define IR_1 0x0000B901
#define IR_2 0x0000B902
#define IR_3 0x0000B903
#define IR_4 0x0000B904
#define IR_5 0x0000B905
#define IR_6 0x0000B906
#define IR_7 0x0000B907
#define IR_8 0x0000B908
#define IR_9 0x0000B909
#define IR_TRACK_MINUS 0x0000B90A
#define IR_TRACK_PLUS 0x0000B90B
#define IR_AM 0x0000B90C
#define IR_FM 0x0000B90D
#define IR_PROG 0x0000B90E
#define IR_DIRECT 0x0000B90F
#define IR_VOL_PLUS 0x0000B914
#define IR_VOL_MINUS 0x0000B915
#define IR_STAR 0x0000B91B
#define IR_TUNER 0x0000B91C
#define IR_TAPE 0x0000B91D
#define IR_CD 0x0000B91E
#define IR_CDMDCH 0x0000B91F
#define IR_DNPP 0x0000B95E
intercept.c
/*
* Intercept.c
*
* To use this code you need to rename /dev/ir to
* /dev/ir_real, mkfifo /dev/ir and put intercept
* into the startup by moving /sbin/init to /sbin/init.empeg
* and creating a script called init to call intercept
* first and then the real init.
*
* It will then intercept IR codes and do a beep
* before passing them onto the player. I have noticed that
* the beep sometimes lags the press, I suspect the intercept
* process is being swapped out by the caching facility.
*
* Thanks to Mike Crowe @empeg for the dsp ioctl
*
* Obviously I take no responsibilty for this mess ;-)
*
* Steve Boyle sysboy@hotmail.com
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ir.h"
#define REAL_IR_DEV "/dev/ir_real"
#define IR_DEV "/dev/ir"
#define DSP_DEV "/dev/dsp"
#define EMPEG_DSP_MAGIC 'a'
#define EMPEG_DSP_BEEP _IOW(EMPEG_DSP_MAGIC, 0, int)
main(argc,argv)
int argc;
char *argv[];
{
int irfd;
int irrealfd;
ssize_t rts;
long ircode;
int dspfd;
int pitch = 80;
int duration = 25;
int args[2];
args[0] = pitch;
args[1] = duration;
irrealfd = open(REAL_IR_DEV, O_RDONLY&O_NDELAY&O_NONBLOCK);
if ( irrealfd == -1 ) {
perror("Opening real IR device.");
exit(1);
}
irfd = open(IR_DEV, O_WRONLY);
if ( irfd == -1 ) {
perror("Opening phony IR device.");
close(irrealfd);
exit(1);
}
dspfd = open(DSP_DEV, O_RDONLY);
if ( dspfd == -1 ) {
perror("Opening DSP device.");
close(irrealfd);
close(irfd);
exit(1);
}
for (;;) {
rts = read(irrealfd, (char *) &ircode, 4);
if (rts == -1 ) {
perror("Reading from real IR device.");
close(irfd);
close(irrealfd);
exit(1);
}
if (rts == 0 ) {
perror("Finished reading from real IR device.");
close(irfd);
close(irrealfd);
exit(0);
}
switch (ircode) {
case IR_TOP_BUTTON_RELEASED:
case IR_RIGHT_BUTTON_RELEASED:
case IR_LEFT_BUTTON_RELEASED:
case IR_BOTTOM_BUTTON_RELEASED:
break; /* do nothing for releases */
default:
if (ioctl(dspfd, EMPEG_DSP_BEEP, args) < 0) {
perror("ioctl.
");
close(irfd);
close(irrealfd);
close(dspfd);
exit(1);
}
}
rts = write(irfd, (char *) &ircode, 4);
if (rts == -1 ) {
perror("Writing to phony IR device.");
close(irfd);
close(irrealfd);
exit(1);
}
}
}
Contributed by
Steve Boyle
Back to Top
| · IrDA Input/Output
We've not done a lot of playing ourselves, but generally: get the IR utils
package and at the very least compile up irattach : you will need
a kernel with IrDA support (the PPP 2.2.12 kernel
here
will do nicely). The IrDA is /dev/ttyS2 , so you need to do:
irattach /dev/ttyS2
You can then enable IrDA discovery by doing:
echo 1 >/proc/sys/net/irda/discovery
...and at this point if I wave my Palm V in front of the empeg the Palm
decides something is trying to talk to it and if you cat
/proc/net/irda/discovery (no sys !) then it tells me the
name of my Palm.
I've not gone further than this yet as it proved the IrDA was doing
stuff. The irtutils archive has various IrOBEX stuff for talking to Palms.
Contributed by Hugo Fiennes
Back to Top
| · Serial Input/Output (todo: move 230k / UART stuff to another section)
Technical Details
The serial port is DTE, just like a normal PC. The supplied lead is a null
modem one.
The harness is identical to the internal port (but with only
TX/RX/GND/power supply on DTR, pin 4) but a female as opposed to a male.
The port's speed defaults to 115200bps but can be run at lower speeds or as
fast as 230400bps. Note that RTS/CTS (though connected to lines on the SA)
isn't implemented at driver level.
Contributed by Hugo Fiennes
Dropping to the Shell
To get into the shell you need to have the developer image installed on
your empeg. These instructions are for beta6 and most likely won't work with
beta5. You can get the image from the
Empeg Upgrade site.
Once you've installed the image use a comm program to access your serial
port (see chart below.) Parameters for the serial port are 115200,8,N,1
no handshaking. Plug in your empeg player (if not already
done.) Wait until you get music to make sure the player is started. Now type
q and then . The prompt should come
up.
OS |
Application |
Port |
Notes |
FreeBSD |
minicom |
/dev/cuaa* |
It may be necessary to run
minicom -o to avoid sending your modem init
string. |
Linux |
/dev/ttyS* |
Win98 |
Tera
Term |
COM* |
|
Palm |
SimpleTerm |
/dev/ttyS* |
You'll have to set terminal speed to 19200:
stty -F /dev/ttyS * 19200 |
Note: replace * with appropriate device number
for your system.
Contributed by gandolf
Maximum Serial Port Speed
230400 works for us - Mike used to run with a 230400bps serial card to
minimise zmodem times :)
Bear in mind that standard PC serials do not run 230,400 - even though
windows offers you the option. The standard 1.8432Mhz serial clock with a x1
divisor gives max 115,200bps: you need at least a 3.6864Mhz serial clock into
your 16c[56789]50 to get 230400bps.
Contributed by Hugo Fiennes
Running at 230K
A patch for various Unix and Windows systems to support chips that emulate
a 16550 but can actually run at > 115K is
here.
The Linux patch has moved. I've tested it on Linux 2.2 but unfortunately it
doesn't recognise my chip. The Linux patch is
here.
According to Rogier Wolff: you can replace the 1.8x MHz crystal with a 14.x
MHz so that the 14MHz crystal frequency will be multiplied by 7.something to
get the 100MHz system clock. And it will be divided by 8 to get the base-clock
for the SMC chip which has the dual 16550s on many ISA buses.
Contributed by Paul Ashton
Back to Top
| · Audio Overlay Kim Salo created a patch to the empeg 2.0b3 kernel that allows to do just that. This is what he says about that patch:
The patch file has been created against the v2.00-beta3 version of the kernel. The patching should go as follows:
% cd kernel/arch/arm/special
% patch < audio_overlay.patch
It modifies the empeg_audio3 and empeg_mixer files. The changes won't affect existing applications, therefore the player and other applications should run as before.
Using the audio overlay system is very simple. When you open the /dev/audio device in your code, you need to specify the O_SYNC flag to determine that you want to overlay audio with the player application.
For example:
int handle = open( "/dev/audio", O_WRONLY | O_SYNC );
That's all. Now, every time you write something to the handle, it will automatically fade the volumes and mix the audio.
The patch is available for download at /files/kernel/audio_overlay-patch.zip or via his BBS post at http://empegbbs.com/php/showthreaded.php?Cat=&Board=hackers_prog&Number=46906&page=0&view=collapsed&sb=5&o=365&vc=1Back to Top
| · IrDA Made Easy (Entry last updated on January 19th, 2002)
TCP/IP over Infra-red on the Empeg
When you think about it, there are so many strings attached to infra-red data transfer. It must be short range, must be line-of-sight, and so on. However, there are numerous benefits as well: it is reasonably high speed (up to 4 Mbps for what is called fast infra-red), it is cordless, it is not exactly limited to line of sight, there is a plethora of devices that support IR out there, and so on. Oh, and it is cool in general. With an increasing number of computers (particularly laptops) including infra-red ports today, support for IrDA has been gaining momentum. In particular, open source IrDA support for Linux is eminently usable already. The IrDA stack is depicted diagrammatically here.
Making two Linuces talk TCP/IP over IR
Linux 1: Sony VAIO
I have a Sony VAIO PCG-Z505 JE laptop, on which IrDA works well. The IrDA specific contents of my /etc/modules.conf are as follows (please note that your configuration will very likely differ):
Sony VAIO PCG-Z505 JE (Linux 2.4.9, irda-utils-0.9.14) |
pre-install nsc-ircc setserial /dev/ttyS2 port 0 irq0
alias irda0 nsc-ircc
options nsc-ircc io=0x3e8 dma=0 irq=10 dongle_id=0x09
alias tty-ldisc-11 irtty
alias char-major-161 ircomm-tty
alias char-major-10-187 irnet
|
Linux 2: The Empeg
I am running the Debian potato distribution on the Empeg, as described in this HOWTO. In order to use IrDA as we are going to, the following are required on the Empeg:
- A development kernel with IrDA and PPP support. I compiled my own kernel (unchanged 2.2.14 sources as provided by Rio), but I believe any appropriate kernel will do.
- The PPP package (ppp_2.3.11-1.4.deb currently for Debian-potato).
- The irda-tools package (irda-tools_0.9.5-2.deb currently).
- The irda-common package (irda-common_0.9.5-2.deb currently).
It is easiest to use SIR to get started with IrDA (which I reckon is the only way that will work on the Empeg because of its IR hardware). We shall use PPP over SIR to get TCP/IP working. Communication speed will be limited to 115200 bps. The following steps should allow you to get a minimal connection working, which you can tailor to suit your needs thereafter:
- Let us treat the "other" (Linux 1) machine as a PPP server. It is assumed that your IR hardware is identified by the kernel and is working. The system service "irda" must also be started (in other words, an "irattach" must be performed, like "irattach /dev/ttyS2 -s 1" - please refer to IR documentation). Moreover, the relevant devices must exist (/dev/ircomm0, ...)
- Start up irda on Linux 1, if it is not already started.
- Execute "echo 1 > /proc/sys/net/irda/discovery" on Linux 1.
- Execute "pppd /dev/ircomm0 115200 noauth x.x.x.x:y.y.y.y" on Linux 1, where x.x.x.x and y.y.y.y are two appropriate IP addresses to be used for the Point-to-Point link that would be established (hopefully!)
- Make sure that a ppp device comes up. It is useful to have a "tail -f" running on /var/log/messages all this while as a debugging aid.
- Drop to the shell on the Empeg (either through a serial connection, or by logging in if your Empeg is configured for remote logins).
- Make sure the appropriate ir devices (/dev/ircomm0, ...) exist in /dev. If they don't, you need to create them. One way is to do a "tar -cpf" on Linux 1 and "tar -xpf" it on the Empeg.
- Run "irattach /dev/ttyS2 -s 1" on the Empeg. If things are fine, the irda0 device should come up.
- Execute "pppd /dev/ircomm0" on the Empeg.
- Count from 1 to 5. Do an "ifconfig -a" on the Empeg. If all went well, you should see the Point-to-Point link established and the IP addresses assigned.
- If everything is working, you can disconnect the Ethernet cable (if connected) and enjoy talking to the Empeg only over IR.
- Note that if the player software is restarted at this point, it should (can be made to) bind to the appropriate port (I think it is 8300) and listen on the newly found address. In other words, emplode/emptool should work over IR. [NB: I am yet to verify this.]
Please note that IrComm is not the only way to connect the Empeg to an IR-enabled computer, but it is the simplest. IrLAN in ad-hoc mode might be another option.
Contributed by
Amit Singh
Back to Top
|
|
|
|