[pvrusb2] question about managing HVR-1900 from an embedded host
Mike Isely
isely at isely.net
Sat Jul 21 13:52:47 CDT 2012
Lots of comments interspersed below...
On Thu, 19 Jul 2012, Mark Atherton wrote:
> Hi All,
> I am working on a small, low power embedded digital TV project (see
> [1]http://www.idesignz.org/DigiLiteZL/DigiLiteZL.htm, and associated
> FPGA modulator
> [2]http://www.idesignz.org/DigiLiteZL_FPGA/DigiLiteZL-FPGA.htm). One of
> the next steps of the project is to hook a real-time MPEG2 video
> encoder up to the system, running at a suitably low rate (maybe 1 or
> 2Mb/s total stream rate). The power budget for the system does not
> allow for a PC, hence the desire to use a small embedded system.
Keep in mind that the mpeg encoder in the HVR-1900 needs a few watts,
which is why such devices are not powered from the USB cable.
> An HVR-1900 MPEG encoder is at hand, but only composite video and audio
> inputs are required. This product appears to contain a Conexant CX23416
> MPEG2 audio/video encoder, a CX25840 PAL/NTSC video decoder, and a
> Cypress FX2, or FX2LP USB interface. The unit has misc stuff associated
> with RF tuner etc, hopefully these can be ignored.
You should be able to safely ignore the RF side.
> Moving on to signal flow: an external PAL video source will be plugged
> into the HVR-1900, the HVR-1900 will be plugged into a custom
> dsPIC33EP512MU810 board (which has a USB 1.1 host). The dsPIC has the
> job of initially loading required firmware into the HVR-1900 then
> selecting the required encode mode and translating the incoming real
> time MPEG Program Stream into Transport Stream. This data will then be
> transferred via a new parallel interface to the FPGA DVB-S modulator
> (USB is currently used).
OK. Sounds doable.
> So far the PVR-1900 has been attached to Ubuntu Studio 10.x via a USB
> 1.1 hub, and it has been confirmed that the whole chain can generate a
> 1Mb/s PS using V4L. This was all rather easier than expected and worked
> pretty much off the bat, so well done.that team.
I assume you mean HVR-1900, not PVR-1900.
Yes, early on in the pvrusb2 debugging I tried running it using USB 1.1
and it worked pretty well using default encoding parameters. However
there are parameters possible that can raise the quality of the encode
and it's possible to exceed what USB 1.1 can transport. But with the
defaults it's all good.
> Having spent some time playing with a Cypress FX2 (CY7C68013) USB
> interface dev kit, it appears that the FX2 can accept firmware over the
> USB port, and run from it's internal 8k (FX2) or 16k (FX2LP) RAM using
> vendor command 0xA0. A second stage boot loader (vend_ax) is required
> if external RAM is required. Some amount of cleverness involves the
> device re-enumerating itself from default VID / PID (0x04B4 / 0x8613)
> once code has been loaded, so that alternate drivers can take over the
> boot and control process. It also appears that DID is used to
> differentiate the FX2 (DID 0x000x) from the FX2LP (DID 0xA00x).
The FX2 normally goes looking for an I2C EEPROM to be connected to it at
a specific I2C address. Having found such a part, the FX2 will expect a
configuration block to be stored there which is used to set up the USB
parameters, e.g. endpoint configuration, device ID, manufacturer ID,
etc. In addition to the configuration block, there can be a program
stored there as well, which the FX2 will immediately copy to its
internal RAM and execute.
For Hauppauge devices with this type of hardware, the EEPROM is
programmed so that the device immediately reports the correct Hauppauge
ID information and a small "boot" program will run. However the device
expects to be loaded with the "real" FX2 program, which the pvrusb2
driver will do. Since the USB ID doesn't change after the FX2 has been
reloaded, the pvrusb2 driver has to do some crufty things to determine
if the device's needs to have its FX2 program loaded. I don't remember
the specifics off-hand, but I believe in one case the driver attempts to
look for a particular FX2 command to implemented. In another case it
may examine the endpoint configuration to tell apart the "boot" program
from the "normal" program.
Code is loaded by forcing the FX2 into reset and then using the USB
control endpoint to download a replacement program, using the vendor
command you had mentioned. The CPU is then released from reset,
whereupon it "renumerates" into its run-time configuration. This
process is controlled via silicon not the FX2's processor, IIRC.
> So the next challenge is to completely understand all steps required to
> boot up a PVR-1900. From then, an understanding is required how to
> configure and use the booted device.
> At a guess, boot sequence is something like:
> 1) PVR-1900 is plugged into the host (dsPIC)
> 2) host registers and enumerates the FX2 device within the PVR-1900
> using VID 0x04B4, PID 0x8613
Yup.
> 3) host downloads FX2 firmware (or second stage loader vend_ax) using
> vendor command 0xA0
> 4) host releases FX2 8051 from reset, new code re-enumerates using
> alternate VID / PID combination
Yes. In the pvrusb2 driver, see the function pvr2_upload_firmware1()
located in pvrusb2-hdw.c. This performs the entire reset-upload-release
sequence.
> -- at this point, the FX2 8051 is running a boot loader that will allow
> code loading of CX25840 and CX23416 --
Yes but it's not a bootloader. In the case of the pvrusb2 driver, at
this point the FX2 is running is its final "operational" firmware. It
just so happens that this is then used to boot up the rest of the
device. But the FX2 firmware is not changed again.
> 5) host loads CX25840 firmware (possibly using two wire interface)
The CX25840 is loaded via its I2C port (the two wire interface), as
driven by the FX2, which in turn acts as a proxy for the host where the
pvrusb2 driver is running.
One very (very!) important function that the FX2 firmware performs is
that it enables a sort of "proxy" access from the host system to its I2C
controller. This allows the pvrusb2 driver to execute all manner of I2C
transactions; in fact the majority of the device's operations are
performed via I2C. The pvrusb2 driver makes all this work by
implementing what appears to the rest of the kernel to be a "standard"
Linux I2C adapter driver. The pvrusb2 driver actually forwards all
requests received via that adapter over to the FX2 via a
command/response protocol on EP1. This enables a key ability - every
V4L-resident chip driver, designed to operate certain specific parts via
I2C, automatically is able to access and operate corresponding chips
inside your HVR-1900. The pvrusb2 driver is effectively implementing a
bridge between that chip driver and the actual hardware, by relaying
transfer requests over USB to the FX2's firmware which then responds by
performing the requested transfers using its own I2C controller. The
net result is that the I2C bus sitting inside your HVR-1900 - to which
nearly everything is connected - is transparently accessible to any I2C
client driver in the Linux kernel, and thus much of the rest of V4L.
> 6) host loads CX23416 firmware (not a clue)
The CX23416 is not I2C-connected. Some other kind of control path
exists between the CX23416 and the FX2. It is probably a means whereby
the FX2 can directly peek/poke the CX23416's RAM (there is a static RAM
next to that part), coupled with an ability to do things like control
the reset signal to the CX23416.
The pvrusb2 driver loads the '416's firmware basically by resetting the
chip, doing other various poorly-documented things to the part, and then
sending the firmware through another USB endpoint set up for the
purpose. Take a look at the function pvr2_upload_firmware2() in
pvrusb2-hdw.c. You'll also see various calls to pvr2_write_register()
which implements a sort of access method to an address space within the
'416.
> 7) host commands CX25840 to select video standard and input source
Yes, via the cx25840.ko kernel module, which in turn operates the chip
via I2C transfers (see above).
> 8) host commands CX23416 to select MPEG encode profile, bit rate etc.
Yes, via a sort of register-hosted mailbox interface. This is done in
pvrusb2-encoder.c. Operations of the CX23416 are done by sending it
command words with arguments specific to each command. These commands
are written to reigsters related to the CX23416 (with the help of the
FX2).
In earlier versions of the pvrusb2 driver, the specific commands to be
sent were constructed by the pvrusb2 driver itself. However this code
was combined with similar code from the ivtv driver (and I think another
driver out there) to form a new V4L module, known as cx2341x.ko. So all
the "intelligence" for talking to the '416 is actually in that module
now. The pvrusb2 driver still has to implement the handshake to the
chip (which is unique to the hardware) but nowadays, basically the
pvrusb2 driver tells cx2341x what it needs then cx2341x issues the
correct commands which the pvrusb2 driver then feeds into the chip (via
the FX2).
If you look at the standalone pvrusb2 driver, you can still see the
older implementation - it's still there for cases where the driver is
compiled against a very old kernel. But if the kernel has cx2341x in
it, the driver will disable its own cx2341x command-forming logic and
defer instead to the cx2341x module.
> 9) host commands CX23416 to start encoding
Yes. Same mechanism as (8).
> 10) host fetches buffers of MPEG video using BULK transfers over EP2 or
> EP6 (?)
Actually, EP4 should be the spigot for streaming in video (search for
call to "pvr2_stream_setup()" in pvrusb2-hdw.c, where the endpoint is
passed down to lower level code. While streaming, the driver
continuously queues bulk transfer URBs to that endpoint.
Note that commands to the FX2 itself are always done using EP1. It's a
pretty simple protocol: You send a command byte followed by some number
of bytes specific to the command, and then just read back the result.
All FX2 commands are run this way. There is a general-purpose function
in the pvrusb2 driver that implements the host side of this protocol.
The function name is "pvr2_send_request_ex()" and can be found in
pvrusb2-hdw.c. Example commands of this sort include requests for I2C
data transfer, read/write of cx23416 registers, etc...
> 11) host translates PS to TS, sending output video to FPGA via parallel
> interface
The pvrusb2 driver currently doesn't do any processing on the received
stream. But obviously what you do with the received packets is up to
you...
> 12) repeat from 10
Yes. In the case of the pvrusb2 driver, this is done with a pool of
request URBs, which makes sense since the USB stack in Linux is
naturally asynchronous. The pvrusb2 driver always tries to keep some
minimum number of URBs queued for reception. Received data is kept in a
ring buffer until the user application reads out the data - presumably
to keep the stream running smoothly, the user application will always
have a read() posted or at least a select() or poll() pending to the
driver's open device node. In your PIC environment of course this is
probably going to be completely different...
> Notes:
> 13) is BT565 is used as video path between CX25840 to CX23416, if not,
> then what ?
I believe it is. I have been told in the past that this is the data
format used between those two chips, however I've never had (yet) to
implement anything that relied on this knowledge. From the viewpoint of
the pvrusb2 driver, "magic" happens between those two parts :-)
> 14) looks like Linux uses v4l-pvrusb2-73xxx-01.fw (16,384 bytes) to
> load into FX2
Yes.
> 15) looks like Linux uses v4l-cx25840.fw (16,382 bytes) to load into
> CX25840
Yes.
> 16) looks like Linux uses v4l-cx2341x-enc.fw (376,836 bytes) to load
> into CX23416
Yes.
> Any corrections, pointers to relevant web pages, or other help to start
> filling in the great voids of understanding will be most appreciated.
> Many thanks,
> Mark
> PS Phew !
>
> References
>
> 1. http://www.idesignz.org/DigiLiteZL/DigiLiteZL.htm
> 2. http://www.idesignz.org/DigiLiteZL_FPGA/DigiLiteZL-FPGA.htm
Hope that helps.
-Mike
--
Mike Isely
isely @ isely (dot) net
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8
More information about the pvrusb2
mailing list