|
IMPORTANT NOTE: This document is outdated. I have figured out most of how
the rio works but don't have time (or put in another way:
have more intereting things to do) to update it. If you want
to know how it works i suggest you look at the
source code
i have written. The information here might help you a bit but
its quite incomplete. Introduction This section describes my findings of how data is sent to
and from the RIO 500. This information has been obtained by
looking at the communication between the RIO and the computer
using a debugger and placing breakpoints in the windows driver
to dump the content of the messages sent throught the control
pipe and bulk read/write pipes. The process is rather complex
to explain and maybe when i get a little more time i'll add
a description so others can also do it. It basically involves
using the debugger supplied in the windows DDK and another
computer connected through the serial port. By adding interrupts
in strategic places of the riousb.sys file the computer will
fall in the debugger. From the other computer one can inspect memory,
stack, and add breakpoints which will dump information when they
are reached.
Overview The RIO 500 opens 3 USB pipes: the control pipe, the bulk read and the bulk write pipe. Unfortunately it doesn't use any of the standard class specifications mentioned in the usb specs. It uses vendor specific messages which means that, if the vendor doesn't supply the specs its hard to comunicate with the device. Fortunately i've been able to look at the messages sent to the rio and i'm in the process of understanting the protocol. If you have read the USB specs you will know that each control message
is caracterized by 6 parameters: request type, request, value, index,
length and data. Almost all the requests sent to the RIO have
request type
set to 0xC0 which means that the data transfer direction is set to
Device-to-Host, the Type is set to Vendor and the Recipient is set
to Device (see ths USB specs, chapter 9 for an explenation of
these terms). The request byte, value and index
are specific to each type of message and will be explained below.
Most commands return 0x01 in the data phase indicating that the command
was successfull.
Starting communication with the RIO When the computer wants to communicate with the RIO it must first
tell it to enter the USB Comm phase. You will notice that the RIO
displays a message indicating that it is communicating with the
computer. To start communication you must send a request 0x47. To
end communication a request 0x48 must be sent:
Memory usage The Rio 500 differs significantly from its predecessor (the Rio 300) in terms of its memory map. The previous Rio had a FAT and the windows software was responsible for maintaing the FAT and deciding where information is stored. The Rio 500 works differently: the device desides were data will be stored and tells the software where in memory the last written information was stored. Memory is divided into 16Kb blocks and addresses point to the beginnig of a block. Offset 0x0 is the first 16Kb block, offset 0x1 is the second 16Kb block, etc. Normally the first 0x16 blocks are used by the Rio 500 internally. The songs, song information and folder information are stored from offset 0x17 on. Folders and song information As you have noticed the RIO has the posibility of creating folders
and storing songs in them. The information for each folder (name of the
folder, offset into memory where the content of this folder is, etc)
is stored in C struct called a folder entry. Eight of this entries fit
in a 16Kb block. I call this block of 8 folder the folder block. If there
are more than 8 folders then there will be more than one folder block.
At the moment i haven't bothered to figure out how it handles more than
8 folders so, for the time being, i'll assume there is just one folder
block with the information for each of the 8 folder entries. Here's
the C struct:
The folder block is read by using the following commands:
This command tells the RIO we want to read the folder block. This
is indicated by the 0xff00. I think it returns the the number of 16Kb
blocks that are used by the folder block but as i said before,
since i haven't bothered with the case of more than 8 folders i'm not
sure. I think i experimented a bit and saw that it returned 0 when there
is no folder block (when the rio is formatted) and 1 when there are less
than 8 folders. And, if i don't remember wrong, at some point i noticed it
returned 2 when there were more than 8 folders but i'm not sure. Now we
must read the data from the bulk pipe. This is done by sending a read
command:
This command tells the RIO we are ready to receive a bulk transfer. At this point the RIO will begin sending length_hi * 0x10000 + length_low bytes throught the bulk pipe. To read the folder block one sets length_hi=0 and length_low=0x4000. Once you have the folder block it can be modified. To transfer the
folder list back to the RIO you should first send a write request to
by issueing the command:
followed by a write request:
where length_hi and length_low are as in the read
command (usually, for the folder block, length_hi=0 and length_low=0x4000)
At this point we must write the data to the bulk write pipe and the RIO
will accept it. As i said before, we do not decide where the data is
being stored. After a write command we must query the Rio to tell us where
it was stored. This is done by the command 0x43:
This command returns the offset into memory where the last bulk transfer was written to. Once the folder block has been written we must tell the rio where the main folder block is. This is done with the command 0x56. This command is different from the rest because, during the data phase of the control message, data is sent TO the rio. 6 bytes are sent: the first two are the offset into memory where the folder block was stored. The next two i'm not sure but i set them to 0x4000 and it works fine. Its probably the size of the folder block. The last two bytes are the number of the folder we just modified (folder 0 is the first folder, etc). Formating the RIO To erase the content of your RIO you must send the following
request:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|