Rockbox.org home
release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Rockbox mail archive

Subject: Re: new thread about remote control with display
From: Andreas Zwirtes (zwirtes_at_gmx.de)
Date: 2002-10-10


The protocol that I want to introduce renders polling totally
unnecessary. It'll be open for new functionaltiy and backwards
compatible. Also it is very flexible, so that there will be only a few
bytes communication for the remote but a PC would be able to ask the
rockbox for almost anything he want's to know. All we have to do is
stick to the protocol (once it is ready) and follow a process when
changing functionality (just to avoid versioning and compatibility
problems). It is very basic and it is tested, so it should be easier to
implement as a totally new protocol that has to run the whole software
and hardware iteration process.

What might be very interesting is, that every participant can ask for
information at any time and also can send information any time he wants.
Certainly he'll have to stick to some rules. Because this issue seems to
be heavily discussed, I'll describe the basics of the protocol right now.

LAYER MODEL: Physical layer:

Controller X SH1
TX---+----------------------------------------------------RX/TX
RX---+
     1
     0
     0
          k
Px----+----1mOhm---GND

Bus modes: Active (communication in progress), Idle (System running but
not communicating), Deep sleep (disconnected or player powered down).

Active:
Controller or SH1 TX active (sending data). Px set to output high, to
keep the line high when sender finished and switches back to RX. Px is a
standard port that is needed for switching off the resistor in deep
sleep mode.

Idle:
Px set to output, high. It is needed to push the line to high pegel when
both TX are inactive. Otherwise the line would float and that's not good
for comms. Both Rx are set to UART and waiting for data. Communication
process to avoid collision is described later.

Deep Sleep:
Px, Rx and Tx are set to input. The 1mOhm discharged static electricity.
This prevents the 100k resistor from drawing current (it would do that
if we connected it directly to Vcc, because the parasitic diodes of the
archos processor would push the remote line to GND). With the 1mOhm we
have a highly sensitive configuration, wich is able to detect a wakeup
when the archos is powered on or the remote is plugged in.

LAYER MODEL: Driver layer (hardware abstraction layer)
This is the first piece of software that should be very easy to write on
both systems. It provides hardware interfacing such as transmit byte,
receive byte function with timeout or events for receive and basic
timeout functionality, wakeup event, port mode and state setting of
used ports. TODO: describe exact functionality

LAYER MODEL: Protocol layer
Now we come to the most interesting part of this. It is described with
the remote as master. It is also possible to use the archos as master,
but then you should write it down and think about it, before mailing.

Deep Sleep to Idle:
Normally, the bus is in deep sleep mode. Something wakes up the
processor (port toggling while plugging in or switching on the archos).
That puts the remote in Idle mode. After deep sleep mostly the remote
now want's to know if an Archos is there. If we are already in idle
mode, anybody who wants to can start communication.

Idle to Active:
The bus is in highZ mode (open, pushed by the resistor). The one who
wants to communicate now pushes the line low for at least 11 bit times.
This action would be considered a break by the opposite side, indicating
a starting up communication. It is possible to do that from both sides,
if both units use the port functionality of the TX port. This is not a
collision, it's intended. They will not draw current from each other,
because they are both pushing to GND. If wakeup send is over, the sender
releases the line (not push it to Vcc!). So if both are trying to wake
up the bus, the maximun wakeup time is about 22 bit times. But that
won't happen very often.

Active mode while communicating:
After the wakeup, only the master is allowed to send a "block". A block
is a logical information unit on the bus. It is the main thing, that the
protocol layer has to deal with. A block has consists of a length byte,
data bytes and a checksum. The length byte gives the total length of the
block, including the length byte, the data bytes and the checksum. The
first data byte normally would be the function. In certain situations
there are no data-bytes, as described in the table below:

Standard frame (frames are with data bytes):
0xll Length information including all bytes (Length byte, data bytes
and checksum)
0xdd One or more data bytes (0xll-2 bytes exactly)
0xcc checksum (addition of all informational bytes, that is length and
data without checksum %0xff)
That easy checksum is enough for a simple remote protocol and easy to
implement. It also runs on controllers with extremely limited capabilities.

Not Acknowledged:
0x03, 0x00, 0x03
This is the standard NACK frame. It is sent, when the device did not
understand the last request or command. It does not cause a re-send,
since this is no communication error.

Short block (frame without data):
0x02 Length information
0x02 Checksum
This one is used to put the bus in Idle mode. Only used by slave.

Request block (frame without data and checksum):
0x01 Length, without checksum
Also called "What do you want?" block. Only sent by master.

Sync block (Zero):
0x00 Length
This can be used to re-sync master and slave, when frequent
communication errors occur. Theese bytes are just thrown away. With a
limit to 16 databytes for frequently used blocks master and slave can be
syncronised by sending 16 0x00 bytes, sometimes useful. They can also be
syncronised by timeout.

The communication follows some simple rules:
1. After a wakeup (break) the master checks, it it has something
important to send (no matter where the wakeup came from).
2. If it has something to send it transmits the complete block and goes
directly to 1.
3. The master sends a "What do you want?" (request block).
4. The slave checks, what it has to say. If it does not have to say
something, it goes to step 6
5. The slave send the frame it has in the buffer. Then both jump to step 3.
6. The slave sends a short block to put the bus into sleep mode. Both
wait for a wakeup.

Oh, not to forget that: Five byte times is the general communication
timeout. If anybody has to say something, it has to do it within five
byte times. Also the time between two byte can be up to five byte times,
but must not exceed it! The sender modules should tolerate up to 10 Byte
times when switching to receive mode (Just a flag, that starts another
timeout after the first one ended). This avoids collision, when the
receiver goes to sleep and tries to wake up the sender, that is busy
sending. And it gives the receiver some time to answer. There are a few
other concerns to think about, but I'll bring that on later.

Weird, huh?
No it isn't. It's one of the simplest and most flexible state machines I
ever programmed. Every communication partner can start communication any
time when the bus is in idle mode. It's fast, small and flexible. Some
thoughts about the flexibility:

We should use the first data byte as functional identifier. The fastest
and shortest (i.e. keypress) could use a three byte block. Other
communications can use larger blocks up to 254 Bytes data volume. That
could for example be used by a PC to get a part of the playlist and it
is not necessary to update display data. The communication for a remote
to send a keypress would look like this:

Key pressed:
remote: Wakeup
remote: 0x03, 0x05, 0x08 (complete block for maybe "User pressed Play")
remote: 0x01 (What do you want?)
player: 0x02,0x02 (Nothing for now, lets go to sleep)

Display update:
player: Wakeup
remote: 0x01 (What do you want?)
player: 0x07, data....., 0xCC (Update time: 12:04)
remote 0x01 (Anything else?)
player: 0x02,0x02 (No, lets go to sleep)

The only thing that is a bit more complex is to tell each other, what
funcionality is supported. But it is very important if we look at
backward and forward compatibility. It also ensures that the
functionality in the player/recorder is only implemented once and not
new for every remote type.

I'd leave the functional identifiers open for the next session, it is
very late and I'm tired.
Also I don't like writing specs, but sometimes it's necessary ;)
The information of orion2003 will be very helpfull, when it comes to the
HAL. Thank you for that!
There might be some translational and also logical errors, since I've
done this in a short time, but that'll be no problem to fix later.

Bye,
Andreas
[radhard]



Page was last modified "Jan 10 2012" The Rockbox Crew
aaa